Update to Drupal 8.2.6. For more information, see https://www.drupal.org/project/drupal/releases/8.2.6

This commit is contained in:
Pantheon Automation 2017-02-02 16:28:38 -08:00 committed by Greg Anderson
parent db56c09587
commit f1e72395cb
588 changed files with 26857 additions and 2777 deletions

265
composer.lock generated
View file

@ -1242,16 +1242,16 @@
}, },
{ {
"name": "symfony/class-loader", "name": "symfony/class-loader",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/class-loader.git", "url": "https://github.com/symfony/class-loader.git",
"reference": "7d362c22710980730d46a5d039e788946a2938cb" "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/class-loader/zipball/7d362c22710980730d46a5d039e788946a2938cb", "url": "https://api.github.com/repos/symfony/class-loader/zipball/7c46951128f7169cbece2c303fba4a9eb35cbe68",
"reference": "7d362c22710980730d46a5d039e788946a2938cb", "reference": "7c46951128f7169cbece2c303fba4a9eb35cbe68",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1291,24 +1291,25 @@
], ],
"description": "Symfony ClassLoader Component", "description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-10 19:33:53" "time": "2017-01-10 14:03:07"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154" "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154", "url": "https://api.github.com/repos/symfony/console/zipball/2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
"reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154", "reference": "2e18b8903d9c498ba02e1dfa73f64d4894bb6912",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.9", "php": ">=5.3.9",
"symfony/debug": "~2.7,>=2.7.2|~3.0.0",
"symfony/polyfill-mbstring": "~1.0" "symfony/polyfill-mbstring": "~1.0"
}, },
"require-dev": { "require-dev": {
@ -1351,20 +1352,20 @@
], ],
"description": "Symfony Console Component", "description": "Symfony Console Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-17 09:19:04" "time": "2017-01-08 20:43:03"
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v2.7.6", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/debug.git",
"reference": "fb9e6887db716939f41af0ba8ef38a1582eb501b" "reference": "567681e2c4e5431704e884e4be25a95fd900770f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/fb9e6887db716939f41af0ba8ef38a1582eb501b", "url": "https://api.github.com/repos/symfony/debug/zipball/567681e2c4e5431704e884e4be25a95fd900770f",
"reference": "fb9e6887db716939f41af0ba8ef38a1582eb501b", "reference": "567681e2c4e5431704e884e4be25a95fd900770f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1375,19 +1376,22 @@
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
}, },
"require-dev": { "require-dev": {
"symfony/class-loader": "~2.2", "symfony/class-loader": "~2.2|~3.0.0",
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2" "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.7-dev" "dev-master": "2.8-dev"
} }
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Symfony\\Component\\Debug\\": "" "Symfony\\Component\\Debug\\": ""
} },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -1405,20 +1409,20 @@
], ],
"description": "Symfony Debug Component", "description": "Symfony Debug Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-10-11 09:39:48" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "f7b4a498e679fa440b16facb934680a1527ed48c" "reference": "b75356611675364607d697f314850d9d870a84aa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7b4a498e679fa440b16facb934680a1527ed48c", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b75356611675364607d697f314850d9d870a84aa",
"reference": "f7b4a498e679fa440b16facb934680a1527ed48c", "reference": "b75356611675364607d697f314850d9d870a84aa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1430,10 +1434,11 @@
"require-dev": { "require-dev": {
"symfony/config": "~2.2|~3.0.0", "symfony/config": "~2.2|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0",
"symfony/yaml": "~2.1|~3.0.0" "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7"
}, },
"suggest": { "suggest": {
"symfony/config": "", "symfony/config": "",
"symfony/expression-language": "For using expressions in service container configuration",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony/yaml": "" "symfony/yaml": ""
}, },
@ -1467,20 +1472,20 @@
], ],
"description": "Symfony DependencyInjection Component", "description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-21 07:27:21" "time": "2017-01-10 14:27:01"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87" "reference": "74877977f90fb9c3e46378d5764217c55f32df34"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34",
"reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87", "reference": "74877977f90fb9c3e46378d5764217c55f32df34",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1527,20 +1532,20 @@
], ],
"description": "Symfony EventDispatcher Component", "description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-07 14:04:32" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "06d6b2c755b2f34ce21e688b62072e9c625709c4" "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/06d6b2c755b2f34ce21e688b62072e9c625709c4", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/464cdde6757a40701d758112cc7ff2c6adf6e82f",
"reference": "06d6b2c755b2f34ce21e688b62072e9c625709c4", "reference": "464cdde6757a40701d758112cc7ff2c6adf6e82f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1582,20 +1587,20 @@
], ],
"description": "Symfony HttpFoundation Component", "description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-27 12:57:53" "time": "2017-01-08 20:43:03"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "2c45576fee2eb228d4771342a05b0565e4711ba2" "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/2c45576fee2eb228d4771342a05b0565e4711ba2", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1097eb4ce0a7bdcd030f110c123682fed89a137c",
"reference": "2c45576fee2eb228d4771342a05b0565e4711ba2", "reference": "1097eb4ce0a7bdcd030f110c123682fed89a137c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1603,7 +1608,7 @@
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/debug": "~2.6,>=2.6.2", "symfony/debug": "~2.6,>=2.6.2",
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0", "symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
"symfony/http-foundation": "~2.5,>=2.5.4|~3.0.0" "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6"
}, },
"conflict": { "conflict": {
"symfony/config": "<2.7" "symfony/config": "<2.7"
@ -1664,20 +1669,20 @@
], ],
"description": "Symfony HttpKernel Component", "description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-25 01:40:30" "time": "2017-01-12 20:27:24"
}, },
{ {
"name": "symfony/polyfill-apcu", "name": "symfony/polyfill-apcu",
"version": "v1.1.1", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-apcu.git", "url": "https://github.com/symfony/polyfill-apcu.git",
"reference": "0c901e4e65a2f7ece68f0fd249b56d6ad3adc214" "reference": "5d4474f447403c3348e37b70acc2b95475b7befa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/0c901e4e65a2f7ece68f0fd249b56d6ad3adc214", "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa",
"reference": "0c901e4e65a2f7ece68f0fd249b56d6ad3adc214", "reference": "5d4474f447403c3348e37b70acc2b95475b7befa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1686,7 +1691,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -1717,20 +1722,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-03-03 16:49:40" "time": "2016-11-14 01:06:16"
}, },
{ {
"name": "symfony/polyfill-iconv", "name": "symfony/polyfill-iconv",
"version": "v1.1.1", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git", "url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "08e3b8768d785ba7f271ef94906d50f7efe72ce8" "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/08e3b8768d785ba7f271ef94906d50f7efe72ce8", "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cba36f3616d9866b3e52662e88da5c090fac1e97",
"reference": "08e3b8768d785ba7f271ef94906d50f7efe72ce8", "reference": "cba36f3616d9866b3e52662e88da5c090fac1e97",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1742,7 +1747,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -1776,20 +1781,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-02-26 11:31:02" "time": "2016-11-14 01:06:16"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.1.0", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "1289d16209491b584839022f29257ad859b8532d" "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
"reference": "1289d16209491b584839022f29257ad859b8532d", "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1801,7 +1806,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -1835,20 +1840,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-01-20 09:13:37" "time": "2016-11-14 01:06:16"
}, },
{ {
"name": "symfony/polyfill-php54", "name": "symfony/polyfill-php54",
"version": "v1.1.0", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php54.git", "url": "https://github.com/symfony/polyfill-php54.git",
"reference": "74663d5a2ff3c530c1bc0571500e0feec9094054" "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/74663d5a2ff3c530c1bc0571500e0feec9094054", "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
"reference": "74663d5a2ff3c530c1bc0571500e0feec9094054", "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1857,7 +1862,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -1893,20 +1898,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-01-20 09:13:37" "time": "2016-11-14 01:06:16"
}, },
{ {
"name": "symfony/polyfill-php55", "name": "symfony/polyfill-php55",
"version": "v1.1.0", "version": "v1.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php55.git", "url": "https://github.com/symfony/polyfill-php55.git",
"reference": "b4f3f07d91702f8f926339fc4fcf81671d8c27e6" "reference": "03e3f0350bca2220e3623a0e340eef194405fc67"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/b4f3f07d91702f8f926339fc4fcf81671d8c27e6", "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67",
"reference": "b4f3f07d91702f8f926339fc4fcf81671d8c27e6", "reference": "03e3f0350bca2220e3623a0e340eef194405fc67",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1916,7 +1921,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.1-dev" "dev-master": "1.3-dev"
} }
}, },
"autoload": { "autoload": {
@ -1949,20 +1954,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2016-01-20 09:13:37" "time": "2016-11-14 01:06:16"
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "fb467471952ef5cf8497c029980e556b47545333" "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333", "url": "https://api.github.com/repos/symfony/process/zipball/ebb3c2abe0940a703f08e0cbe373f62d97d40231",
"reference": "fb467471952ef5cf8497c029980e556b47545333", "reference": "ebb3c2abe0940a703f08e0cbe373f62d97d40231",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1998,7 +2003,7 @@
], ],
"description": "Symfony Process Component", "description": "Symfony Process Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-23 13:11:46" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/psr-http-message-bridge", "name": "symfony/psr-http-message-bridge",
@ -2056,16 +2061,16 @@
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "d7d4a20cb55a90a06c0070d1a360e5ac606306ef" "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/d7d4a20cb55a90a06c0070d1a360e5ac606306ef", "url": "https://api.github.com/repos/symfony/routing/zipball/2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f",
"reference": "d7d4a20cb55a90a06c0070d1a360e5ac606306ef", "reference": "2a7e3e02bbfb0a4f722e6a3154489e4ac8b3a97f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2127,20 +2132,20 @@
"uri", "uri",
"url" "url"
], ],
"time": "2016-03-23 13:11:46" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/serializer", "name": "symfony/serializer",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/serializer.git", "url": "https://github.com/symfony/serializer.git",
"reference": "e848750ceffdc4af374844c338c299627a98196a" "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/serializer/zipball/e848750ceffdc4af374844c338c299627a98196a", "url": "https://api.github.com/repos/symfony/serializer/zipball/3a5337e3daaabb9ada73d60f3271adb6bfa56a1a",
"reference": "e848750ceffdc4af374844c338c299627a98196a", "reference": "3a5337e3daaabb9ada73d60f3271adb6bfa56a1a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2191,20 +2196,20 @@
], ],
"description": "Symfony Serializer Component", "description": "Symfony Serializer Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-07 14:04:32" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "d60b8e076d22953aabebeebda53bf334438e7aca" "reference": "b4ac4a393f6970cc157fba17be537380de396a86"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/d60b8e076d22953aabebeebda53bf334438e7aca", "url": "https://api.github.com/repos/symfony/translation/zipball/b4ac4a393f6970cc157fba17be537380de396a86",
"reference": "d60b8e076d22953aabebeebda53bf334438e7aca", "reference": "b4ac4a393f6970cc157fba17be537380de396a86",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2255,24 +2260,25 @@
], ],
"description": "Symfony Translation Component", "description": "Symfony Translation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-25 01:40:30" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/validator", "name": "symfony/validator",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/validator.git", "url": "https://github.com/symfony/validator.git",
"reference": "ea0ce99531c9eb82abf21011da4e111932f8ce81" "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/validator/zipball/ea0ce99531c9eb82abf21011da4e111932f8ce81", "url": "https://api.github.com/repos/symfony/validator/zipball/3b1a3188efea75ec7c0419a2568b6e5f82031811",
"reference": "ea0ce99531c9eb82abf21011da4e111932f8ce81", "reference": "3b1a3188efea75ec7c0419a2568b6e5f82031811",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.9", "php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0",
"symfony/translation": "~2.4|~3.0.0" "symfony/translation": "~2.4|~3.0.0"
}, },
"require-dev": { "require-dev": {
@ -2281,7 +2287,7 @@
"egulias/email-validator": "~1.2,>=1.2.1", "egulias/email-validator": "~1.2,>=1.2.1",
"symfony/config": "~2.2|~3.0.0", "symfony/config": "~2.2|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0", "symfony/expression-language": "~2.4|~3.0.0",
"symfony/http-foundation": "~2.1|~3.0.0", "symfony/http-foundation": "~2.3|~3.0.0",
"symfony/intl": "~2.7.4|~2.8|~3.0.0", "symfony/intl": "~2.7.4|~2.8|~3.0.0",
"symfony/property-access": "~2.3|~3.0.0", "symfony/property-access": "~2.3|~3.0.0",
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0" "symfony/yaml": "~2.0,>=2.0.5|~3.0.0"
@ -2327,20 +2333,20 @@
], ],
"description": "Symfony Validator Component", "description": "Symfony Validator Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-27 12:57:53" "time": "2017-01-12 19:24:25"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", "url": "https://api.github.com/repos/symfony/yaml/zipball/dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
"reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", "reference": "dbe61fed9cd4a44c5b1d14e5e7b1a8640cfb2bf2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2376,7 +2382,7 @@
], ],
"description": "Symfony Yaml Component", "description": "Symfony Yaml Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-04 07:54:35" "time": "2017-01-03 13:49:52"
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
@ -4043,25 +4049,25 @@
}, },
{ {
"name": "symfony/browser-kit", "name": "symfony/browser-kit",
"version": "v2.7.6", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/browser-kit.git", "url": "https://github.com/symfony/browser-kit.git",
"reference": "07d664a052572ccc28eb2ab7dbbe82155b1ad367" "reference": "d2a5de15c8341a470a66becf4597bc675686a72b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/07d664a052572ccc28eb2ab7dbbe82155b1ad367", "url": "https://api.github.com/repos/symfony/browser-kit/zipball/d2a5de15c8341a470a66becf4597bc675686a72b",
"reference": "07d664a052572ccc28eb2ab7dbbe82155b1ad367", "reference": "d2a5de15c8341a470a66becf4597bc675686a72b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.9", "php": ">=5.3.9",
"symfony/dom-crawler": "~2.0,>=2.0.5" "symfony/dom-crawler": "~2.1|~3.0.0"
}, },
"require-dev": { "require-dev": {
"symfony/css-selector": "~2.0,>=2.0.5", "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/process": "~2.3.34|~2.7,>=2.7.6" "symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0"
}, },
"suggest": { "suggest": {
"symfony/process": "" "symfony/process": ""
@ -4069,13 +4075,16 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.7-dev" "dev-master": "2.8-dev"
} }
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Symfony\\Component\\BrowserKit\\": "" "Symfony\\Component\\BrowserKit\\": ""
} },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -4093,20 +4102,20 @@
], ],
"description": "Symfony BrowserKit Component", "description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-10-23 14:47:27" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v2.8.4", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
"reference": "07b7ced3ae0c12918477c095453ea8595000810e" "reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/07b7ced3ae0c12918477c095453ea8595000810e", "url": "https://api.github.com/repos/symfony/css-selector/zipball/f45daea42232d9ca5cf561ec64f0d4aea820877f",
"reference": "07b7ced3ae0c12918477c095453ea8595000810e", "reference": "f45daea42232d9ca5cf561ec64f0d4aea820877f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4146,27 +4155,28 @@
], ],
"description": "Symfony CssSelector Component", "description": "Symfony CssSelector Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2016-03-04 07:54:35" "time": "2017-01-02 20:30:24"
}, },
{ {
"name": "symfony/dom-crawler", "name": "symfony/dom-crawler",
"version": "v2.7.6", "version": "v2.8.16",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dom-crawler.git", "url": "https://github.com/symfony/dom-crawler.git",
"reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612" "reference": "52cc211afa9458c0a54c478010a55f44892c1c02"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/5fef7d8b80d8f9992df99d8ee283f420484c9612", "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/52cc211afa9458c0a54c478010a55f44892c1c02",
"reference": "5fef7d8b80d8f9992df99d8ee283f420484c9612", "reference": "52cc211afa9458c0a54c478010a55f44892c1c02",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.9" "php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
}, },
"require-dev": { "require-dev": {
"symfony/css-selector": "~2.3" "symfony/css-selector": "~2.8|~3.0.0"
}, },
"suggest": { "suggest": {
"symfony/css-selector": "" "symfony/css-selector": ""
@ -4174,13 +4184,16 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.7-dev" "dev-master": "2.8-dev"
} }
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Symfony\\Component\\DomCrawler\\": "" "Symfony\\Component\\DomCrawler\\": ""
} },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@ -4198,7 +4211,7 @@
], ],
"description": "Symfony DomCrawler Component", "description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2015-10-11 09:39:48" "time": "2017-01-02 20:30:24"
} }
], ],
"aliases": [], "aliases": [],

View file

@ -20,6 +20,7 @@ use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\Core\Site\Settings; use Drupal\Core\Site\Settings;
use Drupal\Core\StringTranslation\Translator\FileTranslation; use Drupal\Core\StringTranslation\Translator\FileTranslation;
use Drupal\Core\StackMiddleware\ReverseProxyMiddleware; use Drupal\Core\StackMiddleware\ReverseProxyMiddleware;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\Core\Extension\ExtensionDiscovery;
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Url; use Drupal\Core\Url;
@ -1036,6 +1037,21 @@ function install_base_system(&$install_state) {
// Install system.module. // Install system.module.
drupal_install_system($install_state); drupal_install_system($install_state);
// Prevent the installer from using the system temporary directory after the
// system module has been installed.
if (drupal_valid_test_ua()) {
// While the temporary directory could be preset/enforced in settings.php
// like the public files directory, some tests expect it to be configurable
// in the UI. If declared in settings.php, they would no longer be
// configurable. The temporary directory needs to match what is set in each
// test types ::prepareEnvironment() step.
$temporary_directory = dirname(PublicStream::basePath()) . '/temp';
file_prepare_directory($temporary_directory, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY);
\Drupal::configFactory()->getEditable('system.file')
->set('path.temporary', $temporary_directory)
->save();
}
// Call file_ensure_htaccess() to ensure that all of Drupal's standard // Call file_ensure_htaccess() to ensure that all of Drupal's standard
// directories (e.g., the public files directory and config directory) have // directories (e.g., the public files directory and config directory) have
// appropriate .htaccess files. These directories will have already been // appropriate .htaccess files. These directories will have already been

View file

@ -1044,10 +1044,11 @@ function drupal_check_module($module) {
* *
* Example of .info.yml file: * Example of .info.yml file:
* @code * @code
* name = Minimal * name: Minimal
* description = Start fresh, with only a few modules enabled. * description: Start fresh, with only a few modules enabled.
* dependencies[] = block * dependencies:
* dependencies[] = dblog * - block
* - dblog
* @endcode * @endcode
* *
* @param $profile * @param $profile

View file

@ -81,7 +81,7 @@ class Drupal {
/** /**
* The current system version. * The current system version.
*/ */
const VERSION = '8.2.5'; const VERSION = '8.2.6';
/** /**
* Core API compatibility. * Core API compatibility.

View file

@ -147,7 +147,7 @@ class FormattableMarkup implements MarkupInterface, \Countable {
* A call like: * A call like:
* @code * @code
* $string = "%output_text"; * $string = "%output_text";
* $arguments = ['output_text' => 'text output here.']; * $arguments = ['%output_text' => 'text output here.'];
* $this->placeholderFormat($string, $arguments); * $this->placeholderFormat($string, $arguments);
* @endcode * @endcode
* makes the following HTML code: * makes the following HTML code:

View file

@ -297,7 +297,7 @@ class ConfigManager implements ConfigManagerInterface {
$dependency_manager = $this->getConfigDependencyManager(); $dependency_manager = $this->getConfigDependencyManager();
$dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager); $dependents = $this->findConfigEntityDependentsAsEntities($type, $names, $dependency_manager);
$original_dependencies = $dependents; $original_dependencies = $dependents;
$delete_uuids = $update_uuids = []; $delete_uuids = [];
$return = [ $return = [
'update' => [], 'update' => [],
@ -305,6 +305,13 @@ class ConfigManager implements ConfigManagerInterface {
'unchanged' => [], 'unchanged' => [],
]; ];
// Create a map of UUIDs to $original_dependencies key so that we can remove
// fixed dependencies.
$uuid_map = [];
foreach ($original_dependencies as $key => $entity) {
$uuid_map[$entity->uuid()] = $key;
}
// Try to fix any dependencies and find out what will happen to the // Try to fix any dependencies and find out what will happen to the
// dependency graph. Entities are processed in the order of most dependent // dependency graph. Entities are processed in the order of most dependent
// first. For example, this ensures that Menu UI third party dependencies on // first. For example, this ensures that Menu UI third party dependencies on
@ -340,8 +347,9 @@ class ConfigManager implements ConfigManagerInterface {
} }
} }
if ($fixed) { if ($fixed) {
// Remove the fixed dependency from the list of original dependencies.
unset($original_dependencies[$uuid_map[$dependent->uuid()]]);
$return['update'][] = $dependent; $return['update'][] = $dependent;
$update_uuids[] = $dependent->uuid();
} }
} }
// If the entity cannot be fixed then it has to be deleted. // If the entity cannot be fixed then it has to be deleted.
@ -354,8 +362,8 @@ class ConfigManager implements ConfigManagerInterface {
} }
// Use the lists of UUIDs to filter the original list to work out which // Use the lists of UUIDs to filter the original list to work out which
// configuration entities are unchanged. // configuration entities are unchanged.
$return['unchanged'] = array_filter($original_dependencies, function ($dependent) use ($delete_uuids, $update_uuids) { $return['unchanged'] = array_filter($original_dependencies, function ($dependent) use ($delete_uuids) {
return !(in_array($dependent->uuid(), $delete_uuids) || in_array($dependent->uuid(), $update_uuids)); return !(in_array($dependent->uuid(), $delete_uuids));
}); });
return $return; return $return;

View file

@ -1031,8 +1031,17 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
$prefix = Settings::getApcuPrefix('class_loader', $this->root); $prefix = Settings::getApcuPrefix('class_loader', $this->root);
$apc_loader = new ApcClassLoader($prefix, $this->classLoader); $apc_loader = new ApcClassLoader($prefix, $this->classLoader);
$this->classLoader->unregister(); $this->classLoader->unregister();
$apc_loader->register(); // The optimized classloader might be persistent and store cache misses.
// For example, once a cache miss is stored in APCu clearing it on a
// specific web-head will not clear any other web-heads. Therefore
// fallback to the composer class loader that only statically caches
// misses.
$old_loader = $this->classLoader;
$this->classLoader = $apc_loader; $this->classLoader = $apc_loader;
// Our class loaders are preprended to ensure they come first like the
// class loader they are replacing.
$old_loader->register(TRUE);
$apc_loader->register(TRUE);
} }
} }

View file

@ -44,7 +44,16 @@ class RssResponseRelativeUrlFilter implements EventSubscriberInterface {
*/ */
protected function transformRootRelativeUrlsToAbsolute($rss_markup, Request $request) { protected function transformRootRelativeUrlsToAbsolute($rss_markup, Request $request) {
$rss_dom = new \DOMDocument(); $rss_dom = new \DOMDocument();
// Load the RSS, if there are parsing errors, abort and return the unchanged
// markup.
$previous_value = libxml_use_internal_errors(TRUE);
$rss_dom->loadXML($rss_markup); $rss_dom->loadXML($rss_markup);
$errors = libxml_get_errors();
libxml_use_internal_errors($previous_value);
if ($errors) {
return $rss_markup;
}
// Invoke Html::transformRootRelativeUrlsToAbsolute() on all HTML content // Invoke Html::transformRootRelativeUrlsToAbsolute() on all HTML content
// embedded in this RSS feed. // embedded in this RSS feed.

View file

@ -21,8 +21,12 @@ abstract class FieldConfigStorageBase extends ConfigEntityStorage {
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function mapFromStorageRecords(array $records) { protected function mapFromStorageRecords(array $records) {
foreach ($records as &$record) { foreach ($records as $id => &$record) {
$class = $this->fieldTypeManager->getPluginClass($record['field_type']); $class = $this->fieldTypeManager->getPluginClass($record['field_type']);
if (empty($class)) {
$config_id = $this->getPrefix() . $id;
throw new \RuntimeException("Unable to determine class for field type '{$record['field_type']}' found in the '$config_id' configuration");
}
$record['settings'] = $class::fieldSettingsFromConfigData($record['settings']); $record['settings'] = $class::fieldSettingsFromConfigData($record['settings']);
} }
return parent::mapFromStorageRecords($records); return parent::mapFromStorageRecords($records);

View file

@ -26,7 +26,7 @@
* file is not controlled by the current module, the return value should be * file is not controlled by the current module, the return value should be
* NULL. * NULL.
* *
* @see file_download() * @see \Drupal\system\FileDownloadController::download()
*/ */
function hook_file_download($uri) { function hook_file_download($uri) {
// Check to see if this is a config download. // Check to see if this is a config download.

View file

@ -52,21 +52,8 @@ class Link implements RenderableInterface {
* @param array $route_parameters * @param array $route_parameters
* (optional) An associative array of parameter names and values. * (optional) An associative array of parameter names and values.
* @param array $options * @param array $options
* (optional) An associative array of additional options, with the following * The options parameter takes exactly the same structure.
* elements: * See \Drupal\Core\Url::fromUri() for details.
* - 'query': An array of query key/value-pairs (without any URL-encoding)
* to append to the URL. Merged with the parameters array.
* - 'fragment': A fragment identifier (named anchor) to append to the URL.
* Do not include the leading '#' character.
* - 'absolute': Defaults to FALSE. Whether to force the output to be an
* absolute link (beginning with http:). Useful for links that will be
* displayed outside the site, such as in an RSS feed.
* - 'language': An optional language object used to look up the alias
* for the URL. If $options['language'] is omitted, it defaults to the
* current language for the language type LanguageInterface::TYPE_URL.
* - 'https': Whether this URL should point to a secure location. If not
* defined, the current scheme is used, so the user stays on HTTP or HTTPS
* respectively. TRUE enforces HTTPS and FALSE enforces HTTP.
* *
* @return static * @return static
*/ */

View file

@ -157,4 +157,11 @@ class PluralTranslatableMarkup extends TranslatableMarkup {
return -1; return -1;
} }
/**
* {@inheritdoc}
*/
public function __sleep() {
return array_merge(parent::__sleep(), array('count'));
}
} }

View file

@ -100,11 +100,12 @@
$(window) $(window)
.on('resize.dialogResize scroll.dialogResize', eventData, autoResize) .on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
.trigger('resize.dialogResize'); .trigger('resize.dialogResize');
$(document).on('drupalViewportOffsetChange', eventData, autoResize); $(document).on('drupalViewportOffsetChange.dialogResize', eventData, autoResize);
} }
}, },
'dialog:beforeclose': function (event, dialog, $element) { 'dialog:beforeclose': function (event, dialog, $element) {
$(window).off('.dialogResize'); $(window).off('.dialogResize');
$(document).off('.dialogResize');
} }
}); });

View file

@ -37,3 +37,24 @@ function aggregator_update_8001() {
/** /**
* @} End of "addtogroup updates-8.0.0-rc". * @} End of "addtogroup updates-8.0.0-rc".
*/ */
/**
* @addtogroup updates-8.2.x
* @{
*/
/**
* Make the 'Source feed' field for aggregator items required.
*/
function aggregator_update_8200() {
// aggregator_update_8001() did not update the last installed field storage
// definition for the aggregator item's 'Source feed' field.
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$field_definition = $definition_update_manager->getFieldStorageDefinition('fid', 'aggregator_item');
$field_definition->setRequired(TRUE);
$definition_update_manager->updateFieldStorageDefinition($field_definition);
}
/**
* @} End of "addtogroup updates-8.2.x".
*/

View file

@ -0,0 +1,41 @@
<?php
namespace Drupal\aggregator\Tests\Update;
use Drupal\system\Tests\Update\UpdatePathTestBase;
/**
* Tests that node settings are properly updated during database updates.
*
* @group aggregator
*/
class AggregatorUpdateTest extends UpdatePathTestBase {
/**
* {@inheritdoc}
*/
protected function setDatabaseDumpFiles() {
$this->databaseDumpFiles = [
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz',
];
}
/**
* Tests that the 'Source feed' field is required.
*
* @see aggregator_update_8200()
*/
public function testSourceFeedRequired() {
// Check that the 'fid' field is not required prior to the update.
$field_definition = \Drupal::entityDefinitionUpdateManager()->getFieldStorageDefinition('fid', 'aggregator_item');
$this->assertFalse($field_definition->isRequired());
// Run updates.
$this->runUpdates();
// Check that the 'fid' field is now required.
$field_definition = \Drupal::entityDefinitionUpdateManager()->getFieldStorageDefinition('fid', 'aggregator_item');
$this->assertTrue($field_definition->isRequired());
}
}

View file

@ -22,7 +22,7 @@ class BasicAuthTest extends WebTestBase {
* *
* @var array * @var array
*/ */
public static $modules = array('basic_auth', 'router_test', 'locale'); public static $modules = array('basic_auth', 'router_test', 'locale', 'basic_auth_test');
/** /**
* Test http basic authentication. * Test http basic authentication.
@ -175,4 +175,25 @@ class BasicAuthTest extends WebTestBase {
$this->assertText('Access denied', "A user friendly access denied message is displayed"); $this->assertText('Access denied', "A user friendly access denied message is displayed");
} }
/**
* Tests if the controller is called before authentication.
*
* @see https://www.drupal.org/node/2817727
*/
public function testControllerNotCalledBeforeAuth() {
$this->drupalGet('/basic_auth_test/state/modify');
$this->assertResponse(401);
$this->drupalGet('/basic_auth_test/state/read');
$this->assertResponse(200);
$this->assertRaw('nope');
$account = $this->drupalCreateUser();
$this->basicAuthGet('/basic_auth_test/state/modify', $account->getUsername(), $account->pass_raw);
$this->assertResponse(200);
$this->assertRaw('Done');
$this->drupalGet('/basic_auth_test/state/read');
$this->assertResponse(200);
$this->assertRaw('yep');
}
} }

View file

@ -0,0 +1,6 @@
name: 'HTTP Basic Authentication test'
type: module
description: 'Support module for HTTP Basic Authentication testing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,16 @@
basic_auth_test.state.modify:
path: '/basic_auth_test/state/modify'
defaults:
_controller: '\Drupal\basic_auth_test\BasicAuthTestController::modifyState'
options:
_auth:
- basic_auth
requirements:
_user_is_logged_in: 'TRUE'
basic_auth_test.state.read:
path: '/basic_auth_test/state/read'
defaults:
_controller: '\Drupal\basic_auth_test\BasicAuthTestController::readState'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,30 @@
<?php
namespace Drupal\basic_auth_test;
class BasicAuthTestController {
/**
* @see \Drupal\basic_auth\Tests\Authentication\BasicAuthTest::testControllerNotCalledBeforeAuth()
*/
public function modifyState() {
\Drupal::state()->set('basic_auth_test.state.controller_executed', TRUE);
return ['#markup' => 'Done'];
}
/**
* @see \Drupal\basic_auth\Tests\Authentication\BasicAuthTest::testControllerNotCalledBeforeAuth()
*/
public function readState() {
// Mark this page as being uncacheable.
\Drupal::service('page_cache_kill_switch')->trigger();
return [
'#markup' => \Drupal::state()->get('basic_auth_test.state.controller_executed') ? 'yep' : 'nope',
'#cache' => [
'max-age' => 0,
],
];
}
}

View file

@ -4,6 +4,7 @@ namespace Drupal\block_content;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityListBuilder; use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Routing\RedirectDestinationTrait;
/** /**
* Defines a class to build a listing of custom block entities. * Defines a class to build a listing of custom block entities.
@ -12,6 +13,8 @@ use Drupal\Core\Entity\EntityListBuilder;
*/ */
class BlockContentListBuilder extends EntityListBuilder { class BlockContentListBuilder extends EntityListBuilder {
use RedirectDestinationTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -34,7 +37,7 @@ class BlockContentListBuilder extends EntityListBuilder {
public function getDefaultOperations(EntityInterface $entity) { public function getDefaultOperations(EntityInterface $entity) {
$operations = parent::getDefaultOperations($entity); $operations = parent::getDefaultOperations($entity);
if (isset($operations['edit'])) { if (isset($operations['edit'])) {
$operations['edit']['query']['destination'] = $entity->url('collection'); $operations['edit']['query']['destination'] = $this->getRedirectDestination()->get();
} }
return $operations; return $operations;
} }

View file

@ -0,0 +1,50 @@
<?php
namespace Drupal\block_content\Tests\Views;
/**
* Tests the redirect destination on block content on entity operations.
*
* @group block_content
*/
class BlockContentRedirectTest extends BlockContentTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['test_block_content_redirect_destination'];
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('block', 'block_content', 'views');
/**
* Tests the redirect destination when editing block content.
*/
public function testRedirectDestination() {
$this->drupalLogin($this->drupalCreateUser(array('administer blocks')));
$this->drupalGet('admin/structure/block/block-content');
// Create a custom block.
$this->clickLink('custom block');
$edit = array();
$edit['info[0][value]'] = 'Test redirect destination';
$edit['body[0][value]'] = $this->randomMachineName(16);
$this->drupalPostForm(NULL, $edit, 'Save');
// Check the block content is present in the view redirect destination.
$this->drupalGet('admin/content/redirect_destination');
$this->assertText('Test redirect destination');
// Edit the created block and save.
$this->clickLink('Edit');
$this->drupalPostForm(NULL, [], 'Save');
$this->assertUrl('admin/content/redirect_destination');
}
}

View file

@ -0,0 +1,234 @@
langcode: en
status: true
dependencies:
module:
- block_content
id: test_block_content_redirect_destination
label: 'Redirect destination'
module: views
description: ''
tag: ''
base_table: block_content_field_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:
info: info
info:
info:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: 'entity:block_content'
fields:
info:
table: block_content_field_data
field: info
id: info
entity_type: null
entity_field: info
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
operations:
id: operations
table: block_content
field: operations
relationship: none
group_type: group
admin_label: ''
label: 'Operations links'
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
destination: true
entity_type: block_content
plugin_id: entity_operations
filters: { }
sorts: { }
title: 'Redirect destination'
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
cache_metadata:
max-age: 0
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: /admin/content/redirect_destination
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
tags: { }

View file

@ -33,6 +33,12 @@ config_test.dynamic.*.*:
type: config_test_dynamic type: config_test_dynamic
label: 'Config test dynamic settings' label: 'Config test dynamic settings'
config_test.dynamic.*.third_party.node:
type: mapping
mapping:
foo:
type: string
config_test.query.*: config_test.query.*:
type: config_entity type: config_entity
mapping: mapping:

View file

@ -136,6 +136,10 @@ class ConfigTest extends ConfigEntityBase implements ConfigTestInterface {
} }
} }
} }
// If any of the dependencies removed still exists, return FALSE.
if (array_intersect_key(array_flip($this->dependencies['enforced']['config']), $dependencies['config'])) {
return FALSE;
}
return $changed; return $changed;
} }

View file

@ -12,3 +12,4 @@ process:
destination: destination:
plugin: config plugin: config
config_name: system.maintenance config_name: system.maintenance
translations: true

View file

@ -36,3 +36,4 @@ process:
destination: destination:
plugin: config plugin: config
config_name: system.site config_name: system.site
translations: true

View file

@ -66,3 +66,4 @@ process:
destination: destination:
plugin: config plugin: config
config_name: user.mail config_name: user.mail
translations: true

View file

@ -27,3 +27,4 @@ process:
destination: destination:
plugin: config plugin: config
config_name: user.settings config_name: user.settings
translations: true

View file

@ -648,7 +648,7 @@ class ConfigTranslationUiTest extends WebTestBase {
foreach ($languages as $langcode => $data) { foreach ($languages as $langcode => $data) {
// Import a .po file to add a new language with a given number of plural forms // Import a .po file to add a new language with a given number of plural forms
$name = tempnam('temporary://', $langcode . '_') . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', $langcode . '_') . '.po';
file_put_contents($name, $this->getPoFile($data['plurals'])); file_put_contents($name, $this->getPoFile($data['plurals']));
$this->drupalPostForm('admin/config/regional/translate/import', array( $this->drupalPostForm('admin/config/regional/translate/import', array(
'langcode' => $langcode, 'langcode' => $langcode,
@ -684,7 +684,7 @@ class ConfigTranslationUiTest extends WebTestBase {
// First import a .po file with multiple plural forms. // First import a .po file with multiple plural forms.
// This will also automatically add the 'sl' language. // This will also automatically add the 'sl' language.
$name = tempnam('temporary://', "sl_") . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', "sl_") . '.po';
file_put_contents($name, $this->getPoFile(4)); file_put_contents($name, $this->getPoFile(4));
$this->drupalPostForm('admin/config/regional/translate/import', array( $this->drupalPostForm('admin/config/regional/translate/import', array(
'langcode' => 'sl', 'langcode' => 'sl',

View file

@ -69,6 +69,11 @@ function contact_entity_extra_field_info() {
'weight' => -30, 'weight' => -30,
); );
} }
$fields['contact_message'][$bundle]['form']['preview'] = array(
'label' => t('Preview sender message'),
'description' => t('Preview'),
'weight' => 40,
);
$fields['contact_message'][$bundle]['form']['copy'] = array( $fields['contact_message'][$bundle]['form']['copy'] = array(
'label' => t('Send copy to sender'), 'label' => t('Send copy to sender'),
'description' => t('Option'), 'description' => t('Option'),

View file

@ -50,6 +50,7 @@ class ContactSitewideTest extends WebTestBase {
'administer users', 'administer users',
'administer account settings', 'administer account settings',
'administer contact_message fields', 'administer contact_message fields',
'administer contact_message form display',
]); ]);
$this->drupalLogin($admin_user); $this->drupalLogin($admin_user);
@ -283,6 +284,10 @@ class ContactSitewideTest extends WebTestBase {
$this->fieldUIAddNewField(NULL, $field_name, $field_label, 'text'); $this->fieldUIAddNewField(NULL, $field_name, $field_label, 'text');
$field_name = 'field_' . $field_name; $field_name = 'field_' . $field_name;
// Check preview field can be ordered.
$this->drupalGet('admin/structure/contact/manage/' . $contact_form . '/form-display');
$this->assertText(t('Preview'));
// Check that the field is displayed. // Check that the field is displayed.
$this->drupalGet('contact/' . $contact_form); $this->drupalGet('contact/' . $contact_form);
$this->assertText($field_label); $this->assertText($field_label);

View file

@ -2,6 +2,7 @@
namespace Drupal\datetime; namespace Drupal\datetime;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
@ -40,14 +41,28 @@ class DateTimeComputed extends TypedData {
return $this->date; return $this->date;
} }
/** @var \Drupal\Core\Field\FieldItemInterface $item */
$item = $this->getParent(); $item = $this->getParent();
$value = $item->{($this->definition->getSetting('date source'))}; $value = $item->{($this->definition->getSetting('date source'))};
$storage_format = $item->getFieldDefinition()->getSetting('datetime_type') == 'date' ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; $datetime_type = $item->getFieldDefinition()->getSetting('datetime_type');
$storage_format = $datetime_type === DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT;
try { try {
$date = DrupalDateTime::createFromFormat($storage_format, $value, DATETIME_STORAGE_TIMEZONE); $date = DrupalDateTime::createFromFormat($storage_format, $value, DATETIME_STORAGE_TIMEZONE);
if ($date instanceof DrupalDateTime && !$date->hasErrors()) { if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
$this->date = $date; $this->date = $date;
// If the format did not include an explicit time portion, then the
// time will be set from the current time instead. For consistency, we
// set the time to 12:00:00 UTC for date-only fields. This is used so
// that the local date portion is the same, across nearly all time
// zones.
// @see datetime_date_default_time()
// @see http://php.net/manual/en/datetime.createfromformat.php
// @todo Update comment and/or code per the chosen solution in
// https://www.drupal.org/node/2830094
if ($datetime_type === DateTimeItem::DATETIME_TYPE_DATE) {
$this->date->setTime(12, 0, 0);
}
} }
} }
catch (\Exception $e) { catch (\Exception $e) {

View file

@ -0,0 +1,105 @@
<?php
namespace Drupal\Tests\datetime_range\Kernel;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
/**
* Test datetime range field type via API.
*
* @group datetime
*/
class DateRangeItemTest extends FieldKernelTestBase {
/**
* A field storage to use in this test class.
*
* @var \Drupal\field\Entity\FieldStorageConfig
*/
protected $fieldStorage;
/**
* The field used in this test class.
*
* @var \Drupal\field\Entity\FieldConfig
*/
protected $field;
/**
* {@inheritdoc}
*/
public static $modules = [
'datetime',
'datetime_range',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Add a datetime range field.
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => Unicode::strtolower($this->randomMachineName()),
'entity_type' => 'entity_test',
'type' => 'daterange',
'settings' => ['datetime_type' => DateRangeItem::DATETIME_TYPE_DATE],
]);
$this->fieldStorage->save();
$this->field = FieldConfig::create([
'field_storage' => $this->fieldStorage,
'bundle' => 'entity_test',
'required' => TRUE,
]);
$this->field->save();
$display_options = [
'type' => 'daterange_default',
'label' => 'hidden',
'settings' => [
'format_type' => 'fallback',
'separator' => 'UNTRANSLATED',
],
];
EntityViewDisplay::create([
'targetEntityType' => $this->field->getTargetEntityTypeId(),
'bundle' => $this->field->getTargetBundle(),
'mode' => 'default',
'status' => TRUE,
])->setComponent($this->fieldStorage->getName(), $display_options)
->save();
}
/**
* Tests the field configured for date-only.
*/
public function testDateOnly() {
$this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATE);
$field_name = $this->fieldStorage->getName();
// Create an entity.
$entity = EntityTest::create([
'name' => $this->randomString(),
$field_name => [
'value' => '2016-09-21',
'end_value' => '2016-09-21',
],
]);
// Dates are saved without a time value. When they are converted back into
// a \Drupal\datetime\DateTimeComputed object they should all have the same
// time.
$start_date = $entity->{$field_name}->start_date;
sleep(1);
$end_date = $entity->{$field_name}->end_date;
$this->assertEquals($start_date->getTimestamp(), $end_date->getTimestamp());
}
}

View file

@ -150,8 +150,12 @@ class FieldStorageConfigStorage extends ConfigEntityStorage {
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function mapFromStorageRecords(array $records) { protected function mapFromStorageRecords(array $records) {
foreach ($records as &$record) { foreach ($records as $id => &$record) {
$class = $this->fieldTypeManager->getPluginClass($record['type']); $class = $this->fieldTypeManager->getPluginClass($record['type']);
if (empty($class)) {
$config_id = $this->getPrefix() . $id;
throw new \RuntimeException("Unable to determine class for field type '{$record['type']}' found in the '$config_id' configuration");
}
$record['settings'] = $class::storageSettingsFromConfigData($record['settings']); $record['settings'] = $class::storageSettingsFromConfigData($record['settings']);
} }
return parent::mapFromStorageRecords($records); return parent::mapFromStorageRecords($records);

View file

@ -558,7 +558,7 @@ class FileWidget extends WidgetBase implements ContainerFactoryPluginInterface {
} }
// If there are more files uploaded via the same widget, we have to separate // If there are more files uploaded via the same widget, we have to separate
// them, as we display each file in it's own widget. // them, as we display each file in its own widget.
$new_values = array(); $new_values = array();
foreach ($submitted_values as $delta => $submitted_value) { foreach ($submitted_values as $delta => $submitted_value) {
if (is_array($submitted_value['fids'])) { if (is_array($submitted_value['fids'])) {

View file

@ -232,11 +232,17 @@ class ContentEntityNormalizer extends NormalizerBase {
$types = array($types); $types = array($types);
} }
if (empty($types)) {
throw new UnexpectedValueException('No entity type(s) specified');
}
foreach ($types as $type) { foreach ($types as $type) {
if (!isset($type['href'])) { if (!isset($type['href'])) {
throw new UnexpectedValueException('Type must contain an \'href\' attribute.'); throw new UnexpectedValueException('Type must contain an \'href\' attribute.');
} }
$type_uri = $type['href']; $type_uri = $type['href'];
// Check whether the URI corresponds to a known type on this site. Break // Check whether the URI corresponds to a known type on this site. Break
// once one does. // once one does.
if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'], $context)) { if ($typed_data_ids = $this->linkManager->getTypeInternalIds($type['href'], $context)) {

View file

@ -97,21 +97,18 @@ trait HalEntityNormalizationTrait {
if ($this->entity->getEntityType()->hasKey('bundle')) { if ($this->entity->getEntityType()->hasKey('bundle')) {
$normalization = $this->getNormalizedPostEntity(); $normalization = $this->getNormalizedPostEntity();
// @todo Uncomment this in https://www.drupal.org/node/2824827.
// @codingStandardsIgnoreStart
/*
$normalization['_links']['type'] = Url::fromUri('base:rest/type/' . static::$entityTypeId . '/bad_bundle_name'); $normalization['_links']['type'] = Url::fromUri('base:rest/type/' . static::$entityTypeId . '/bad_bundle_name');
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
// DX: 400 when incorrect entity type bundle is specified. // DX: 400 when incorrect entity type bundle is specified.
$response = $this->request($method, $url, $request_options); $response = $this->request($method, $url, $request_options);
// @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853. // @todo Uncomment, remove next 3 in https://www.drupal.org/node/2813853.
// $this->assertResourceErrorResponse(400, 'The type link relation must be specified.', $response); // $this->assertResourceErrorResponse(400, 'No entity type(s) specified', $response);
$this->assertSame(400, $response->getStatusCode()); $this->assertSame(400, $response->getStatusCode());
$this->assertSame([static::$mimeType], $response->getHeader('Content-Type')); $this->assertSame([static::$mimeType], $response->getHeader('Content-Type'));
$this->assertSame($this->serializer->encode(['error' => 'The type link relation must be specified.'], static::$format), (string) $response->getBody()); $this->assertSame($this->serializer->encode(['error' => 'No entity type(s) specified'], static::$format), (string) $response->getBody());
*/
// @codingStandardsIgnoreEnd
unset($normalization['_links']['type']); unset($normalization['_links']['type']);
$request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format); $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);

View file

@ -74,6 +74,36 @@ class DenormalizeTest extends NormalizerTestBase {
} }
} }
/**
* Tests link relation handling with an invalid type.
*/
public function testTypeHandlingWithInvalidType() {
$data_with_invalid_type = array(
'_links' => array(
'type' => array(
'href' => Url::fromUri('base:rest/type/entity_test/entity_test_invalid', array('absolute' => TRUE))->toString(),
),
),
);
$this->setExpectedException(UnexpectedValueException::class);
$this->serializer->denormalize($data_with_invalid_type, $this->entityClass, $this->format);
}
/**
* Tests link relation handling with no types.
*/
public function testTypeHandlingWithNoTypes() {
$data_with_no_types = array(
'_links' => array(
'type' => array(),
),
);
$this->setExpectedException(UnexpectedValueException::class);
$this->serializer->denormalize($data_with_no_types, $this->entityClass, $this->format);
}
/** /**
* Test that a field set to an empty array is different than an absent field. * Test that a field set to an empty array is different than an absent field.
*/ */

View file

@ -27,8 +27,8 @@
* Example .info.yml file properties for a custom module with a po file located * Example .info.yml file properties for a custom module with a po file located
* in the module's folder. * in the module's folder.
* @code * @code
* interface translation project = example_module * 'interface translation project': example_module
* interface translation server pattern = modules/custom/example_module/%project-%version.%language.po * 'interface translation server pattern': modules/custom/example_module/%project-%version.%language.po
* @endcode * @endcode
* *
* Streamwrappers can be used in the server pattern definition. The interface * Streamwrappers can be used in the server pattern definition. The interface
@ -36,10 +36,10 @@
* using the "translations://" streamwrapper. But also other streamwrappers can * using the "translations://" streamwrapper. But also other streamwrappers can
* be used. * be used.
* @code * @code
* interface translation server pattern = translations://%project-%version.%language.po * 'interface translation server pattern': translations://%project-%version.%language.po
* @endcode * @endcode
* @code * @code
* interface translation server pattern = public://translations/%project-%version.%language.po * 'interface translation server pattern': public://translations/%project-%version.%language.po
* @endcode * @endcode
* *
* Multiple custom modules or themes sharing the same po file should have * Multiple custom modules or themes sharing the same po file should have
@ -51,8 +51,8 @@
* Example .info.yml file properties for a custom module with a po file located * Example .info.yml file properties for a custom module with a po file located
* on a remote translation server. * on a remote translation server.
* @code * @code
* interface translation project = example_module * 'interface translation project': example_module
* interface translation server pattern = http://example.com/files/translations/%core/%project/%project-%version.%language.po * 'interface translation server pattern': http://example.com/files/translations/%core/%project/%project-%version.%language.po
* @endcode * @endcode
* *
* Custom themes, features and distributions can implement these .info.yml file * Custom themes, features and distributions can implement these .info.yml file

View file

@ -3,6 +3,7 @@
namespace Drupal\locale\Form; namespace Drupal\locale\Form;
use Drupal\Component\Gettext\PoStreamWriter; use Drupal\Component\Gettext\PoStreamWriter;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
@ -23,14 +24,24 @@ class ExportForm extends FormBase {
*/ */
protected $languageManager; protected $languageManager;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/** /**
* Constructs a new ExportForm. * Constructs a new ExportForm.
* *
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager. * The language manager.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
*/ */
public function __construct(LanguageManagerInterface $language_manager) { public function __construct(LanguageManagerInterface $language_manager, FileSystemInterface $file_system) {
$this->languageManager = $language_manager; $this->languageManager = $language_manager;
$this->fileSystem = $file_system;
} }
/** /**
@ -38,7 +49,8 @@ class ExportForm extends FormBase {
*/ */
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( return new static(
$container->get('language_manager') $container->get('language_manager'),
$container->get('file_system')
); );
} }
@ -148,7 +160,7 @@ class ExportForm extends FormBase {
$item = $reader->readItem(); $item = $reader->readItem();
if (!empty($item)) { if (!empty($item)) {
$uri = tempnam('temporary://', 'po_'); $uri = $this->fileSystem->tempnam('temporary://', 'po_');
$header = $reader->getHeader(); $header = $reader->getHeader();
$header->setProjectName($this->config('system.site')->get('name')); $header->setProjectName($this->config('system.site')->get('name'));
$header->setLanguageName($language_name); $header->setLanguageName($language_name);

View file

@ -43,7 +43,7 @@ class LocaleExportTest extends WebTestBase {
public function testExportTranslation() { public function testExportTranslation() {
// First import some known translations. // First import some known translations.
// This will also automatically add the 'fr' language. // This will also automatically add the 'fr' language.
$name = tempnam('temporary://', "po_") . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
file_put_contents($name, $this->getPoFile()); file_put_contents($name, $this->getPoFile());
$this->drupalPostForm('admin/config/regional/translate/import', array( $this->drupalPostForm('admin/config/regional/translate/import', array(
'langcode' => 'fr', 'langcode' => 'fr',
@ -62,7 +62,7 @@ class LocaleExportTest extends WebTestBase {
$this->assertRaw('msgstr "lundi"', 'French translations present in exported file.'); $this->assertRaw('msgstr "lundi"', 'French translations present in exported file.');
// Import some more French translations which will be marked as customized. // Import some more French translations which will be marked as customized.
$name = tempnam('temporary://', "po2_") . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', "po2_") . '.po';
file_put_contents($name, $this->getCustomPoFile()); file_put_contents($name, $this->getCustomPoFile());
$this->drupalPostForm('admin/config/regional/translate/import', array( $this->drupalPostForm('admin/config/regional/translate/import', array(
'langcode' => 'fr', 'langcode' => 'fr',

View file

@ -369,7 +369,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
* (optional) Additional options to pass to the translation import form. * (optional) Additional options to pass to the translation import form.
*/ */
public function importPoFile($contents, array $options = array()) { public function importPoFile($contents, array $options = array()) {
$name = tempnam('temporary://', "po_") . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
file_put_contents($name, $contents); file_put_contents($name, $contents);
$options['files[file]'] = $name; $options['files[file]'] = $name;
$this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import')); $this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));

View file

@ -351,7 +351,7 @@ class LocalePluralFormatTest extends WebTestBase {
* Additional options to pass to the translation import form. * Additional options to pass to the translation import form.
*/ */
public function importPoFile($contents, array $options = array()) { public function importPoFile($contents, array $options = array()) {
$name = tempnam('temporary://', "po_") . '.po'; $name = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
file_put_contents($name, $contents); file_put_contents($name, $contents);
$options['files[file]'] = $name; $options['files[file]'] = $name;
$this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import')); $this->drupalPostForm('admin/config/regional/translate/import', $options, t('Import'));

View file

@ -136,7 +136,7 @@ class LocaleUpdateTest extends LocaleUpdateBase {
// Check the status on the Available translation status page. // Check the status on the Available translation status page.
$this->assertRaw('<label for="edit-langcodes-de" class="visually-hidden">Update German</label>', 'German language found'); $this->assertRaw('<label for="edit-langcodes-de" class="visually-hidden">Update German</label>', 'German language found');
$this->assertText('Updates for: Contributed module one, Contributed module two, Custom module one, Locale test', 'Updates found'); $this->assertText('Updates for: Contributed module one, Contributed module two, Custom module one, Locale test', 'Updates found');
$this->assertText('Contributed module one (' . format_date($this->timestampNow, 'html_date') . ')', 'Updates for Contrib module one'); $this->assertText('Contributed module one (' . format_date($this->timestampNew, 'html_date') . ')', 'Updates for Contrib module one');
$this->assertText('Contributed module two (' . format_date($this->timestampNew, 'html_date') . ')', 'Updates for Contrib module two'); $this->assertText('Contributed module two (' . format_date($this->timestampNew, 'html_date') . ')', 'Updates for Contrib module two');
// Execute the translation update. // Execute the translation update.

View file

@ -2,6 +2,7 @@
namespace Drupal\migrate; namespace Drupal\migrate;
use Drupal\Component\Utility\Bytes;
use Drupal\Core\Utility\Error; use Drupal\Core\Utility\Error;
use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\migrate\Event\MigrateEvents; use Drupal\migrate\Event\MigrateEvents;
@ -112,23 +113,7 @@ class MigrateExecutable implements MigrateExecutableInterface {
$this->memoryLimit = PHP_INT_MAX; $this->memoryLimit = PHP_INT_MAX;
} }
else { else {
if (!is_numeric($limit)) { $this->memoryLimit = Bytes::toInt($limit);
$last = strtolower(substr($limit, -1));
switch ($last) {
case 'g':
$limit *= 1024;
case 'm':
$limit *= 1024;
case 'k':
$limit *= 1024;
break;
default:
$limit = PHP_INT_MAX;
$this->message->display($this->t('Invalid PHP memory_limit @limit, setting to unlimited.',
array('@limit' => $limit)));
}
}
$this->memoryLimit = $limit;
} }
} }

View file

@ -54,13 +54,16 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
* The migration entity. * The migration entity.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory. * The configuration factory.
* @param \Drupal\Core\Language\ConfigurableLanguageManagerInterface $language_manager * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager. * The language manager.
*/ */
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager) { public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration); parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
$this->config = $config_factory->getEditable($configuration['config_name']); $this->config = $config_factory->getEditable($configuration['config_name']);
$this->language_manager = $language_manager; $this->language_manager = $language_manager;
if ($this->isTranslationDestination()) {
$this->supportsRollback = TRUE;
}
} }
/** /**
@ -81,7 +84,7 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
* {@inheritdoc} * {@inheritdoc}
*/ */
public function import(Row $row, array $old_destination_id_values = array()) { public function import(Row $row, array $old_destination_id_values = array()) {
if ($row->hasDestinationProperty('langcode')) { if ($this->isTranslationDestination()) {
$this->config = $this->language_manager->getLanguageConfigOverride($row->getDestinationProperty('langcode'), $this->config->getName()); $this->config = $this->language_manager->getLanguageConfigOverride($row->getDestinationProperty('langcode'), $this->config->getName());
} }
@ -91,7 +94,11 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
} }
} }
$this->config->save(); $this->config->save();
return [$this->config->getName()]; $ids[] = $this->config->getName();
if ($this->isTranslationDestination()) {
$ids[] = $row->getDestinationProperty('langcode');
}
return $ids;
} }
/** /**
@ -106,6 +113,9 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
*/ */
public function getIds() { public function getIds() {
$ids['config_name']['type'] = 'string'; $ids['config_name']['type'] = 'string';
if ($this->isTranslationDestination()) {
$ids['langcode']['type'] = 'string';
}
return $ids; return $ids;
} }
@ -118,4 +128,25 @@ class Config extends DestinationBase implements ContainerFactoryPluginInterface,
return $this->dependencies; return $this->dependencies;
} }
/**
* Get whether this destination is for translations.
*
* @return bool
* Whether this destination is for translations.
*/
protected function isTranslationDestination() {
return !empty($this->configuration['translations']);
}
/**
* {@inheritdoc}
*/
public function rollback(array $destination_identifier) {
if ($this->isTranslationDestination()) {
$language = $destination_identifier['langcode'];
$config = $this->language_manager->getLanguageConfigOverride($language, $this->config->getName());
$config->delete();
}
}
} }

View file

@ -0,0 +1,170 @@
<?php
namespace Drupal\Tests\migrate\Kernel;
use Drupal\migrate\MigrateExecutable;
/**
* Tests rolling back of configuration objects.
*
* @group migrate
*/
class MigrateConfigRollbackTest extends MigrateTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['system', 'language', 'config_translation'];
/**
* Tests rolling back configuration.
*/
public function testConfigRollback() {
// Use system.site configuration to demonstrate importing and rolling back
// configuration.
$variable = [
[
'id' => 'site_name',
'site_name' => 'Some site',
'site_slogan' => 'Awesome slogan',
],
];
$ids = [
'id' =>
[
'type' => 'string'
],
];
$definition = [
'id' => 'config',
'migration_tags' => ['Import and rollback test'],
'source' => [
'plugin' => 'embedded_data',
'data_rows' => $variable,
'ids' => $ids,
],
'process' => [
'name' => 'site_name',
'slogan' => 'site_slogan',
],
'destination' => [
'plugin' => 'config',
'config_name' => 'system.site',
],
];
/** @var \Drupal\migrate\Plugin\Migration $config_migration */
$config_migration = \Drupal::service('plugin.manager.migration')
->createStubMigration($definition);
$config_id_map = $config_migration->getIdMap();
// Rollback is not enabled for configuration translations.
$this->assertFalse($config_migration->getDestinationPlugin()->supportsRollback());
// Import and validate config entities were created.
$config_executable = new MigrateExecutable($config_migration, $this);
$config_executable->import();
$config = $this->config('system.site');
$this->assertSame('Some site', $config->get('name'));
$this->assertSame('Awesome slogan', $config->get('slogan'));
$map_row = $config_id_map->getRowBySource(['id' => $variable[0]['id']]);
$this->assertNotNull($map_row['destid1']);
// Rollback and verify the configuration changes are still there.
$config_executable->rollback();
$config = $this->config('system.site');
$this->assertSame('Some site', $config->get('name'));
$this->assertSame('Awesome slogan', $config->get('slogan'));
// Confirm the map row is deleted.
$map_row = $config_id_map->getRowBySource(['id' => $variable[0]['id']]);
$this->assertNull($map_row['destid1']);
// We use system configuration to demonstrate importing and rolling back
// configuration translations.
$i18n_variable = [
[
'id' => 'site_name',
'language' => 'fr',
'site_name' => 'fr - Some site',
'site_slogan' => 'fr - Awesome slogan',
],
[
'id' => 'site_name',
'language' => 'is',
'site_name' => 'is - Some site',
'site_slogan' => 'is - Awesome slogan',
],
];
$ids = [
'id' =>
[
'type' => 'string'
],
'language' =>
[
'type' => 'string'
]
];
$definition = [
'id' => 'i18n_config',
'migration_tags' => ['Import and rollback test'],
'source' => [
'plugin' => 'embedded_data',
'data_rows' => $i18n_variable,
'ids' => $ids,
],
'process' => [
'langcode' => 'language',
'name' => 'site_name',
'slogan' => 'site_slogan',
],
'destination' => [
'plugin' => 'config',
'config_name' => 'system.site',
'translations' => 'true',
],
];
$config_migration = \Drupal::service('plugin.manager.migration')
->createStubMigration($definition);
$config_id_map = $config_migration->getIdMap();
// Rollback is enabled for configuration translations.
$this->assertTrue($config_migration->getDestinationPlugin()->supportsRollback());
// Import and validate config entities were created.
$config_executable = new MigrateExecutable($config_migration, $this);
$config_executable->import();
$language_manager = \Drupal::service('language_manager');
foreach ($i18n_variable as $row) {
$langcode = $row['language'];
/** @var \Drupal\language\Config\LanguageConfigOverride $config_translation */
$config_translation = $language_manager->getLanguageConfigOverride($langcode, 'system.site');
$this->assertSame($row['site_name'], $config_translation->get('name'));
$this->assertSame($row['site_slogan'], $config_translation->get('slogan'));
$map_row = $config_id_map->getRowBySource(['id' => $row['id'], 'language' => $row['language']]);
$this->assertNotNull($map_row['destid1']);
}
// Rollback and verify the translation have been removed.
$config_executable->rollback();
foreach ($i18n_variable as $row) {
$langcode = $row['language'];
$config_translation = $language_manager->getLanguageConfigOverride($langcode, 'system.site');
$this->assertNull($config_translation->get('name'));
$this->assertNull($config_translation->get('slogan'));
// Confirm the map row is deleted.
$map_row = $config_id_map->getRowBySource(['id' => $row['id'], 'language' => $langcode]);
$this->assertFalse($map_row);
}
// Test that the configuration is still present.
$config = $this->config('system.site');
$this->assertSame('Some site', $config->get('name'));
$this->assertSame('Awesome slogan', $config->get('slogan'));
}
}

View file

@ -3,7 +3,7 @@
namespace Drupal\Tests\migrate\Kernel\process; namespace Drupal\Tests\migrate\Kernel\process;
use Drupal\Core\StreamWrapper\StreamWrapperInterface; use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\KernelTests\Core\File\FileTestBase; use Drupal\KernelTests\KernelTestBase;
use Drupal\migrate\MigrateExecutableInterface; use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\migrate\process\FileCopy; use Drupal\migrate\Plugin\migrate\process\FileCopy;
use Drupal\migrate\Row; use Drupal\migrate\Row;
@ -13,7 +13,7 @@ use Drupal\migrate\Row;
* *
* @group migrate * @group migrate
*/ */
class CopyFileTest extends FileTestBase { class CopyFileTest extends KernelTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -180,4 +180,39 @@ class CopyFileTest extends FileTestBase {
return $result; 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;
}
} }

View file

@ -44,9 +44,6 @@ class ConfigTest extends UnitTestCase {
$row = $this->getMockBuilder('Drupal\migrate\Row') $row = $this->getMockBuilder('Drupal\migrate\Row')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$row->expects($this->once())
->method('hasDestinationProperty')
->will($this->returnValue(FALSE));
$row->expects($this->any()) $row->expects($this->any())
->method('getRawDestination') ->method('getRawDestination')
->will($this->returnValue($source)); ->will($this->returnValue($source));
@ -94,9 +91,6 @@ class ConfigTest extends UnitTestCase {
$row = $this->getMockBuilder('Drupal\migrate\Row') $row = $this->getMockBuilder('Drupal\migrate\Row')
->disableOriginalConstructor() ->disableOriginalConstructor()
->getMock(); ->getMock();
$row->expects($this->once())
->method('hasDestinationProperty')
->will($this->returnValue($source));
$row->expects($this->any()) $row->expects($this->any())
->method('getRawDestination') ->method('getRawDestination')
->will($this->returnValue($source)); ->will($this->returnValue($source));
@ -110,9 +104,9 @@ class ConfigTest extends UnitTestCase {
->method('getLanguageConfigOverride') ->method('getLanguageConfigOverride')
->with('mi', 'd8_config') ->with('mi', 'd8_config')
->will($this->returnValue($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(array('config_name' => 'd8_config', 'translations' => 'true'), 'd8_config', array('pluginId' => 'd8_config'), $migration, $config_factory, $language_manager);
$destination_id = $destination->import($row); $destination_id = $destination->import($row);
$this->assertEquals($destination_id, ['d8_config']); $this->assertEquals($destination_id, ['d8_config', 'mi']);
} }
} }

View file

@ -44405,6 +44405,30 @@ $connection->insert('url_alias')
'dst' => 'alias-three', 'dst' => 'alias-three',
'language' => '', 'language' => '',
)) ))
->values(array(
'pid' => '4',
'src' => 'node/10',
'dst' => 'the-real-mccoy',
'language' => 'en',
))
->values(array(
'pid' => '5',
'src' => 'node/11',
'dst' => 'le-vrai-mccoy',
'language' => 'fr',
))
->values(array(
'pid' => '6',
'src' => 'node/12',
'dst' => 'abantu-zulu',
'language' => 'zu',
))
->values(array(
'pid' => '7',
'src' => 'node/13',
'dst' => 'the-zulu-people',
'language' => 'en',
))
->execute(); ->execute();
$connection->schema()->createTable('users', array( $connection->schema()->createTable('users', array(

View file

@ -4485,6 +4485,18 @@ $connection->insert('field_data_field_file')
'field_file_display' => '1', 'field_file_display' => '1',
'field_file_description' => 'file desc', '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(); ->execute();
$connection->schema()->createTable('field_data_field_float', array( $connection->schema()->createTable('field_data_field_float', array(
@ -6674,6 +6686,18 @@ $connection->insert('field_revision_field_file')
'field_file_display' => '1', 'field_file_display' => '1',
'field_file_description' => 'file desc', '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(); ->execute();
$connection->schema()->createTable('field_revision_field_float', array( $connection->schema()->createTable('field_revision_field_float', array(
@ -8307,6 +8331,16 @@ $connection->insert('file_managed')
'status' => '1', 'status' => '1',
'timestamp' => '1421727515', 'timestamp' => '1421727515',
)) ))
->values(array(
'fid' => '2',
'uid' => '1',
'filename' => 'ds9.txt',
'uri' => 'public://ds9.txt',
'filemime' => 'text/plain',
'filesize' => '4720',
'status' => '1',
'timestamp' => '1421727516',
))
->execute(); ->execute();
$connection->schema()->createTable('file_usage', array( $connection->schema()->createTable('file_usage', array(
@ -8375,6 +8409,13 @@ $connection->insert('file_usage')
'id' => '1', 'id' => '1',
'count' => '1', 'count' => '1',
)) ))
->values(array(
'fid' => '2',
'module' => 'file',
'type' => 'user',
'id' => '2',
'count' => '1',
))
->execute(); ->execute();
$connection->schema()->createTable('filter', array( $connection->schema()->createTable('filter', array(
@ -43860,7 +43901,7 @@ $connection->insert('variable')
)) ))
->values(array( ->values(array(
'name' => 'menu_override_parent_selector', 'name' => 'menu_override_parent_selector',
'value' => 'b:0;', 'value' => 'b:1;',
)) ))
->values(array( ->values(array(
'name' => 'menu_parent_article', 'name' => 'menu_parent_article',

View file

@ -45,7 +45,7 @@ class MigrateUpgrade7Test extends MigrateUpgradeTestBase {
'editor' => 2, 'editor' => 2,
'field_config' => 49, 'field_config' => 49,
'field_storage_config' => 37, 'field_storage_config' => 37,
'file' => 1, 'file' => 2,
'filter_format' => 7, 'filter_format' => 7,
'image_style' => 6, 'image_style' => 6,
'language_content_settings' => 2, 'language_content_settings' => 2,

View file

@ -0,0 +1,79 @@
__ ___ ___
,' ,' | | `. `.
,' ,' |===| `. `.
/ // |___| \\ \
/ // |___| \\ \
//// |___| \\\\
/ / || || \ \
/ / || || \ \
/| | || || | |\
|| | | : o : | | ||
| \| | .===. | |/ |
| |\ /| (___) |\ /| |
|__||.\ .-. // /,_._,\ \\ .-. /.||__|
|__||_.\ `-.\ //_ [:(|):] _\\ /.-' /._||__|
__/| ||___`._____ ___\\__/___/_ ||| _\___\__//___ _____.'___||_ |\__
/___//__________/.-/_____________|.-.|_____________\-.\__________\\___\
\___\\__\\\_____\`-\__\\\\__\____|_-_|____/_//_____/-'/__//______//__//
\|__||__..' // \ _ \__|||__/ _ / \\ `..__||__|/
|__||_./ .-'/ \\ |(|)| // \`-. \..||__|
| || / `-' \\ \'/ // `-' \ || |
| |/ \| :(-): |/ \| |
| /| | : o : | |\ |
|| | | |___| | | ||
\| | || || | |/
\ \ || || / /
\ \ ||___|| / /
\\\\ |___| ////
\ \\ |___| // /
\ \\ | | // /
`. `. |===| ,' ,'
`._`. |___| ,'_,'
_ _
_____---' \_n_/ `---_____
_ / ... ----------- ... \ _
( )-' . '::.\__ V __/.::' . `-( )
_ .-' ':::. ____ \ / ____ .:::' `-. _
,-'.`' __.--' \ | | / `--.__ `'.`-.
/ ''::.. \ || || / ..::'' \
/ ..... ,'\,' ||_|| `./`. ..... \
/ :::::' ,' | | `. '::::: \
| '::: ,' | | `. :::' |
_/ :: / |___| \ :: \_
(/ / ,-' `-. \ \)
_/ `. ,-' ooo oo `-. ,' \_
| /`./ ,-'\ /`-. \.'\ |
| .: / / \ \_ __.---.__ _/ / \ \ :. |
.' :;: | _ / o \[ ' \ / ` ]/ \ _ | ::: `.
| ':: | ( `-. / | | \ ,-' ) | ::' |
|: ': | `-./ / ___ \ \,-' | :' :|
.':: ' | | / `-. .-' . `-. .-' \ o | | ' ::`.
| ::. | | o ,| `-. / \`_|_'/ \ .-' |. o | | .:: |
\ |_ |____| | ` / \ ' | |____| _| /
(| _] ]____[ |- ( (O) ) -| ]____[ [_ |)
/.: | | | | . \_ _/ . | | | | :.\
| :' | | o `|-,-' \ /..|..\ / `-.-|' o | |. ': |
`. :: | | o \ .-' `-.___.-' `-. / o | | :: .'
| .:: | _.\ \| | | \/ /._ | ::. |
| ': | _.-' \ o \ | | / o / `-._ | :' |
`. __ |__.-'_ _.\ /[_.__ | | __._]\ o /._ _`-.__| __ .'
| \ \_.--''.' .-' \ / / `---' \ \ / `-. `.``--__/ / |
|_\ __ ,',-' `-./ o \,-' `-.`. __ /_|
\\ / .',' `-. oo .-. oo ,-' `.`. \ //
(\\ \ \ `-._| |_,-' / / //)
\\ ) \ (_) / ( //
/ \/ `. ,' \/ \
\ .::. `. ,' .::: /
\ ':::. `-./`. .'\.-' '''''' /
\ ''' /_ _ _\ ::.. /
`-.'::' `--.______| |______.--' ,-'
`-'`-._ .. .: .: _,-'`'
(_)-. ::. '':::: :::::: : ,-(_)
\_____ '' _ _ ' _____/
---._/ u \_.---
Used with permission from:
Orbital Space Station (Terok Nor - Deep Space 9) - Joe Reiss
https://startrekasciiart.blogspot.co.uk/2011/05/deep-space-nine.html

View file

@ -66,13 +66,6 @@ views.argument.node_vid:
type: boolean type: boolean
label: 'Exclude' label: 'Exclude'
views.argument_default.node:
type: sequence
label: 'Content ID from URL'
sequence:
type: string
label: 'Nid'
views.field.node: views.field.node:
type: views_field type: views_field
label: 'Node' label: 'Node'

View file

@ -73,6 +73,11 @@ class NodePreviewForm extends FormBase {
$view_mode = $node->preview_view_mode; $view_mode = $node->preview_view_mode;
$query_options = array('query' => array('uuid' => $node->uuid())); $query_options = array('query' => array('uuid' => $node->uuid()));
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$query_options['query']['destination'] = $query->get('destination');
}
$form['backlink'] = array( $form['backlink'] = array(
'#type' => 'link', '#type' => 'link',
'#title' => $this->t('Back to content editing'), '#title' => $this->t('Back to content editing'),
@ -80,9 +85,11 @@ class NodePreviewForm extends FormBase {
'#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options, '#options' => array('attributes' => array('class' => array('node-preview-backlink'))) + $query_options,
); );
$view_mode_options = $this->entityManager->getViewModeOptionsByBundle('node', $node->bundle()); // 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());
// Unset view modes that are not used in the front end. // Unset view modes that are not used in the front end.
unset($view_mode_options['default']);
unset($view_mode_options['rss']); unset($view_mode_options['rss']);
unset($view_mode_options['search_index']); unset($view_mode_options['search_index']);
@ -116,10 +123,18 @@ class NodePreviewForm extends FormBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function submitForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRedirect('entity.node.preview', array( $route_parameters = [
'node_preview' => $form_state->getValue('uuid'), 'node_preview' => $form_state->getValue('uuid'),
'view_mode_id' => $form_state->getValue('view_mode'), 'view_mode_id' => $form_state->getValue('view_mode'),
)); ];
$options = [];
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$options['query']['destination'] = $query->get('destination');
$query->remove('destination');
}
$form_state->setRedirect('entity.node.preview', $route_parameters, $options);
} }
} }

View file

@ -22,6 +22,9 @@ class NodeForm extends ContentEntityForm {
/** /**
* Whether this node has been previewed or not. * Whether this node has been previewed or not.
*
* @deprecated Scheduled for removal in Drupal 8.3.x. Use the form state
* property 'has_been_previewed' instead.
*/ */
protected $hasBeenPreviewed = FALSE; protected $hasBeenPreviewed = FALSE;
@ -65,6 +68,8 @@ class NodeForm extends ContentEntityForm {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function form(array $form, FormStateInterface $form_state) { 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 // Try to restore from temp store, this must be done before calling
// parent::form(). // parent::form().
$store = $this->tempStoreFactory->get('node_preview'); $store = $this->tempStoreFactory->get('node_preview');
@ -89,6 +94,7 @@ class NodeForm extends ContentEntityForm {
$this->entity = $preview->getFormObject()->getEntity(); $this->entity = $preview->getFormObject()->getEntity();
$this->entity->in_preview = NULL; $this->entity->in_preview = NULL;
$form_state->set('has_been_previewed', TRUE);
$this->hasBeenPreviewed = TRUE; $this->hasBeenPreviewed = TRUE;
} }
@ -231,7 +237,7 @@ class NodeForm extends ContentEntityForm {
$node = $this->entity; $node = $this->entity;
$preview_mode = $node->type->entity->getPreviewMode(); $preview_mode = $node->type->entity->getPreviewMode();
$element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $this->hasBeenPreviewed; $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
// If saving is an option, privileged users get dedicated form submit // If saving is an option, privileged users get dedicated form submit
// buttons to adjust the publishing status while saving in one go. // buttons to adjust the publishing status while saving in one go.
@ -338,10 +344,19 @@ class NodeForm extends ContentEntityForm {
$store = $this->tempStoreFactory->get('node_preview'); $store = $this->tempStoreFactory->get('node_preview');
$this->entity->in_preview = TRUE; $this->entity->in_preview = TRUE;
$store->set($this->entity->uuid(), $form_state); $store->set($this->entity->uuid(), $form_state);
$form_state->setRedirect('entity.node.preview', array(
$route_parameters = [
'node_preview' => $this->entity->uuid(), 'node_preview' => $this->entity->uuid(),
'view_mode_id' => 'default', 'view_mode_id' => 'full',
)); ];
$options = [];
$query = $this->getRequest()->query;
if ($query->has('destination')) {
$options['query']['destination'] = $query->get('destination');
$query->remove('destination');
}
$form_state->setRedirect('entity.node.preview', $route_parameters, $options);
} }
/** /**

View file

@ -6,6 +6,7 @@ use Drupal\comment\Tests\CommentTestTrait;
use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Component\Utility\Unicode; use Drupal\Component\Utility\Unicode;
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Url;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait; use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldStorageConfig;
@ -195,7 +196,7 @@ class PagePreviewTest extends NodeTestBase {
->save(); ->save();
$view_mode_edit = array('view_mode' => 'teaser'); $view_mode_edit = array('view_mode' => 'teaser');
$this->drupalPostForm('node/preview/' . $uuid . '/default', $view_mode_edit, t('Switch')); $this->drupalPostForm('node/preview/' . $uuid . '/full', $view_mode_edit, t('Switch'));
$this->assertRaw('view-mode-teaser', 'View mode teaser class found.'); $this->assertRaw('view-mode-teaser', 'View mode teaser class found.');
$this->assertNoText($edit[$body_key], 'Body not displayed.'); $this->assertNoText($edit[$body_key], 'Body not displayed.');
@ -292,6 +293,29 @@ class PagePreviewTest extends NodeTestBase {
$this->clickLink(t('Back to content editing')); $this->clickLink(t('Back to content editing'));
$this->assertRaw('edit-submit'); $this->assertRaw('edit-submit');
// Check that destination is remembered when clicking on preview. When going
// back to the edit form and clicking save, we should go back to the
// original destination, if set.
$destination = 'node';
$this->drupalPostForm($node->toUrl('edit-form'), [], t('Preview'), ['query' => ['destination' => $destination]]);
$parameters = ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'];
$options = ['absolute' => TRUE, 'query' => ['destination' => $destination]];
$this->assertUrl(Url::fromRoute('entity.node.preview', $parameters, $options));
$this->drupalPostForm(NULL, ['view_mode' => 'teaser'], t('Switch'));
$this->clickLink(t('Back to content editing'));
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertUrl($destination);
// Check that preview page works as expected without a destination set.
$this->drupalPostForm($node->toUrl('edit-form'), [], t('Preview'));
$parameters = ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'];
$this->assertUrl(Url::fromRoute('entity.node.preview', $parameters, ['absolute' => TRUE]));
$this->drupalPostForm(NULL, ['view_mode' => 'teaser'], t('Switch'));
$this->clickLink(t('Back to content editing'));
$this->drupalPostForm(NULL, [], t('Save'));
$this->assertUrl($node->toUrl());
$this->assertResponse(200);
// Assert multiple items can be added and are not lost when previewing. // Assert multiple items can be added and are not lost when previewing.
$test_image_1 = current($this->drupalGetTestFiles('image', 39325)); $test_image_1 = current($this->drupalGetTestFiles('image', 39325));
$edit_image_1['files[field_image_0][]'] = drupal_realpath($test_image_1->uri); $edit_image_1['files[field_image_0][]'] = drupal_realpath($test_image_1->uri);
@ -418,7 +442,7 @@ class PagePreviewTest extends NodeTestBase {
/** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */ /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
$controller_resolver = \Drupal::service('controller_resolver'); $controller_resolver = \Drupal::service('controller_resolver');
$node_preview_controller = $controller_resolver->getControllerFromDefinition('\Drupal\node\Controller\NodePreviewController::view'); $node_preview_controller = $controller_resolver->getControllerFromDefinition('\Drupal\node\Controller\NodePreviewController::view');
$node_preview_controller($node, 'default'); $node_preview_controller($node, 'full');
} }
/** /**
@ -439,7 +463,7 @@ class PagePreviewTest extends NodeTestBase {
$edit2 = array($title_key => 'Another page title'); $edit2 = array($title_key => 'Another page title');
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit2, t('Preview')); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit2, t('Preview'));
$this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'default'], ['absolute' => TRUE])); $this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'full'], ['absolute' => TRUE]));
$this->assertText($edit2[$title_key]); $this->assertText($edit2[$title_key]);
} }

View file

@ -0,0 +1,23 @@
/**
* @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;
}

View file

@ -0,0 +1,32 @@
/**
* @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;
}

View file

@ -3,49 +3,50 @@
* Visual styling for summary and details in the Settings Tray module's off canvas tray. * Visual styling for summary and details in the Settings Tray module's off canvas tray.
*/ */
.ui-dialog-offcanvas details, .ui-dialog-outside-in details,
.ui-dialog-offcanvas summary, .ui-dialog-outside-in summary,
.ui-dialog-offcanvas .ui-dialog-content { .ui-dialog-outside-in .ui-dialog-content {
background: #474747; background: #474747;
color: #ddd; color: #ddd;
} }
.ui-dialog-offcanvas summary a { .ui-dialog-outside-in summary a {
color: #ddd; color: #ddd;
padding: 0 inherit; padding-top: 0;
padding-bottom: 0;
} }
.ui-dialog-offcanvas summary a:hover, .ui-dialog-outside-in summary a:hover,
.ui-dialog-offcanvas summary a:focus { .ui-dialog-outside-in summary a:focus {
color: #fff; color: #fff;
} }
.ui-dialog-offcanvas details, .ui-dialog-outside-in details,
.ui-dialog-offcanvas summary, .ui-dialog-outside-in summary,
.ui-dialog-offcanvas .details-wrapper { .ui-dialog-outside-in .details-wrapper {
border-width: 0; border-width: 0;
/* Cancel out the padding of the parent. */ /* Cancel out the padding of the parent. */
margin: 0 -20px; margin: 0 -20px;
padding: 0 20px; padding: 0 20px;
} }
.ui-dialog-offcanvas summary { .ui-dialog-outside-in summary {
text-shadow: none; text-shadow: none;
outline: none; outline: none;
padding: 10px 20px; padding: 10px 20px;
font-size: 14px; font-size: 14px;
transition: all .5s ease; transition: all .5s ease;
} }
.ui-dialog-offcanvas summary:hover, .ui-dialog-outside-in summary:hover,
.ui-dialog-offcanvas summary:focus { .ui-dialog-outside-in summary:focus {
background-color: #222; background-color: #222;
outline: none; outline: none;
} }
.ui-dialog-offcanvas details[open] { .ui-dialog-outside-in details[open] {
background-color: #333; background-color: #333;
padding-bottom: 10px; padding-bottom: 10px;
} }
.ui-dialog-offcanvas details[open] > summary { .ui-dialog-outside-in details[open] > summary {
background-color: #333; background-color: #333;
color: #eee; color: #eee;
} }
.ui-dialog-offcanvas details[open] > summary:hover { .ui-dialog-outside-in details[open] > summary:hover {
background-color: #222; background-color: #222;
color: #fff; color: #fff;
} }

View file

@ -3,40 +3,40 @@
* Visual styling for forms in the Settings Tray module's off canvas tray. * Visual styling for forms in the Settings Tray module's off canvas tray.
*/ */
.ui-dialog-offcanvas label { .ui-dialog-outside-in label {
line-height: normal; line-height: normal;
font-size: 12px; font-size: 12px;
font-weight: normal; font-weight: normal;
color: #ddd; color: #ddd;
} }
.ui-dialog-offcanvas .description, .ui-dialog-outside-in .description,
.ui-dialog-offcanvas .form-item .description, .ui-dialog-outside-in .form-item .description,
.ui-dialog-offcanvas .details-description { .ui-dialog-outside-in .details-description {
color: #ddd; color: #ddd;
margin-top: 5px; margin-top: 5px;
font-size: 12px; font-size: 12px;
font-style: normal; font-style: normal;
} }
.ui-dialog-offcanvas .details-wrapper .description { .ui-dialog-outside-in .details-wrapper .description {
color: #bbb; color: #bbb;
} }
.ui-dialog-offcanvas .form-item { .ui-dialog-outside-in .form-item {
margin-bottom: 10px; margin-bottom: 10px;
margin-top: 10px; margin-top: 10px;
} }
/* Set size and position for all inputs. */ /* Set size and position for all inputs. */
.ui-dialog-offcanvas .form-select, .ui-dialog-outside-in .form-select,
.ui-dialog-offcanvas .form-text, .ui-dialog-outside-in .form-text,
.ui-dialog-offcanvas .form-tel, .ui-dialog-outside-in .form-tel,
.ui-dialog-offcanvas .form-email, .ui-dialog-outside-in .form-email,
.ui-dialog-offcanvas .form-url, .ui-dialog-outside-in .form-url,
.ui-dialog-offcanvas .form-search, .ui-dialog-outside-in .form-search,
.ui-dialog-offcanvas .form-number, .ui-dialog-outside-in .form-number,
.ui-dialog-offcanvas .form-color, .ui-dialog-outside-in .form-color,
.ui-dialog-offcanvas .form-file, .ui-dialog-outside-in .form-file,
.ui-dialog-offcanvas .form-textarea, .ui-dialog-outside-in .form-textarea,
.ui-dialog-offcanvas .form-date, .ui-dialog-outside-in .form-date,
.ui-dialog-offcanvas .form-time { .ui-dialog-outside-in .form-time {
box-sizing: border-box; box-sizing: border-box;
max-width: 100%; max-width: 100%;
padding: 6px; padding: 6px;
@ -53,58 +53,58 @@
cursor: pointer; cursor: pointer;
} }
/* Reduce contrast for fields against dark backround. */ /* Reduce contrast for fields against dark backround. */
.ui-dialog-offcanvas .form-text, .ui-dialog-outside-in .form-text,
.ui-dialog-offcanvas .form-tel, .ui-dialog-outside-in .form-tel,
.ui-dialog-offcanvas .form-email, .ui-dialog-outside-in .form-email,
.ui-dialog-offcanvas .form-url, .ui-dialog-outside-in .form-url,
.ui-dialog-offcanvas .form-search, .ui-dialog-outside-in .form-search,
.ui-dialog-offcanvas .form-number, .ui-dialog-outside-in .form-number,
.ui-dialog-offcanvas .form-color, .ui-dialog-outside-in .form-color,
.ui-dialog-offcanvas .form-file, .ui-dialog-outside-in .form-file,
.ui-dialog-offcanvas .form-textarea, .ui-dialog-outside-in .form-textarea,
.ui-dialog-offcanvas .form-date, .ui-dialog-outside-in .form-date,
.ui-dialog-offcanvas .form-time { .ui-dialog-outside-in .form-time {
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .125); box-shadow: inset 0 1px 2px rgba(0, 0, 0, .125);
background-color: #eee; background-color: #eee;
border-color: #333; border-color: #333;
color: #595959; color: #595959;
} }
.ui-dialog-offcanvas .form-text:focus, .ui-dialog-outside-in .form-text:focus,
.ui-dialog-offcanvas .form-tel:focus, .ui-dialog-outside-in .form-tel:focus,
.ui-dialog-offcanvas .form-email:focus, .ui-dialog-outside-in .form-email:focus,
.ui-dialog-offcanvas .form-url:focus, .ui-dialog-outside-in .form-url:focus,
.ui-dialog-offcanvas .form-search:focus, .ui-dialog-outside-in .form-search:focus,
.ui-dialog-offcanvas .form-number:focus, .ui-dialog-outside-in .form-number:focus,
.ui-dialog-offcanvas .form-color:focus, .ui-dialog-outside-in .form-color:focus,
.ui-dialog-offcanvas .form-file:focus, .ui-dialog-outside-in .form-file:focus,
.ui-dialog-offcanvas .form-textarea:focus, .ui-dialog-outside-in .form-textarea:focus,
.ui-dialog-offcanvas .form-date:focus, .ui-dialog-outside-in .form-date:focus,
.ui-dialog-offcanvas .form-time:focus { .ui-dialog-outside-in .form-time:focus {
border-color: #40b6ff; border-color: #40b6ff;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .125), 0 0 8px #40b6ff; box-shadow: inset 0 1px 3px rgba(0, 0, 0, .125), 0 0 8px #40b6ff;
background-color: #fff; background-color: #fff;
} }
.ui-dialog-offcanvas input[type="checkbox"], .ui-dialog-outside-in input[type="checkbox"],
.ui-dialog-offcanvas .checkbox, .ui-dialog-outside-in .checkbox,
.ui-dialog-offcanvas input[type="radio"], .ui-dialog-outside-in input[type="radio"],
.ui-dialog-offcanvas .radio { .ui-dialog-outside-in .radio {
position: static; position: static;
margin: 0; margin: 0;
} }
.ui-dialog-offcanvas td .checkbox { .ui-dialog-outside-in td .checkbox {
display: table-cell; display: table-cell;
line-height: normal; line-height: normal;
vertical-align: middle; vertical-align: middle;
} }
.ui-dialog-offcanvas .form-checkbox, .ui-dialog-outside-in .form-checkbox,
.ui-dialog-offcanvas .form-radio { .ui-dialog-outside-in .form-radio {
/* Add contrast for dark background. */ /* Add contrast for dark background. */
box-shadow: 0 0 2px 1px #000; box-shadow: 0 0 2px 1px #000;
} }
.ui-dialog-offcanvas input[type="radio"] { .ui-dialog-outside-in input[type="radio"] {
/* Add full circular radius. */ /* Add full circular radius. */
border-radius: 50%; border-radius: 50%;
} }
.ui-dialog-offcanvas .form-actions { .ui-dialog-outside-in .form-actions {
text-align: center; text-align: center;
} }

View file

@ -2,31 +2,6 @@
* @file * @file
* Styling for Settings Tray module. * Styling for Settings Tray module.
*/ */
/* Position the offcanvas tray container outside the right of the viewport. */
.ui-dialog-offcanvas {
box-sizing: border-box;
height: 100%;
overflow: visible;
}
/* Shift the main canvas to the right for right-to-left languages. */
[dir="rtl"] #main-canvas-wrapper.js-tray-open #main-canvas {
right: 0;
}
/* Wrap the form that's inside the 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;
}
/* /*
* Position the edit toolbar tab. * Position the edit toolbar tab.
* @todo Move changes into contextual module when Settings Tray is not * @todo Move changes into contextual module when Settings Tray is not
@ -38,3 +13,26 @@
[dir="rtl"] .toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab { [dir="rtl"] .toolbar .toolbar-bar .contextual-toolbar-tab.toolbar-tab {
float: right; 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;
}
}

View file

@ -10,18 +10,6 @@
* file: https://www.drupal.org/node/2784443. * file: https://www.drupal.org/node/2784443.
*/ */
/* Transition the offcanvas tray container, with 2s delay to match main canvas speed. */
#offcanvas {
-webkit-transition: all .7s ease 2s;
-moz-transition: all .7s ease 2s;
transition: all .7s ease 2s;
}
#main-canvas-wrapper #main-canvas,
#main-canvas-wrapper.js-tray-open #main-canvas {
-webkit-transition: all .7s ease;
-moz-transition: all .7s ease;
transition: all .7s ease;
}
/* Transition the edit icon in the toolbar. */ /* Transition the edit icon in the toolbar. */
#toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before { #toolbar-bar.button.toolbar-icon.toolbar-icon.toolbar-icon-edit:before {
@ -31,9 +19,9 @@
} }
/* Transition the editables on the page, their contextual links and their hover states. */ /* Transition the editables on the page, their contextual links and their hover states. */
#main-canvas-wrapper .contextual, .dialog-offcanvas__main-canvas .contextual,
#main-canvas-wrapper .js-outside-in-edit-mode .outside-in-editable, .dialog-offcanvas__main-canvas .js-outside-in-edit-mode .outside-in-editable,
#main-canvas-wrapper.js-tray-open .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; -webkit-transition: all .7s ease;
-moz-transition: all .7s ease; -moz-transition: all .7s ease;
transition: all .7s ease; transition: all .7s ease;
@ -47,19 +35,6 @@
transition: all .5s ease; transition: all .5s ease;
} }
@media (max-width: 700px) {
#offcanvas {
-webkit-transition: all .7s ease;
-moz-transition: all .7s ease;
transition: all .7s ease;
}
#main-canvas-wrapper.js-tray-open #offcanvas {
-webkit-transition: all .7s ease;
-moz-transition: all .7s ease;
transition: all .7s ease;
}
}
/* Transition the administration tray. /* Transition the administration tray.
#toolbar-administration, #toolbar-administration,
#toolbar-administration * { #toolbar-administration * {

View file

@ -3,7 +3,7 @@
* Visual styling for tables in the Settings Tray module's off canvas tray. * Visual styling for tables in the Settings Tray module's off canvas tray.
*/ */
.ui-dialog-offcanvas table { .ui-dialog-outside-in table {
border: 0; border: 0;
border-collapse: collapse; border-collapse: collapse;
min-width: 300px; min-width: 300px;
@ -13,7 +13,7 @@
margin-left: -20px; margin-left: -20px;
margin-bottom: -10px; margin-bottom: -10px;
} }
.ui-dialog-offcanvas tr th { .ui-dialog-outside-in tr th {
padding: 2px 4px; padding: 2px 4px;
background-color: transparent; background-color: transparent;
border: 0; border: 0;
@ -22,15 +22,14 @@
color: #bbb; color: #bbb;
text-align: left; /* LTR */ text-align: left; /* LTR */
} }
[dir="rtl"] .ui-dialog-offcanvas tr th { [dir="rtl"] .ui-dialog-outside-in tr th {
text-align: right; text-align: right;
} }
.ui-dialog-offcanvas tr, .ui-dialog-outside-in tr,
.ui-dialog-offcanvas tr td { .ui-dialog-outside-in tr td {
padding: 2px 4px; padding: 2px 4px;
height: 35px; height: 35px;
vertical-align: middle; vertical-align: middle;
font-size: 13px;
text-align: left; /* LTR */ text-align: left; /* LTR */
border: 0px; border: 0px;
border-style: solid; border-style: solid;
@ -40,29 +39,28 @@
background-color: transparent; background-color: transparent;
font-size: 12px; font-size: 12px;
} }
[dir="rtl"] .ui-dialog-offcanvas tr th, [dir="rtl"] .ui-dialog-outside-in tr th,
[dir="rtl"] .ui-dialog-offcanvas tr td { [dir="rtl"] .ui-dialog-outside-in tr td {
text-align: right; text-align: right;
} }
.ui-dialog-offcanvas td a { .ui-dialog-outside-in td a {
display: block; display: block;
max-width: 120px; max-width: 120px;
overflow: hidden; overflow: hidden;
} }
.ui-dialog.ui-dialog-offcanvas tr td:first-child, .ui-dialog.ui-dialog-outside-in tr td:first-child,
.ui-dialog.ui-dialog-offcanvas tr th:first-child { .ui-dialog.ui-dialog-outside-in tr th:first-child {
min-width: 120px;
padding-left: 20px; /* LTR */ padding-left: 20px; /* LTR */
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
} }
[dir="rtl"] .ui-dialog.ui-dialog-offcanvas tr td:first-child, [dir="rtl"] .ui-dialog.ui-dialog-outside-in tr td:first-child,
[dir="rtl"] .ui-dialog.ui-dialog-offcanvas tr th:first-child { [dir="rtl"] .ui-dialog.ui-dialog-outside-in tr th:first-child {
padding-right: 20px; padding-right: 20px;
} }
.ui-dialog-offcanvas tr.odd, .ui-dialog-outside-in tr.odd,
.ui-dialog-offcanvas tr.even { .ui-dialog-outside-in tr.even {
background-image: none; background-image: none;
background-color: transparent; background-color: transparent;
} }

View file

@ -8,40 +8,40 @@
/* Because base font sizes will vary widely across themes, to maintain consistency outside-in uses only pixels. */ /* Because base font sizes will vary widely across themes, to maintain consistency outside-in uses only pixels. */
.ui-dialog-offcanvas body.drag { .ui-dialog-outside-in body.drag {
cursor: move; cursor: move;
} }
.ui-dialog-offcanvas tr.region-title { .ui-dialog-outside-in tr.region-title {
font-weight: normal; font-weight: normal;
} }
.ui-dialog-offcanvas tr.region-message { .ui-dialog-outside-in tr.region-message {
color: #fff; color: #fff;
} }
.ui-dialog-offcanvas tr.region-populated { .ui-dialog-outside-in tr.region-populated {
display: none; display: none;
} }
.ui-dialog-offcanvas tr.add-new .tabledrag-changed { .ui-dialog-outside-in tr.add-new .tabledrag-changed {
display: none; display: none;
} }
.ui-dialog-offcanvas .draggable a.tabledrag-handle { .ui-dialog-outside-in .draggable a.tabledrag-handle {
background-image: none; background-image: none;
margin: 0; margin: 0;
margin-left: 0; /* LTR */ margin-left: 0; /* LTR */
margin-right: 5px; /* LTR */ margin-right: 5px; /* LTR */
height: auto; height: auto;
min-width: 20px; min-width: 20px;
padding: 0px; padding: 0;
overflow: hidden; overflow: hidden;
float: left; /* LTR */ float: left; /* LTR */
text-decoration: none; text-decoration: none;
cursor: move; cursor: move;
} }
[dir="rtl"] .ui-dialog-offcanvas .draggable a.tabledrag-handle { [dir="rtl"] .ui-dialog-outside-in .draggable a.tabledrag-handle {
float: right; float: right;
margin-right: 0; margin-right: 0;
margin-left: 5px; margin-left: 5px;
} }
.ui-dialog-offcanvas a.tabledrag-handle .handle { .ui-dialog-outside-in a.tabledrag-handle .handle {
/* Use lighter drag icon against dark background. */ /* Use lighter drag icon against dark background. */
background-image: url(../../../misc/icons/bebebe/move.svg); background-image: url(../../../misc/icons/bebebe/move.svg);
background-repeat: no-repeat; background-repeat: no-repeat;
@ -51,54 +51,54 @@
padding: 0; padding: 0;
width: auto; width: auto;
} }
.ui-dialog-offcanvas .draggable a.tabledrag-handle:hover .handle, .ui-dialog-outside-in .draggable a.tabledrag-handle:hover .handle,
.ui-dialog-offcanvas .draggable a.tabledrag-handle:focus .handle { .ui-dialog-outside-in .draggable a.tabledrag-handle:focus .handle {
background-image: url(../../../misc/icons/787878/move.svg); background-image: url(../../../misc/icons/787878/move.svg);
text-decoration: none; text-decoration: none;
} }
.ui-dialog-offcanvas .touchevents .draggable td { .ui-dialog-outside-in .touchevents .draggable td {
padding: 0 10px; padding: 0 10px;
} }
.ui-dialog-offcanvas .touchevents .draggable .menu-item__link { .ui-dialog-outside-in .touchevents .draggable .menu-item__link {
display: inline-block; display: inline-block;
padding: 10px 0; padding: 10px 0;
} }
.ui-dialog-offcanvas .touchevents a.tabledrag-handle { .ui-dialog-outside-in .touchevents a.tabledrag-handle {
height: 44px; height: 44px;
width: 40px; width: 40px;
} }
.ui-dialog-offcanvas .touchevents a.tabledrag-handle .handle { .ui-dialog-outside-in .touchevents a.tabledrag-handle .handle {
background-position: 40% 19px; /* LTR */ background-position: 40% 19px; /* LTR */
height: 21px; height: 21px;
} }
[dir="rtl"] .ui-dialog-offcanvas .touch a.tabledrag-handle .handle { [dir="rtl"] .ui-dialog-outside-in .touch a.tabledrag-handle .handle {
background-position: right 40% top 19px; background-position: right 40% top 19px;
} }
.ui-dialog-offcanvas .touchevents .draggable.drag a.tabledrag-handle .handle { .ui-dialog-outside-in .touchevents .draggable.drag a.tabledrag-handle .handle {
background-position: 50% -32px; background-position: 50% -32px;
} }
.ui-dialog-offcanvas .tabledrag-toggle-weight-wrapper { .ui-dialog-outside-in .tabledrag-toggle-weight-wrapper {
text-align: right; /* LTR */ text-align: right; /* LTR */
} }
[dir="rtl"] .ui-dialog-offcanvas .tabledrag-toggle-weight-wrapper { [dir="rtl"] .ui-dialog-outside-in .tabledrag-toggle-weight-wrapper {
text-align: left; text-align: left;
} }
.ui-dialog-offcanvas .indentation { .ui-dialog-outside-in .indentation {
float: left; /* LTR */ float: left; /* LTR */
height: auto; height: auto;
margin: 0 3px 0 -10px; /* LTR */ margin: 0 3px 0 -10px; /* LTR */
padding: 0 0 0 10px; /* LTR */ padding: 0 0 0 10px; /* LTR */
width: auto; width: auto;
} }
[dir="rtl"] .ui-dialog-offcanvas .indentation { [dir="rtl"] .ui-dialog-outside-in .indentation {
float: right; float: right;
margin: 0 -10px 0 3px; margin: 0 -10px 0 3px;
padding: 0 10px 0 0; padding: 0 10px 0 0;
} }
.ui-dialog-offcanvas tr.drag { .ui-dialog-outside-in tr.drag {
background-color: #555; background-color: #555;
} }
.ui-dialog-offcanvas tr.drag-previous { .ui-dialog-outside-in tr.drag-previous {
background-color: #000; background-color: #000;
} }

View file

@ -60,19 +60,19 @@
} }
/* Style the editables while in edit mode. */ /* Style the editables while in edit mode. */
#main-canvas.js-outside-in-edit-mode .outside-in-editable { .dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable {
outline: 1px dashed rgba(0,0,0,0.5); outline: 1px dashed rgba(0,0,0,0.5);
box-shadow: 0 0 0 1px rgba(255,255,255,0.7); box-shadow: 0 0 0 1px rgba(255,255,255,0.7);
} }
#main-canvas.js-outside-in-edit-mode .outside-in-editable:hover, .dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable:hover,
#main-canvas.js-outside-in-edit-mode .outside-in-editable.outside-in-active-editable { .dialog-offcanvas__main-canvas.js-outside-in-edit-mode .outside-in-editable.outside-in-active-editable {
background-color: rgba(0,0,0,0.2); background-color: rgba(0,0,0,0.2);
} }
/* Style the offcanvas container. */ /* Style the dialog-offcanvas container. */
.ui-dialog-offcanvas { .ui-dialog-outside-in {
background: #444; background: #444;
border: 0px solid transparent; border: 0 solid transparent;
border-radius: 0; border-radius: 0;
box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.3333); box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.3333);
padding: 0; padding: 0;
@ -82,20 +82,20 @@
} }
/* Style content in the tray. */ /* Style content in the tray. */
.ui-dialog-offcanvas p, .ui-dialog-outside-in p,
.ui-dialog-offcanvas h1, .ui-dialog-outside-in h1,
.ui-dialog-offcanvas h2, .ui-dialog-outside-in h2,
.ui-dialog-offcanvas h3, .ui-dialog-outside-in h3,
.ui-dialog-offcanvas h4, .ui-dialog-outside-in h4,
.ui-dialog-offcanvas h5, .ui-dialog-outside-in h5,
.ui-dialog-offcanvas h6, .ui-dialog-outside-in h6,
.ui-dialog-offcanvas pre, .ui-dialog-outside-in pre,
.ui-dialog-offcanvas legend, .ui-dialog-outside-in legend,
.ui-dialog-offcanvas cite, .ui-dialog-outside-in cite,
.ui-dialog-offcanvas span, .ui-dialog-outside-in span,
.ui-dialog-offcanvas summary, .ui-dialog-outside-in summary,
.ui-dialog-offcanvas details, .ui-dialog-outside-in details,
.ui-dialog-offcanvas .form-item { .ui-dialog-outside-in .form-item {
color: #ddd; color: #ddd;
font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif; font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif;
font-size: 14px; font-size: 14px;
@ -103,8 +103,8 @@
background-color: transparent; background-color: transparent;
text-shadow: none; text-shadow: none;
} }
.ui-dialog-offcanvas a, .ui-dialog-outside-in a,
.ui-dialog-offcanvas .link { .ui-dialog-outside-in .link {
border-bottom: none; border-bottom: none;
font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif; font-family: "Lucida Grande", 'Lucida Sans Unicode','liberation sans', sans-serif;
font-size: 14px; font-size: 14px;
@ -113,16 +113,16 @@
text-decoration: none; text-decoration: none;
transition: color .5s ease; transition: color .5s ease;
} }
.ui-dialog-offcanvas a:focus, .ui-dialog-outside-in a:focus,
.ui-dialog-offcanvas .link:focus, .ui-dialog-outside-in .link:focus,
.ui-dialog-offcanvas a:hover, .ui-dialog-outside-in a:hover,
.ui-dialog-offcanvas .link:hover { .ui-dialog-outside-in .link:hover {
outline: none; outline: none;
color: #46a0f5; color: #46a0f5;
} }
/* Style the tray header. */ /* Style the tray header. */
.ui-dialog-offcanvas .ui-dialog-titlebar { .ui-dialog-outside-in .ui-dialog-titlebar {
padding: 20px; padding: 20px;
background: #2d2d2d; background: #2d2d2d;
border: 0; border: 0;
@ -131,11 +131,10 @@
font-weight: normal; font-weight: normal;
color: #fff; color: #fff;
} }
.ui-dialog-offcanvas .ui-dialog-titlebar-close { .ui-dialog-outside-in .ui-dialog-titlebar-close {
background-image: url(../../../misc/icons/bebebe/ex.svg); background-image: url(../../../misc/icons/bebebe/ex.svg);
background-position-x: center; background-position: center center;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position-y: center;
background-color: transparent; background-color: transparent;
border: 0; border: 0;
position: absolute; position: absolute;
@ -143,14 +142,14 @@
-moz-transition: all .5s ease; -moz-transition: all .5s ease;
transition: background .5s ease; transition: background .5s ease;
} }
.ui-dialog-offcanvas .ui-dialog-titlebar-close:hover { .ui-dialog-outside-in .ui-dialog-titlebar-close:hover {
background-image: url(../../../misc/icons/ffffff/ex.svg); background-image: url(../../../misc/icons/ffffff/ex.svg);
} }
[dir="rtl"] .ui-dialog-offcanvas .ui-dialog-titlebar-close { [dir="rtl"] .ui-dialog-outside-in .ui-dialog-titlebar-close {
left: 20px; left: 20px;
right: auto; right: auto;
} }
.ui-dialog-offcanvas .ui-dialog-title { .ui-dialog-outside-in .ui-dialog-title {
font-size: 16px; font-size: 16px;
margin: 0; margin: 0;
/* Push the text away from the icon. */ /* Push the text away from the icon. */
@ -160,12 +159,12 @@
max-width: 210px; max-width: 210px;
text-align: left; /* LTR */ text-align: left; /* LTR */
} }
[dir="rtl"] .ui-dialog-offcanvas .ui-dialog-title { [dir="rtl"] .ui-dialog-outside-in .ui-dialog-title {
text-align: right; text-align: right;
padding-left: 0px; padding-left: 0px;
padding-right: 0px; padding-right: 0px;
} }
.ui-dialog-offcanvas .ui-dialog-title:before { .ui-dialog-outside-in .ui-dialog-title:before {
background: transparent url(../../../misc/icons/ffffff/pencil.svg) no-repeat scroll center center; background: transparent url(../../../misc/icons/ffffff/pencil.svg) no-repeat scroll center center;
background-size: 100% auto; background-size: 100% auto;
content: ''; content: '';
@ -176,7 +175,7 @@
top: 0; top: 0;
width: 20px; width: 20px;
} }
[dir="rtl"] .ui-dialog-offcanvas .ui-dialog-title:before { [dir="rtl"] .ui-dialog-outside-in .ui-dialog-title:before {
left: auto; left: auto;
right: 20px; right: 20px;
} }
@ -191,7 +190,7 @@
color: #333; color: #333;
} }
/* Hide the defauld Jquery UI dialog close button. */ /* Hide the defauld Jquery UI dialog close button. */
.ui-dialog-offcanvas .ui-icon-closethick { .ui-dialog-outside-in .ui-icon-closethick {
visibility: hidden; visibility: hidden;
} }
@ -199,18 +198,18 @@
/** /**
* Visual styling for buttons in the Settings Tray module's off canvas tray. * Visual styling for buttons in the Settings Tray module's off canvas tray.
* @todo Move to it's own component: * @todo Move to its own component:
* https://www.drupal.org/node/1945262. * https://www.drupal.org/node/1945262.
*/ */
.ui-dialog-offcanvas button.link { .ui-dialog-outside-in button.link {
background: transparent; background: transparent;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.ui-dialog-offcanvas .button { .ui-dialog-outside-in .button {
width: 100%; width: 100%;
height: auto; height: auto;
margin: 1em auto; margin: 1em auto;
@ -221,39 +220,39 @@
color: #fff; color: #fff;
transition: all .5s ease; transition: all .5s ease;
} }
.ui-dialog-offcanvas .button:hover, .ui-dialog-outside-in .button:hover,
.ui-dialog-offcanvas .button:focus { .ui-dialog-outside-in .button:focus {
background: #888; background: #888;
} }
.ui-dialog-offcanvas .button--primary { .ui-dialog-outside-in .button--primary {
background: #277abd none; background: #277abd none;
border: none; border: none;
color: #fff; color: #fff;
transition: all .5s ease; transition: all .5s ease;
} }
.ui-dialog-offcanvas .button--primary:hover, .ui-dialog-outside-in .button--primary:hover,
.ui-dialog-offcanvas .button--primary:focus { .ui-dialog-outside-in .button--primary:focus {
background: #2b8bd8; background: #2b8bd8;
} }
/* /*
* Visual styling for dropbutton in the Settings Tray module's off canvas tray. * Visual styling for dropbutton in the Settings Tray module's off canvas tray.
* @todo Move to it's own component: * @todo Move to its own component:
* https://www.drupal.org/node/1945262. * https://www.drupal.org/node/1945262.
*/ */
.ui-dialog-offcanvas .dropbutton-widget { .ui-dialog-outside-in .dropbutton-widget {
background: #7b7b7b none; background: #7b7b7b none;
border: 0; border: 0;
border-radius: 1em; border-radius: 1em;
color: #eee; color: #eee;
transition: background .5s ease; transition: background .5s ease;
} }
.ui-dialog-offcanvas .dropbutton-widget:hover { .ui-dialog-outside-in .dropbutton-widget:hover {
box-shadow: 0 2px 2px 1px rgba(0,0,0,0.5); box-shadow: 0 2px 2px 1px rgba(0,0,0,0.5);
} }
.ui-dialog-offcanvas .dropbutton-toggle button { .ui-dialog-outside-in .dropbutton-toggle button {
background: #7b7b7b none; background: #7b7b7b none;
border-bottom-right-radius: 1em; /* LTR */ border-bottom-right-radius: 1em; /* LTR */
border-top-right-radius: 1em; /* LTR */ border-top-right-radius: 1em; /* LTR */
@ -262,37 +261,37 @@
border-left-width: 1px; /* LTR */ border-left-width: 1px; /* LTR */
transition: background .5s ease; transition: background .5s ease;
} }
[dir="rtl"] .ui-dialog-offcanvas .dropbutton-toggle button { [dir="rtl"] .ui-dialog-outside-in .dropbutton-toggle button {
border-radius: 0; border-radius: 0;
border-bottom-left-radius: 1em; border-bottom-left-radius: 1em;
border-top-left-radius: 1em; border-top-left-radius: 1em;
border-width: 0; border-width: 0;
border-right-width: 1px; border-right-width: 1px;
} }
.ui-dialog-offcanvas .dropbutton .dropbutton-action:hover, .ui-dialog-outside-in .dropbutton .dropbutton-action:hover,
.ui-dialog-offcanvas .dropbutton a:hover { .ui-dialog-outside-in .dropbutton a:hover {
background: #6b6b6b none; background: #6b6b6b none;
border-bottom-left-radius: 1em; /* LTR */ border-bottom-left-radius: 1em; /* LTR */
border-top-left-radius: 1em; /* LTR */ border-top-left-radius: 1em; /* LTR */
} }
[dir="rtl"] .ui-dialog-offcanvas .dropbutton .dropbutton-action:hover, [dir="rtl"] .ui-dialog-outside-in .dropbutton .dropbutton-action:hover,
[dir="rtl"] .ui-dialog-offcanvas .dropbutton a:hover { [dir="rtl"] .ui-dialog-outside-in .dropbutton a:hover {
border-radius: 0; border-radius: 0;
border-bottom-right-radius: 1em; border-bottom-right-radius: 1em;
border-top-right-radius: 1em; border-top-right-radius: 1em;
} }
.ui-dialog-offcanvas .dropbutton a { .ui-dialog-outside-in .dropbutton a {
padding: 0.1em 0.8em; padding: 0.1em 0.8em;
color: #eee; color: #eee;
font-size: 90%; font-size: 90%;
line-height: 1.8; line-height: 1.8;
transition: all .5s ease; transition: all .5s ease;
} }
.ui-dialog-offcanvas .dropbutton:hover a { .ui-dialog-outside-in .dropbutton:hover a {
color: #fff; color: #fff;
} }
/* Make an arrow out of borders with some fancy CSS. */ /* Make an arrow out of borders with some fancy CSS. */
.ui-dialog-offcanvas span.dropbutton-arrow { .ui-dialog-outside-in span.dropbutton-arrow {
border-bottom-color: transparent; border-bottom-color: transparent;
border-left-color: transparent; border-left-color: transparent;
border-right-color: transparent; border-right-color: transparent;
@ -309,21 +308,19 @@
overflow: hidden; overflow: hidden;
color: #fff; color: #fff;
} }
.js .dropbutton-toggle .dropbutton-arrow:hover { .js .ui-dialog-outside-in .dropbutton-toggle .dropbutton-arrow:hover {
background: transparent; background: transparent;
} }
.ui-dialog-offcanvas td .dropbutton-multiple { .ui-dialog-outside-in td .dropbutton-multiple {
padding-right: 0; padding-right: 0;
} }
[dir="rtl"].ui-dialog-offcanvas td .dropbutton-multiple { [dir="rtl"].ui-dialog-outside-in td .dropbutton-multiple {
padding-left: 0; padding-left: 0;
} }
.ui-dialog-offcanvas td .dropbutton-multiple .dropbutton { .ui-dialog-outside-in td .dropbutton-multiple .dropbutton {
border-right: 0; border-right: 0;
border-left: 0; border-left: 0;
} }
.ui-dialog-offcanvas td .dropbutton .secondary-action { .ui-dialog-outside-in td .dropbutton .secondary-action {
border-top-color: #000; border-top-color: #000;
} }

View file

@ -11,6 +11,10 @@
'use strict'; '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. * The edge of the screen that the dialog should appear on.
* *
@ -18,7 +22,7 @@
*/ */
var edge = document.documentElement.dir === 'rtl' ? 'left' : 'right'; var edge = document.documentElement.dir === 'rtl' ? 'left' : 'right';
var $mainCanvasWrapper = $('#main-canvas-wrapper'); var $mainCanvasWrapper = $('[data-offcanvas-main-canvas]');
/** /**
* Resets the size of the dialog. * Resets the size of the dialog.
@ -47,7 +51,7 @@
$element $element
.dialog('option', adjustedOptions) .dialog('option', adjustedOptions)
.trigger('dialogContentResize.outsidein'); .trigger('dialogContentResize.offcanvas');
} }
/** /**
@ -81,6 +85,9 @@
* The event triggered. * The event triggered.
*/ */
function bodyPadding(event) { function bodyPadding(event) {
if ($('body').outerWidth() < minDisplaceWidth) {
return;
}
var $element = event.data.$element; var $element = event.data.$element;
var $widget = $element.dialog('widget'); var $widget = $element.dialog('widget');
@ -100,26 +107,28 @@
$('.ui-dialog-offcanvas, .ui-dialog-offcanvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title); $('.ui-dialog-offcanvas, .ui-dialog-offcanvas .ui-dialog-titlebar').toggleClass('ui-dialog-empty-title', !settings.title);
$element $element
.on('dialogresize.outsidein', eventData, debounce(bodyPadding, 100)) .on('dialogresize.offcanvas', eventData, debounce(bodyPadding, 100))
.on('dialogContentResize.outsidein', eventData, handleDialogResize) .on('dialogContentResize.offcanvas', eventData, handleDialogResize)
.trigger('dialogresize.outsidein'); .on('dialogContentResize.offcanvas', eventData, debounce(bodyPadding, 100))
.trigger('dialogresize.offcanvas');
$element.dialog('widget').attr('data-offset-' + edge, ''); $element.dialog('widget').attr('data-offset-' + edge, '');
$(window) $(window)
.on('resize.outsidein scroll.outsidein', eventData, debounce(resetSize, 100)) .on('resize.offcanvas scroll.offcanvas', eventData, debounce(resetSize, 100))
.trigger('resize.outsidein'); .trigger('resize.offcanvas');
} }
}, },
'dialog:beforecreate': function (event, dialog, $element, settings) { 'dialog:beforecreate': function (event, dialog, $element, settings) {
if ($element.is('#drupal-offcanvas')) { if ($element.is('#drupal-offcanvas')) {
$('body').addClass('js-tray-open');
// @see http://api.jqueryui.com/position/ // @see http://api.jqueryui.com/position/
settings.position = { settings.position = {
my: 'left top', my: 'left top',
at: edge + ' top', at: edge + ' top',
of: window of: window
}; };
settings.dialogClass = 'ui-dialog-offcanvas'; settings.dialogClass += ' ui-dialog-offcanvas';
// Applies initial height to dialog based on window height. // Applies initial height to dialog based on window height.
// See http://api.jqueryui.com/dialog for all dialog options. // See http://api.jqueryui.com/dialog for all dialog options.
settings.height = $(window).height(); settings.height = $(window).height();
@ -127,8 +136,9 @@
}, },
'dialog:beforeclose': function (event, dialog, $element) { 'dialog:beforeclose': function (event, dialog, $element) {
if ($element.is('#drupal-offcanvas')) { if ($element.is('#drupal-offcanvas')) {
$(document).off('.outsidein'); $('body').removeClass('js-tray-open');
$(window).off('.outsidein'); $(document).off('.offcanvas');
$(window).off('.offcanvas');
$mainCanvasWrapper.css('padding-' + edge, 0); $mainCanvasWrapper.css('padding-' + edge, 0);
} }
} }

View file

@ -9,8 +9,9 @@
var blockConfigureSelector = '[data-outside-in-edit]'; var blockConfigureSelector = '[data-outside-in-edit]';
var toggleEditSelector = '[data-drupal-outsidein="toggle"]'; var toggleEditSelector = '[data-drupal-outsidein="toggle"]';
var itemsToToggleSelector = '#main-canvas, #toolbar-bar, [data-drupal-outsidein="editable"] a, [data-drupal-outsidein="editable"] button'; 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 contextualItemsSelector = '[data-contextual-id] a, [data-contextual-id] button';
var quickEditItemSelector = '[data-quickedit-entity-id]';
/** /**
* Reacts to contextual links being added. * Reacts to contextual links being added.
@ -36,9 +37,20 @@
if (!isInEditMode()) { if (!isInEditMode()) {
$(toggleEditSelector).trigger('click.outsidein'); $(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. * Gets all items that should be toggled with class during edit mode.
* *
@ -88,11 +100,21 @@
* Close any active toolbar tray before entering edit mode. * Close any active toolbar tray before entering edit mode.
*/ */
function closeToolbarTrays() { function closeToolbarTrays() {
$('#toolbar-bar') $(Drupal.toolbar.models.toolbarModel.get('activeTab')).trigger('click');
.find('.toolbar-tab') }
.not('.contextual-toolbar-tab')
.has('.toolbar-tray.is-active') /**
.find('.toolbar-item').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');
} }
/** /**
@ -113,7 +135,7 @@
$editables = $('[data-drupal-outsidein="editable"]').once('outsidein'); $editables = $('[data-drupal-outsidein="editable"]').once('outsidein');
if ($editables.length) { if ($editables.length) {
// Use event capture to prevent clicks on links. // Use event capture to prevent clicks on links.
document.querySelector('#main-canvas').addEventListener('click', preventClick, true); document.querySelector('[data-offcanvas-main-canvas]').addEventListener('click', preventClick, true);
// When a click occurs try and find the outside-in edit link // When a click occurs try and find the outside-in edit link
// and click it. // and click it.
@ -124,8 +146,21 @@
if ($(e.target).closest('.contextual').length || !localStorage.getItem('Drupal.contextualToolbar.isViewing')) { if ($(e.target).closest('.contextual').length || !localStorage.getItem('Drupal.contextualToolbar.isViewing')) {
return; return;
} }
$(e.currentTarget).find(blockConfigureSelector).trigger('click'); $(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');
}); });
} }
} }
@ -133,13 +168,14 @@
else { else {
$editables = $('[data-drupal-outsidein="editable"]').removeOnce('outsidein'); $editables = $('[data-drupal-outsidein="editable"]').removeOnce('outsidein');
if ($editables.length) { if ($editables.length) {
document.querySelector('#main-canvas').removeEventListener('click', preventClick, true); document.querySelector('[data-offcanvas-main-canvas]').removeEventListener('click', preventClick, true);
$editables.off('.outsidein'); $editables.off('.outsidein');
$(quickEditItemSelector).off('.outsidein');
} }
$editButton.text(Drupal.t('Edit')); $editButton.text(Drupal.t('Edit'));
// Close/remove offcanvas. closeOffCanvas();
$('.ui-dialog-offcanvas .ui-dialog-titlebar-close').trigger('click'); disableQuickEdit();
} }
getItemsToToggle().toggleClass('js-outside-in-edit-mode', editMode); getItemsToToggle().toggleClass('js-outside-in-edit-mode', editMode);
$('.edit-mode-inactive').toggleClass('visually-hidden', editMode); $('.edit-mode-inactive').toggleClass('visually-hidden', editMode);
@ -177,7 +213,7 @@
var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog'; var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog';
var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_offcanvas'; var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_offcanvas';
// Loop through all Ajax links and change the format to offcanvas when // Loop through all Ajax links and change the format to dialog-offcanvas when
// needed. // needed.
Drupal.ajax.instances Drupal.ajax.instances
.filter(function (instance) { .filter(function (instance) {
@ -210,8 +246,9 @@
if ($element.is('#drupal-offcanvas')) { if ($element.is('#drupal-offcanvas')) {
$('body .outside-in-active-editable').removeClass('outside-in-active-editable'); $('body .outside-in-active-editable').removeClass('outside-in-active-editable');
var $activeElement = $('#' + settings.outsideInActiveEditableId); var $activeElement = $('#' + settings.outsideInActiveEditableId);
if ($activeElement) { if ($activeElement.length) {
$activeElement.addClass('outside-in-active-editable'); $activeElement.addClass('outside-in-active-editable');
settings.dialogClass += ' ui-dialog-outside-in';
} }
} }
}, },

View file

@ -12,9 +12,7 @@
*/ */
#} #}
{% if children %} {% if children %}
<div id="main-canvas-wrapper"> <div class="dialog-offcanvas__main-canvas" data-offcanvas-main-canvas >
<div id="main-canvas"> {{ children }}
{{ children }}
</div>
</div> </div>
{% endif %} {% endif %}

View file

@ -0,0 +1,4 @@
#main-canvas.js-outside-in-edit-mode a,
#main-canvas.js-outside-in-edit-mode input {
pointer-events: inherit !important;
}

View file

@ -0,0 +1,8 @@
name: 'CSS Test fix'
type: module
description: 'Provides CSS fixes for tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- outside_in

View file

@ -0,0 +1,5 @@
drupal.css_fix:
version: VERSION
css:
theme:
css/css_fix.theme.css: {}

View file

@ -0,0 +1,16 @@
<?php
/**
* @file
* Module for attaching CSS during tests.
*
* CSS pointer-events properties cause testing errors.
*/
/**
* Implements hook_page_attachments().
*/
function outside_in_test_css_page_attachments(array &$attachments) {
// Unconditionally attach an asset to the page.
$attachments['#attached']['library'][] = 'outside_in_test_css/drupal.css_fix';
}

View file

@ -69,4 +69,38 @@ class OffCanvasTest extends OutsideInJavascriptTestBase {
} }
} }
/**
* 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.');
}
}
} }

View file

@ -2,6 +2,8 @@
namespace Drupal\Tests\outside_in\FunctionalJavascript; namespace Drupal\Tests\outside_in\FunctionalJavascript;
use Drupal\user\Entity\Role;
/** /**
* Testing opening and saving block forms in the off-canvas tray. * Testing opening and saving block forms in the off-canvas tray.
* *
@ -22,6 +24,9 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase {
'outside_in', 'outside_in',
'quickedit', 'quickedit',
'search', 'search',
// Add test module to override CSS pointer-events properties because they
// cause test failures.
'outside_in_test_css',
]; ];
/** /**
@ -112,8 +117,16 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase {
// suppressed. // suppressed.
$this->openBlockForm($element_selector); $this->openBlockForm($element_selector);
// Exit edit mode. // Exit edit mode using ESC.
$this->toggleEditingMode(); $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');
} }
/** /**
@ -153,13 +166,15 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase {
* Enables Editing mode by pressing "Edit" button in the toolbar. * Enables Editing mode by pressing "Edit" button in the toolbar.
*/ */
protected function toggleEditingMode() { protected function toggleEditingMode() {
$this->waitForElement('div[data-contextual-id="block:block=powered:langcode=en|outside_in::langcode=en"] .contextual-links a'); $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->waitForElement('#toolbar-bar'); $this->assertSession()->assertWaitOnAjaxRequest();
$edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button'); $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button');
$edit_button->press(); $edit_button->press();
// Waiting for Toolbar animation.
$this->assertSession()->assertWaitOnAjaxRequest();
} }
/** /**
@ -187,4 +202,86 @@ class OutsideInBlockFormTest extends OutsideInJavascriptTestBase {
$this->assertOffCanvasBlockFormIsValid(); $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);
}
} }

View file

@ -89,4 +89,46 @@ abstract class OutsideInJavascriptTestBase extends JavascriptTestBase {
$this->assertJsCondition($condition, $timeout); $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');");
}
} }

View file

@ -20,5 +20,17 @@ process:
langcode: langcode:
plugin: d6_url_alias_language plugin: d6_url_alias_language
source: language source: language
node_translation:
-
plugin: explode
source: src
delimiter: /
-
plugin: extract
index:
- 1
-
plugin: migration
migration: d6_node_translation
destination: destination:
plugin: url_alias plugin: url_alias

View file

@ -59,13 +59,21 @@ class UrlAlias extends DestinationBase implements ContainerFactoryPluginInterfac
* {@inheritdoc} * {@inheritdoc}
*/ */
public function import(Row $row, array $old_destination_id_values = array()) { public function import(Row $row, array $old_destination_id_values = array()) {
$source = $row->getDestinationProperty('source');
$alias = $row->getDestinationProperty('alias');
$langcode = $row->getDestinationProperty('langcode');
$pid = $old_destination_id_values ? $old_destination_id_values[0] : NULL;
$path = $this->aliasStorage->save( // Check if this alias is for a node and if that node is a translation.
$row->getDestinationProperty('source'), if (preg_match('/^\/node\/\d+$/', $source) && $row->hasDestinationProperty('node_translation')) {
$row->getDestinationProperty('alias'),
$row->getDestinationProperty('langcode'), // Replace the alias source with the translation source path.
$old_destination_id_values ? $old_destination_id_values[0] : NULL $node_translation = $row->getDestinationProperty('node_translation');
); $source = '/node/' . $node_translation[0];
$langcode = $node_translation[1];
}
$path = $this->aliasStorage->save($source, $alias, $langcode, $pid);
return array($path['pid']); return array($path['pid']);
} }

View file

@ -13,7 +13,11 @@ abstract class UrlAliasBase extends DrupalSqlBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function query() { public function query() {
return $this->select('url_alias', 'ua')->fields('ua'); // The order of the migration is significant since
// \Drupal\Core\Path\AliasStorage::lookupPathAlias() orders by pid before
// returning a result. Postgres does not automatically order by primary key
// therefore we need to add a specific order by.
return $this->select('url_alias', 'ua')->fields('ua')->orderBy('pid');
} }
/** /**

View file

@ -16,14 +16,26 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public static $modules = array('path'); public static $modules = ['language', 'content_translation', 'path'];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function setUp() { protected function setUp() {
parent::setUp(); parent::setUp();
$this->executeMigration('d6_url_alias'); $this->installEntitySchema('node');
$this->installConfig(['node']);
$this->installSchema('node', ['node_access']);
$this->migrateUsers(FALSE);
$this->migrateFields();
$this->executeMigrations([
'language',
'd6_node_settings',
'd6_node',
'd6_node_translation',
'd6_url_alias',
]);
} }
/** /**
@ -93,4 +105,33 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
$this->assertPath('3', $conditions, $path); $this->assertPath('3', $conditions, $path);
} }
/**
* Test the URL alias migration with translated nodes.
*/
public function testUrlAliasWithTranslatedNodes() {
$alias_storage = $this->container->get('path.alias_storage');
// Alias for the 'The Real McCoy' node in English.
$path = $alias_storage->load(['alias' => '/the-real-mccoy']);
$this->assertSame('/node/10', $path['source']);
$this->assertSame('en', $path['langcode']);
// Alias for the 'The Real McCoy' French translation,
// which should now point to node/10 instead of node/11.
$path = $alias_storage->load(['alias' => '/le-vrai-mccoy']);
$this->assertSame('/node/10', $path['source']);
$this->assertSame('fr', $path['langcode']);
// Alias for the 'Abantu zulu' node in Zulu.
$path = $alias_storage->load(['alias' => '/abantu-zulu']);
$this->assertSame('/node/12', $path['source']);
$this->assertSame('zu', $path['langcode']);
// Alias for the 'Abantu zulu' English translation,
// which should now point to node/12 instead of node/13.
$path = $alias_storage->load(['alias' => '/the-zulu-people']);
$this->assertSame('/node/12', $path['source']);
$this->assertSame('en', $path['langcode']);
}
} }

View file

@ -35,13 +35,13 @@ function responsive_image_help($route_name, RouteMatchInterface $route_match) {
$output .= '<dd>' . 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 <a href=":responsive_image_style">Responsive image styles</a> page, click <em>Add responsive image style</em> 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'))) . '</dd>'; $output .= '<dd>' . 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 <a href=":responsive_image_style">Responsive image styles</a> page, click <em>Add responsive image style</em> 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'))) . '</dd>';
$output .= '<dl>'; $output .= '<dl>';
$output .= '<dt>' . t('Fallback image style') . '</dt>'; $output .= '<dt>' . t('Fallback image style') . '</dt>';
$output .= '<dd>' . 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.)</dd>'); $output .= '<dd>' . 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.') . '</dd>';
$output .= '<dt>' . t('Breakpoint groups: viewport sizing vs art direction') . '</dt>'; $output .= '<dt>' . t('Breakpoint groups: viewport sizing vs art direction') . '</dt>';
$output .= '<dd>' . t('The breakpoint group typically only needs a single breakpoint with an empty media query in order to do <em>viewport sizing.</em> Multiple breakpoints are used for changing the crop or aspect ratio of images at different viewport sizes, which is often referred to as <em>art direction.</em> Once you select a breakpoint group, you can choose which breakpoints to use for the responsive image style. By default, the option <em>do not use this breakpoint</em> is selected for each breakpoint. See the <a href=":breakpoint_help">help page of the Breakpoint module</a> for more information.', array(':breakpoint_help' => \Drupal::url('help.page', array('name' => 'breakpoint')))) . '</dd>'; $output .= '<dd>' . t('The breakpoint group typically only needs a single breakpoint with an empty media query in order to do <em>viewport sizing.</em> Multiple breakpoints are used for changing the crop or aspect ratio of images at different viewport sizes, which is often referred to as <em>art direction.</em> Once you select a breakpoint group, you can choose which breakpoints to use for the responsive image style. By default, the option <em>do not use this breakpoint</em> is selected for each breakpoint. See the <a href=":breakpoint_help">help page of the Breakpoint module</a> for more information.', array(':breakpoint_help' => \Drupal::url('help.page', array('name' => 'breakpoint')))) . '</dd>';
$output .= '<dt>' . t('Breakpoint settings: sizes vs image styles') . '</dt>'; $output .= '<dt>' . t('Breakpoint settings: sizes vs image styles') . '</dt>';
$output .= '<dd>' . 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.</dd>'); $output .= '<dd>' . 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.') . '</dd>';
$output .= '<dt>' . t('Sizes field') . '</dt>'; $output .= '<dt>' . t('Sizes field') . '</dt>';
$output .= '<dd>' . 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 <em>Sizes</em> 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. <em>Media conditions</em> 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 <em>image width</em> 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.</dd>'); $output .= '<dd>' . 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 <em>Sizes</em> 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. <em>Media conditions</em> 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 <em>image width</em> 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.') . '</dd>';
$output .= '<dt>' . t('Image styles for sizes') . '</dt>'; $output .= '<dt>' . t('Image styles for sizes') . '</dt>';
$output .= '<dd>' . 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 <a href=":image_styles">Image styles page</a> that is provided by the <a href=":image_help">Image module</a>.', array(':image_styles' => \Drupal::url('entity.image_style.collection'), ':image_help' => \Drupal::url('help.page', array('name' => 'image')))) . '</dd>'; $output .= '<dd>' . 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 <a href=":image_styles">Image styles page</a> that is provided by the <a href=":image_help">Image module</a>.', array(':image_styles' => \Drupal::url('entity.image_style.collection'), ':image_help' => \Drupal::url('help.page', array('name' => 'image')))) . '</dd>';
$output .= '</dl></dd>'; $output .= '</dl></dd>';

View file

@ -240,7 +240,10 @@ abstract class TestBase {
/** /**
* The temporary file directory for the test environment. * The temporary file directory for the test environment.
* *
* This is set in TestBase::prepareEnvironment(). * This is set in TestBase::prepareEnvironment(). This value has to match the
* temporary directory created in install_base_system() for test installs.
*
* @see install_base_system()
* *
* @var string * @var string
*/ */

View file

@ -0,0 +1,22 @@
<?php
namespace Drupal\simpletest\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Tests the test-specifics customisations done in the installation.
*
* @group simpletest
*/
class WebTestBaseInstallTest extends WebTestBase {
/**
* Tests the Drupal install done in \Drupal\simpletest\WebTestBase::setUp().
*/
public function testInstall() {
$htaccess_filename = $this->getTempFilesDirectory() . '/.htaccess';
$this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
}
}

View file

@ -496,9 +496,15 @@ abstract class WebTestBase extends TestBase {
$directory = DRUPAL_ROOT . '/' . $this->siteDirectory; $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php'); copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
// All file system paths are created by System module during installation. // 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
// WebTestBase::initConfig().
// @see system_requirements() // @see system_requirements()
// @see TestBase::prepareEnvironment() // @see TestBase::prepareEnvironment()
// @see install_base_system()
// @see\Drupal\simpletest\WebTestBase::initConfig()
$settings['settings']['file_public_path'] = (object) [ $settings['settings']['file_public_path'] = (object) [
'value' => $this->publicFilesDirectory, 'value' => $this->publicFilesDirectory,
'required' => TRUE, 'required' => TRUE,
@ -587,15 +593,8 @@ abstract class WebTestBase extends TestBase {
protected function initConfig(ContainerInterface $container) { protected function initConfig(ContainerInterface $container) {
$config = $container->get('config.factory'); $config = $container->get('config.factory');
// Manually create and configure private and temporary files directories. // Manually create the private directory.
// While these could be preset/enforced in settings.php like the public
// files directory above, some tests expect them to be configurable in the
// UI. If declared in settings.php, they would no longer be configurable.
file_prepare_directory($this->privateFilesDirectory, FILE_CREATE_DIRECTORY); file_prepare_directory($this->privateFilesDirectory, FILE_CREATE_DIRECTORY);
file_prepare_directory($this->tempFilesDirectory, FILE_CREATE_DIRECTORY);
$config->getEditable('system.file')
->set('path.temporary', $this->tempFilesDirectory)
->save();
// Manually configure the test mail collector implementation to prevent // Manually configure the test mail collector implementation to prevent
// tests from sending out emails and collect them in state instead. // tests from sending out emails and collect them in state instead.

View file

@ -167,7 +167,7 @@ class ModulesUninstallForm extends FormBase {
public function validateForm(array &$form, FormStateInterface $form_state) { public function validateForm(array &$form, FormStateInterface $form_state) {
// Form submitted, but no modules selected. // Form submitted, but no modules selected.
if (!array_filter($form_state->getValue('uninstall'))) { if (!array_filter($form_state->getValue('uninstall'))) {
$form_state->setErrorByName('uninstall', $this->t('No modules selected.')); $form_state->setErrorByName('', $this->t('No modules selected.'));
$form_state->setRedirect('system.modules_uninstall'); $form_state->setRedirect('system.modules_uninstall');
} }
} }

View file

@ -121,6 +121,11 @@ class UninstallTest extends WebTestBase {
$this->drupalGet('admin/modules/uninstall/confirm'); $this->drupalGet('admin/modules/uninstall/confirm');
$this->assertUrl('admin/modules/uninstall'); $this->assertUrl('admin/modules/uninstall');
$this->assertTitle(t('Uninstall') . ' | Drupal'); $this->assertTitle(t('Uninstall') . ' | Drupal');
// Make sure the correct error is shown when no modules are selected.
$edit = array();
$this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall'));
$this->assertText(t('No modules selected.'), 'No module is selected to uninstall');
} }
/** /**

View file

@ -113,7 +113,12 @@ class UncaughtExceptionTest extends WebTestBase {
* Tests a missing dependency on a service. * Tests a missing dependency on a service.
*/ */
public function testMissingDependency() { public function testMissingDependency() {
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\error_service_test\LonelyMonkeyClass::__construct() must be an instance of Drupal\Core\Database\Connection, non'; if (version_compare(PHP_VERSION, '7.1') < 0) {
$this->expectedExceptionMessage = 'Argument 1 passed to Drupal\error_service_test\LonelyMonkeyClass::__construct() must be an instance of Drupal\Core\Database\Connection, non';
}
else {
$this->expectedExceptionMessage = 'Too few arguments to function Drupal\error_service_test\LonelyMonkeyClass::__construct(), 0 passed';
}
$this->drupalGet('broken-service-class'); $this->drupalGet('broken-service-class');
$this->assertResponse(500); $this->assertResponse(500);

View file

@ -209,7 +209,7 @@ class TwigTransTest extends WebTestBase {
$this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.'); $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
// Import the custom .po contents for the language. // Import the custom .po contents for the language.
$filename = tempnam('temporary://', "po_") . '.po'; $filename = \Drupal::service('file_system')->tempnam('temporary://', "po_") . '.po';
file_put_contents($filename, $contents); file_put_contents($filename, $contents);
$options = array( $options = array(
'files[file]' => $filename, 'files[file]' => $filename,

View file

@ -837,7 +837,9 @@ function system_preprocess_block(&$variables) {
} }
$variables['site_slogan'] = ''; $variables['site_slogan'] = '';
if ($variables['content']['site_slogan']['#access'] && $variables['content']['site_slogan']['#markup']) { if ($variables['content']['site_slogan']['#access'] && $variables['content']['site_slogan']['#markup']) {
$variables['site_slogan']['#markup'] = $variables['content']['site_slogan']['#markup']; $variables['site_slogan'] = [
'#markup' => $variables['content']['site_slogan']['#markup'],
];
} }
break; break;

View file

@ -0,0 +1,7 @@
core.entity_view_display.*.*.*.third_party.entity_test_third_party:
type: mapping
label: 'Schema for entity_test module additions to entity_view_display entity'
mapping:
key:
type: string
label: 'Label for key'

View file

@ -0,0 +1,8 @@
name: 'Entity test third-party settings module'
type: module
description: 'Provides third-party settings for test entity types.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- entity_test

View file

@ -0,0 +1,22 @@
/**
* @file
* Testing behavior for JSWebAssertTest.
*/
(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) {
$('input[name="test_assert_wait_on_ajax_input"]').val('js_webassert_test');
}
};
})(jQuery, Drupal, drupalSettings);

View file

@ -0,0 +1,22 @@
/**
* @file
* Testing behavior for JSWebAssertTest.
*/
(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) {
$('#js_webassert_test_element_invisible').show();
}
};
})(jQuery, Drupal, drupalSettings);

View file

@ -0,0 +1,6 @@
name: 'JS WebAssert test module'
type: module
description: 'Module for the JSWebAssert test.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,14 @@
wait_for_ajax_request:
version: VERSION
js:
js/js_webassert_test.wait_for_ajax_request.js: {}
dependencies:
- core/jquery
- core/drupal
wait_for_element:
version: VERSION
js:
js/js_webassert_test.wait_for_element.js: {}
dependencies:
- core/jquery
- core/drupal

View file

@ -0,0 +1,7 @@
js_webassert_test.js_webassert_test_form:
path: '/js_webassert_test_form'
defaults:
_form: 'Drupal\js_webassert_test\Form\JsWebAssertTestForm'
_title: 'JsWebAssertForm'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,207 @@
<?php
namespace Drupal\js_webassert_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Test form for JSWebAssert JavaScriptTestBase.
*/
class JsWebAssertTestForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'js_webassert_test_form';
}
/**
* Form for testing the addition of various types of elements via AJAX.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#prefix'] = '<div id="js_webassert_test_form_wrapper">';
$form['#suffix'] = '</div>';
// Button to test for the waitForButton() assertion.
$form['test_button'] = [
'#type' => 'submit',
'#value' => $this->t('Add button'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addButton',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
// Button to test for the waitForLink() assertion.
$form['test_link'] = [
'#type' => 'submit',
'#value' => $this->t('Add link'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addLink',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
// Button to test for the waitForField() assertion.
$form['test_field'] = [
'#type' => 'submit',
'#value' => $this->t('Add field'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addField',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
// Button to test for the waitForId() assertion.
$form['test_id'] = [
'#type' => 'submit',
'#value' => $this->t('Add ID'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addId',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
// Button to test the assertWaitOnAjaxRequest() assertion.
$form['test_wait_for_element_visible'] = [
'#type' => 'submit',
'#value' => $this->t('Test waitForElementVisible'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addWaitForElementVisible',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
// Button to test the assertWaitOnAjaxRequest() assertion.
$form['test_assert_wait_on_ajax_request'] = [
'#type' => 'submit',
'#value' => $this->t('Test assertWaitOnAjaxRequest'),
'#button_type' => 'primary',
'#ajax' => [
'callback' => 'Drupal\js_webassert_test\Form\JsWebAssertTestForm::addAssertWaitOnAjaxRequest',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
'wrapper' => 'js_webassert_test_form_wrapper',
],
];
return $form;
}
/**
* Ajax callback for the "Add button" button.
*/
public static function addButton(array $form, FormStateInterface $form_state) {
$form['added_button'] = [
'#type' => 'submit',
'#value' => 'Added button',
'#button_type' => 'primary',
];
return $form;
}
/**
* Ajax callback for the "Add link" button.
*/
public static function addLink(array $form, FormStateInterface $form_state) {
$form['added_link'] = [
'#title' => 'Added link',
'#type' => 'link',
'#url' => Url::fromRoute('js_webassert_test.js_webassert_test_form')
];
return $form;
}
/**
* Ajax callback for the "Add field" button.
*/
public static function addField(array $form, FormStateInterface $form_state) {
$form['added_field'] = [
'#type' => 'textfield',
'#title' => 'Added textfield',
'#name' => 'added_field',
];
return $form;
}
/**
* Ajax callback for the "Add ID" button.
*/
public static function addId(array $form, FormStateInterface $form_state) {
$form['added_id'] = [
'#id' => 'js_webassert_test_field_id',
'#type' => 'submit',
'#value' => 'Added ID',
'#button_type' => 'primary',
];
return $form;
}
/**
* Ajax callback for the "Test waitForAjax" button.
*/
public static function addAssertWaitOnAjaxRequest(array $form, FormStateInterface $form_state) {
// Attach the library necessary for this test.
$form['#attached']['library'][] = 'js_webassert_test/wait_for_ajax_request';
$form['test_assert_wait_on_ajax_input'] = [
'#type' => 'textfield',
'#name' => 'test_assert_wait_on_ajax_input',
];
return $form;
}
/**
* Ajax callback for the "Test waitForElementVisible" button.
*/
public static function addWaitForElementVisible(array $form, FormStateInterface $form_state) {
// Attach the library necessary for this test.
$form['#attached']['library'][] = 'js_webassert_test/wait_for_element';
$form['element_invisible'] = [
'#id' => 'js_webassert_test_element_invisible',
'#type' => 'submit',
'#value' => 'Added WaitForElementVisible',
'#button_type' => 'primary',
'#attributes' => [
'style' => ['display: none;'],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}

View file

@ -120,7 +120,7 @@ class TermTest extends TaxonomyTestBase {
// Set limit to 10 terms per page. Set variable to 9 so 10 terms appear. // 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(); $this->config('taxonomy.settings')->set('terms_per_page_admin', '9')->save();
$term1 = $this->createTerm($this->vocabulary); $term1 = $this->createTerm($this->vocabulary);
$terms_array = ''; $terms_array = [];
$taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term'); $taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term');

View file

@ -49,10 +49,6 @@ views.argument_default.user:
type: boolean type: boolean
label: 'Also look for a node and use the node author' label: 'Also look for a node and use the node author'
views.argument_default.current_user:
type: boolean
label: 'User ID from logged in user'
views_field_user: views_field_user:
type: views_field type: views_field
mapping: mapping:
@ -102,3 +98,7 @@ views.filter.user_permissions:
views.filter.user_roles: views.filter.user_roles:
type: views.filter.many_to_one type: views.filter.many_to_one
label: 'Role' label: 'Role'
views.filter_value.user_current:
type: views.filter_value.boolean
label: 'Current user'

Some files were not shown because too many files have changed in this diff Show more