Version Description
- Minimum PHP version is now 5.6.0.
Download this release
Release Info
Developer | Collizo4sky |
Plugin | WP User Avatar |
Version | 3.1.14 |
Comparing to | |
See all releases |
Code changes from version 3.1.13 to 3.1.14
- changelog.txt +4 -1
- languages/wp-user-avatar.pot +4 -4
- readme.txt +8 -37
- vendor/autoload.php +1 -1
- vendor/composer/autoload_real.php +7 -7
- vendor/composer/autoload_static.php +4 -4
- vendor/composer/installed.json +9 -9
- vendor/composer/installed.php +5 -5
- vendor/composer/platform_check.php +2 -2
- vendor/symfony/css-selector/.gitignore +3 -0
- vendor/symfony/css-selector/CHANGELOG.md +0 -5
- vendor/symfony/css-selector/CssSelectorConverter.php +6 -10
- vendor/symfony/css-selector/Exception/ExceptionInterface.php +1 -1
- vendor/symfony/css-selector/Exception/SyntaxErrorException.php +10 -3
- vendor/symfony/css-selector/LICENSE +1 -1
- vendor/symfony/css-selector/Node/AbstractNode.php +4 -1
- vendor/symfony/css-selector/Node/AttributeNode.php +29 -8
- vendor/symfony/css-selector/Node/ClassNode.php +14 -5
- vendor/symfony/css-selector/Node/CombinedSelectorNode.php +18 -6
- vendor/symfony/css-selector/Node/ElementNode.php +15 -5
- vendor/symfony/css-selector/Node/FunctionNode.php +13 -6
- vendor/symfony/css-selector/Node/HashNode.php +14 -5
- vendor/symfony/css-selector/Node/NegationNode.php +10 -4
- vendor/symfony/css-selector/Node/NodeInterface.php +18 -3
- vendor/symfony/css-selector/Node/PseudoNode.php +14 -5
- vendor/symfony/css-selector/Node/SelectorNode.php +14 -5
- vendor/symfony/css-selector/Node/Specificity.php +22 -7
- vendor/symfony/css-selector/Parser/Handler/CommentHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php +4 -1
- vendor/symfony/css-selector/Parser/Handler/HashHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Handler/NumberHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Handler/StringHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php +1 -1
- vendor/symfony/css-selector/Parser/Parser.php +42 -12
- vendor/symfony/css-selector/Parser/ParserInterface.php +3 -1
- vendor/symfony/css-selector/Parser/Reader.php +36 -8
- vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php +1 -1
- vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php +1 -1
- vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php +1 -1
- vendor/symfony/css-selector/Parser/Shortcut/HashParser.php +1 -1
- vendor/symfony/css-selector/Parser/Token.php +57 -19
- vendor/symfony/css-selector/Parser/TokenStream.php +11 -7
- vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php +3 -1
- vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php +18 -3
- vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php +30 -7
- vendor/symfony/css-selector/README.md +5 -5
- vendor/symfony/css-selector/Tests/CssSelectorConverterTest.php +74 -0
- vendor/symfony/css-selector/Tests/Node/AbstractNodeTest.php +34 -0
- vendor/symfony/css-selector/Tests/Node/AttributeNodeTest.php +37 -0
- vendor/symfony/css-selector/Tests/Node/ClassNodeTest.php +33 -0
- vendor/symfony/css-selector/Tests/Node/CombinedSelectorNodeTest.php +35 -0
- vendor/symfony/css-selector/Tests/Node/ElementNodeTest.php +35 -0
- vendor/symfony/css-selector/Tests/Node/FunctionNodeTest.php +47 -0
- vendor/symfony/css-selector/Tests/Node/HashNodeTest.php +33 -0
- vendor/symfony/css-selector/Tests/Node/NegationNodeTest.php +33 -0
- vendor/symfony/css-selector/Tests/Node/PseudoNodeTest.php +32 -0
- vendor/symfony/css-selector/Tests/Node/SelectorNodeTest.php +34 -0
- vendor/symfony/css-selector/Tests/Node/SpecificityTest.php +63 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/AbstractHandlerTest.php +70 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/CommentHandlerTest.php +55 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/HashHandlerTest.php +49 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/IdentifierHandlerTest.php +49 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/NumberHandlerTest.php +50 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/StringHandlerTest.php +50 -0
- vendor/symfony/css-selector/Tests/Parser/Handler/WhitespaceHandlerTest.php +44 -0
- vendor/symfony/css-selector/Tests/Parser/ParserTest.php +253 -0
- vendor/symfony/css-selector/Tests/Parser/ReaderTest.php +102 -0
- vendor/symfony/css-selector/Tests/Parser/Shortcut/ClassParserTest.php +45 -0
- vendor/symfony/css-selector/Tests/Parser/Shortcut/ElementParserTest.php +44 -0
- vendor/symfony/css-selector/Tests/Parser/Shortcut/EmptyStringParserTest.php +36 -0
- vendor/symfony/css-selector/Tests/Parser/Shortcut/HashParserTest.php +45 -0
- vendor/symfony/css-selector/Tests/Parser/TokenStreamTest.php +96 -0
- vendor/symfony/css-selector/Tests/XPath/Fixtures/ids.html +48 -0
- vendor/symfony/css-selector/Tests/XPath/Fixtures/lang.xml +11 -0
- vendor/symfony/css-selector/Tests/XPath/Fixtures/shakespear.html +308 -0
- vendor/symfony/css-selector/Tests/XPath/TranslatorTest.php +413 -0
- vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php +5 -5
- vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php +58 -10
- vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php +18 -6
- vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php +8 -6
- vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php +26 -9
- vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php +38 -12
- vendor/symfony/css-selector/XPath/Extension/NodeExtension.php +64 -19
- vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php +38 -10
- vendor/symfony/css-selector/XPath/Translator.php +51 -18
- vendor/symfony/css-selector/XPath/TranslatorInterface.php +11 -2
- vendor/symfony/css-selector/XPath/XPathExpr.php +35 -8
- vendor/symfony/css-selector/composer.json +2 -2
- vendor/symfony/css-selector/phpunit.xml.dist +31 -0
- wp-user-avatar.php +2 -2
changelog.txt
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
-
= 3.1.
|
|
|
|
|
|
|
2 |
* Added checks to ensure pages exist before setting/redirecting to them.
|
3 |
* Fixed user profile responsiveness.
|
4 |
* Fixes PHP Fatal error: Uncaught Error: Class "DOMDocument" not found.
|
1 |
+
= 3.1.14 =
|
2 |
+
* Minimum PHP version now 5.6.0.
|
3 |
+
|
4 |
+
= 3.1.13 =
|
5 |
* Added checks to ensure pages exist before setting/redirecting to them.
|
6 |
* Fixed user profile responsiveness.
|
7 |
* Fixes PHP Fatal error: Uncaught Error: Class "DOMDocument" not found.
|
languages/wp-user-avatar.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the same license as the ProfilePress package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: ProfilePress 3.1.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-user-avatar\n"
|
7 |
-
"POT-Creation-Date: 2021-07-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -5421,9 +5421,9 @@ msgstr ""
|
|
5421 |
msgid "ProfilePress"
|
5422 |
msgstr ""
|
5423 |
|
5424 |
-
#. #-#-#-#-# wp-user-avatar.pot (ProfilePress 3.1.
|
5425 |
#. Plugin URI of the plugin/theme
|
5426 |
-
#. #-#-#-#-# wp-user-avatar.pot (ProfilePress 3.1.
|
5427 |
#. Author URI of the plugin/theme
|
5428 |
msgid "https://profilepress.net"
|
5429 |
msgstr ""
|
2 |
# This file is distributed under the same license as the ProfilePress package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: ProfilePress 3.1.14\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-user-avatar\n"
|
7 |
+
"POT-Creation-Date: 2021-07-23 16:31:41+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
5421 |
msgid "ProfilePress"
|
5422 |
msgstr ""
|
5423 |
|
5424 |
+
#. #-#-#-#-# wp-user-avatar.pot (ProfilePress 3.1.14) #-#-#-#-#
|
5425 |
#. Plugin URI of the plugin/theme
|
5426 |
+
#. #-#-#-#-# wp-user-avatar.pot (ProfilePress 3.1.14) #-#-#-#-#
|
5427 |
#. Author URI of the plugin/theme
|
5428 |
msgid "https://profilepress.net"
|
5429 |
msgstr ""
|
readme.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
=== User Registration, User Profile
|
2 |
Contributors: properfraction, collizo4sky
|
3 |
Donate link: https://profilepress.net/pricing/
|
4 |
Tags: user registration, user profile, registration form, membership, login form, login, registration, password reset, members, users, profile, front-end profile, edit profile, avatar, profile picture
|
5 |
Requires at least: 4.7
|
6 |
-
Requires PHP:
|
7 |
Tested up to: 5.8
|
8 |
-
Stable tag: 3.1.
|
9 |
License: GPLv2 or later
|
10 |
|
11 |
Modern membership plugin for user registration, login form, user profile, member directories & content restriction.
|
@@ -14,9 +14,9 @@ Modern membership plugin for user registration, login form, user profile, member
|
|
14 |
|
15 |
= The Modern WordPress Membership & User Profile Plugin =
|
16 |
|
17 |
-
[ProfilePress](https://profilepress.net/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) (formerly WP User Avatar) is a lightweight membership plugin that lets you create beautiful user profiles, member directories and frontend
|
18 |
|
19 |
-
|
20 |
|
21 |
[Website](https://profilepress.net/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Addons](https://profilepress.net/addons/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Documentation](https://profilepress.net/docs/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Support](https://profilepress.net/support/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion)
|
22 |
|
@@ -117,6 +117,9 @@ No. You can create and manage your forms, user profiles and member directories w
|
|
117 |
|
118 |
== Changelog ==
|
119 |
|
|
|
|
|
|
|
120 |
= 3.1.13 =
|
121 |
* Added checks to ensure pages exist before setting/redirecting to them.
|
122 |
* Fixed user profile responsiveness.
|
@@ -127,36 +130,4 @@ No. You can create and manage your forms, user profiles and member directories w
|
|
127 |
* Fixed issue where line breaks weren't maintained.
|
128 |
* Fixed bug where redirect after login was to an invalid url.
|
129 |
|
130 |
-
= 3.1.11 =
|
131 |
-
* Fixed missing sql unescaping in member directory search.
|
132 |
-
* Validate redirect_to urls to prevent redirect to another site.
|
133 |
-
* XSS fix by escaping variables in tab widget.
|
134 |
-
|
135 |
-
= 3.1.10 =
|
136 |
-
* Fixed issue where bulk delete wasn't working in some cases.
|
137 |
-
* Scoped wp_list actions to manage_options capability.
|
138 |
-
* Fixed typos in admin setting and My Account pages.
|
139 |
-
* Fixed broken member directory admin page design.
|
140 |
-
* Improved sanitization and escaping of data.
|
141 |
-
* Added file upload field support to profile-cpf shortcode.
|
142 |
-
* Added missing bio support to profile-hide-empty-data shortcode.
|
143 |
-
* Fixed bug where profileslug + slash in a post slug redirected to homepage.
|
144 |
-
* Fixed bug where custom processing labels didn't work for password reset forms.
|
145 |
-
|
146 |
-
= 3.1.8 =
|
147 |
-
* Fixed issue with global site access not correctly working.
|
148 |
-
* Added success color to registration form notice.
|
149 |
-
* Fixed bug admin bar control wasn't working.
|
150 |
-
* Fixed bug where specifying custom roles for registration forms didn't work.
|
151 |
-
* Improved sanitization and escaping of data in settings pages.
|
152 |
-
* Auto paragraphed form custom messages.
|
153 |
-
|
154 |
-
= 3.1.7 =
|
155 |
-
* Enhancement: JS scripts are now conditionally loaded.
|
156 |
-
* Fixed display issue in perfecto lite themes.
|
157 |
-
* Added custom message when logged in users view a login and signup page.
|
158 |
-
* Added compatibility with peters login redirect.
|
159 |
-
* Fixed incorrect avatar size retrieval.
|
160 |
-
* Fixed Warning: array_reduce() expects parameter 1 to be array, null given.
|
161 |
-
|
162 |
See the [changelog file](https://plugins.svn.wordpress.org/wp-user-avatar/trunk/changelog.txt) for full change log information.
|
1 |
+
=== User Registration, Login Form, User Profile & Membership – ProfilePress (Formerly WP User Avatar) ===
|
2 |
Contributors: properfraction, collizo4sky
|
3 |
Donate link: https://profilepress.net/pricing/
|
4 |
Tags: user registration, user profile, registration form, membership, login form, login, registration, password reset, members, users, profile, front-end profile, edit profile, avatar, profile picture
|
5 |
Requires at least: 4.7
|
6 |
+
Requires PHP: 5.6.0
|
7 |
Tested up to: 5.8
|
8 |
+
Stable tag: 3.1.14
|
9 |
License: GPLv2 or later
|
10 |
|
11 |
Modern membership plugin for user registration, login form, user profile, member directories & content restriction.
|
14 |
|
15 |
= The Modern WordPress Membership & User Profile Plugin =
|
16 |
|
17 |
+
[ProfilePress](https://profilepress.net/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) (formerly WP User Avatar) is a lightweight membership plugin that lets you create beautiful user profiles, member directories and frontend user registration form, login form, password reset and editing profile information. It also allows you to protect sensitive content and control user access.
|
18 |
|
19 |
+
Our Drag-and-Drop form builder makes building forms easy. It is the perfect solution for creating online communities and membership sites where users can easily register or signup to become members.
|
20 |
|
21 |
[Website](https://profilepress.net/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Addons](https://profilepress.net/addons/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Documentation](https://profilepress.net/docs/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion) | [Support](https://profilepress.net/support/?utm_source=wprepo&utm_medium=link&utm_campaign=liteversion)
|
22 |
|
117 |
|
118 |
== Changelog ==
|
119 |
|
120 |
+
= 3.1.14 =
|
121 |
+
* Minimum PHP version is now 5.6.0.
|
122 |
+
|
123 |
= 3.1.13 =
|
124 |
* Added checks to ensure pages exist before setting/redirecting to them.
|
125 |
* Fixed user profile responsiveness.
|
130 |
* Fixed issue where line breaks weren't maintained.
|
131 |
* Fixed bug where redirect after login was to an invalid url.
|
132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
See the [changelog file](https://plugins.svn.wordpress.org/wp-user-avatar/trunk/changelog.txt) for full change log information.
|
vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInite760b0ce87d8db13feabd2df26c92bfb::getLoader();
|
vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -24,15 +24,15 @@ class ComposerAutoloaderInitbeccdcb685b3e44da0733df7e3f5a3c4
|
|
24 |
|
25 |
require __DIR__ . '/platform_check.php';
|
26 |
|
27 |
-
spl_autoload_register(array('
|
28 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
29 |
-
spl_autoload_unregister(array('
|
30 |
|
31 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
32 |
if ($useStaticLoader) {
|
33 |
require __DIR__ . '/autoload_static.php';
|
34 |
|
35 |
-
call_user_func(\Composer\Autoload\
|
36 |
} else {
|
37 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
38 |
foreach ($map as $namespace => $path) {
|
@@ -53,19 +53,19 @@ class ComposerAutoloaderInitbeccdcb685b3e44da0733df7e3f5a3c4
|
|
53 |
$loader->register(true);
|
54 |
|
55 |
if ($useStaticLoader) {
|
56 |
-
$includeFiles = Composer\Autoload\
|
57 |
} else {
|
58 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
59 |
}
|
60 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
61 |
-
|
62 |
}
|
63 |
|
64 |
return $loader;
|
65 |
}
|
66 |
}
|
67 |
|
68 |
-
function
|
69 |
{
|
70 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
71 |
require $file;
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInite760b0ce87d8db13feabd2df26c92bfb
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
24 |
|
25 |
require __DIR__ . '/platform_check.php';
|
26 |
|
27 |
+
spl_autoload_register(array('ComposerAutoloaderInite760b0ce87d8db13feabd2df26c92bfb', 'loadClassLoader'), true, true);
|
28 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
29 |
+
spl_autoload_unregister(array('ComposerAutoloaderInite760b0ce87d8db13feabd2df26c92bfb', 'loadClassLoader'));
|
30 |
|
31 |
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
32 |
if ($useStaticLoader) {
|
33 |
require __DIR__ . '/autoload_static.php';
|
34 |
|
35 |
+
call_user_func(\Composer\Autoload\ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb::getInitializer($loader));
|
36 |
} else {
|
37 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
38 |
foreach ($map as $namespace => $path) {
|
53 |
$loader->register(true);
|
54 |
|
55 |
if ($useStaticLoader) {
|
56 |
+
$includeFiles = Composer\Autoload\ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb::$files;
|
57 |
} else {
|
58 |
$includeFiles = require __DIR__ . '/autoload_files.php';
|
59 |
}
|
60 |
foreach ($includeFiles as $fileIdentifier => $file) {
|
61 |
+
composerRequiree760b0ce87d8db13feabd2df26c92bfb($fileIdentifier, $file);
|
62 |
}
|
63 |
|
64 |
return $loader;
|
65 |
}
|
66 |
}
|
67 |
|
68 |
+
function composerRequiree760b0ce87d8db13feabd2df26c92bfb($fileIdentifier, $file)
|
69 |
{
|
70 |
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
71 |
require $file;
|
vendor/composer/autoload_static.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
-
class
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'fda73876e8be17735f680f484cec1679' => __DIR__ . '/../..' . '/src/Functions/custom-settings-api.php',
|
@@ -286,9 +286,9 @@ class ComposerStaticInitbeccdcb685b3e44da0733df7e3f5a3c4
|
|
286 |
public static function getInitializer(ClassLoader $loader)
|
287 |
{
|
288 |
return \Closure::bind(function () use ($loader) {
|
289 |
-
$loader->prefixLengthsPsr4 =
|
290 |
-
$loader->prefixDirsPsr4 =
|
291 |
-
$loader->classMap =
|
292 |
|
293 |
}, null, ClassLoader::class);
|
294 |
}
|
4 |
|
5 |
namespace Composer\Autoload;
|
6 |
|
7 |
+
class ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb
|
8 |
{
|
9 |
public static $files = array (
|
10 |
'fda73876e8be17735f680f484cec1679' => __DIR__ . '/../..' . '/src/Functions/custom-settings-api.php',
|
286 |
public static function getInitializer(ClassLoader $loader)
|
287 |
{
|
288 |
return \Closure::bind(function () use ($loader) {
|
289 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb::$prefixLengthsPsr4;
|
290 |
+
$loader->prefixDirsPsr4 = ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb::$prefixDirsPsr4;
|
291 |
+
$loader->classMap = ComposerStaticInite760b0ce87d8db13feabd2df26c92bfb::$classMap;
|
292 |
|
293 |
}, null, ClassLoader::class);
|
294 |
}
|
vendor/composer/installed.json
CHANGED
@@ -127,23 +127,23 @@
|
|
127 |
},
|
128 |
{
|
129 |
"name": "symfony/css-selector",
|
130 |
-
"version": "
|
131 |
-
"version_normalized": "
|
132 |
"source": {
|
133 |
"type": "git",
|
134 |
"url": "https://github.com/symfony/css-selector.git",
|
135 |
-
"reference": "
|
136 |
},
|
137 |
"dist": {
|
138 |
"type": "zip",
|
139 |
-
"url": "https://api.github.com/repos/symfony/css-selector/zipball/
|
140 |
-
"reference": "
|
141 |
"shasum": ""
|
142 |
},
|
143 |
"require": {
|
144 |
-
"php": "
|
145 |
},
|
146 |
-
"time": "
|
147 |
"type": "library",
|
148 |
"installation-source": "dist",
|
149 |
"autoload": {
|
@@ -172,10 +172,10 @@
|
|
172 |
"homepage": "https://symfony.com/contributors"
|
173 |
}
|
174 |
],
|
175 |
-
"description": "
|
176 |
"homepage": "https://symfony.com",
|
177 |
"support": {
|
178 |
-
"source": "https://github.com/symfony/css-selector/tree/
|
179 |
},
|
180 |
"funding": [
|
181 |
{
|
127 |
},
|
128 |
{
|
129 |
"name": "symfony/css-selector",
|
130 |
+
"version": "v3.4.47",
|
131 |
+
"version_normalized": "3.4.47.0",
|
132 |
"source": {
|
133 |
"type": "git",
|
134 |
"url": "https://github.com/symfony/css-selector.git",
|
135 |
+
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33"
|
136 |
},
|
137 |
"dist": {
|
138 |
"type": "zip",
|
139 |
+
"url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33",
|
140 |
+
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33",
|
141 |
"shasum": ""
|
142 |
},
|
143 |
"require": {
|
144 |
+
"php": "^5.5.9|>=7.0.8"
|
145 |
},
|
146 |
+
"time": "2020-10-24T10:57:07+00:00",
|
147 |
"type": "library",
|
148 |
"installation-source": "dist",
|
149 |
"autoload": {
|
172 |
"homepage": "https://symfony.com/contributors"
|
173 |
}
|
174 |
],
|
175 |
+
"description": "Symfony CssSelector Component",
|
176 |
"homepage": "https://symfony.com",
|
177 |
"support": {
|
178 |
+
"source": "https://github.com/symfony/css-selector/tree/v3.4.47"
|
179 |
},
|
180 |
"funding": [
|
181 |
{
|
vendor/composer/installed.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
'type' => 'library',
|
6 |
'install_path' => __DIR__ . '/../../',
|
7 |
'aliases' => array(),
|
8 |
-
'reference' => '
|
9 |
'name' => '__root__',
|
10 |
'dev' => false,
|
11 |
),
|
@@ -16,7 +16,7 @@
|
|
16 |
'type' => 'library',
|
17 |
'install_path' => __DIR__ . '/../../',
|
18 |
'aliases' => array(),
|
19 |
-
'reference' => '
|
20 |
'dev_requirement' => false,
|
21 |
),
|
22 |
'collizo4sky/persist-admin-notices-dismissal' => array(
|
@@ -38,12 +38,12 @@
|
|
38 |
'dev_requirement' => false,
|
39 |
),
|
40 |
'symfony/css-selector' => array(
|
41 |
-
'pretty_version' => '
|
42 |
-
'version' => '
|
43 |
'type' => 'library',
|
44 |
'install_path' => __DIR__ . '/../symfony/css-selector',
|
45 |
'aliases' => array(),
|
46 |
-
'reference' => '
|
47 |
'dev_requirement' => false,
|
48 |
),
|
49 |
),
|
5 |
'type' => 'library',
|
6 |
'install_path' => __DIR__ . '/../../',
|
7 |
'aliases' => array(),
|
8 |
+
'reference' => 'fa8ad89d612ec6c2c102321f1b1958952ba2be96',
|
9 |
'name' => '__root__',
|
10 |
'dev' => false,
|
11 |
),
|
16 |
'type' => 'library',
|
17 |
'install_path' => __DIR__ . '/../../',
|
18 |
'aliases' => array(),
|
19 |
+
'reference' => 'fa8ad89d612ec6c2c102321f1b1958952ba2be96',
|
20 |
'dev_requirement' => false,
|
21 |
),
|
22 |
'collizo4sky/persist-admin-notices-dismissal' => array(
|
38 |
'dev_requirement' => false,
|
39 |
),
|
40 |
'symfony/css-selector' => array(
|
41 |
+
'pretty_version' => 'v3.4.47',
|
42 |
+
'version' => '3.4.47.0',
|
43 |
'type' => 'library',
|
44 |
'install_path' => __DIR__ . '/../symfony/css-selector',
|
45 |
'aliases' => array(),
|
46 |
+
'reference' => 'da3d9da2ce0026771f5fe64cb332158f1bd2bc33',
|
47 |
'dev_requirement' => false,
|
48 |
),
|
49 |
),
|
vendor/composer/platform_check.php
CHANGED
@@ -4,8 +4,8 @@
|
|
4 |
|
5 |
$issues = array();
|
6 |
|
7 |
-
if (!(PHP_VERSION_ID >=
|
8 |
-
$issues[] = 'Your Composer dependencies require a PHP version ">=
|
9 |
}
|
10 |
|
11 |
if ($issues) {
|
4 |
|
5 |
$issues = array();
|
6 |
|
7 |
+
if (!(PHP_VERSION_ID >= 50600)) {
|
8 |
+
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
|
9 |
}
|
10 |
|
11 |
if ($issues) {
|
vendor/symfony/css-selector/.gitignore
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
vendor/
|
2 |
+
composer.lock
|
3 |
+
phpunit.xml
|
vendor/symfony/css-selector/CHANGELOG.md
CHANGED
@@ -1,11 +1,6 @@
|
|
1 |
CHANGELOG
|
2 |
=========
|
3 |
|
4 |
-
4.4.0
|
5 |
-
-----
|
6 |
-
|
7 |
-
* Added support for `*:only-of-type`
|
8 |
-
|
9 |
2.8.0
|
10 |
-----
|
11 |
|
1 |
CHANGELOG
|
2 |
=========
|
3 |
|
|
|
|
|
|
|
|
|
|
|
4 |
2.8.0
|
5 |
-----
|
6 |
|
vendor/symfony/css-selector/CssSelectorConverter.php
CHANGED
@@ -27,23 +27,16 @@ use Symfony\Component\CssSelector\XPath\Translator;
|
|
27 |
class CssSelectorConverter
|
28 |
{
|
29 |
private $translator;
|
30 |
-
private $cache;
|
31 |
-
|
32 |
-
private static $xmlCache = [];
|
33 |
-
private static $htmlCache = [];
|
34 |
|
35 |
/**
|
36 |
* @param bool $html Whether HTML support should be enabled. Disable it for XML documents
|
37 |
*/
|
38 |
-
public function __construct(
|
39 |
{
|
40 |
$this->translator = new Translator();
|
41 |
|
42 |
if ($html) {
|
43 |
$this->translator->registerExtension(new HtmlExtension($this->translator));
|
44 |
-
$this->cache = &self::$htmlCache;
|
45 |
-
} else {
|
46 |
-
$this->cache = &self::$xmlCache;
|
47 |
}
|
48 |
|
49 |
$this->translator
|
@@ -60,10 +53,13 @@ class CssSelectorConverter
|
|
60 |
* Optionally, a prefix can be added to the resulting XPath
|
61 |
* expression with the $prefix parameter.
|
62 |
*
|
|
|
|
|
|
|
63 |
* @return string
|
64 |
*/
|
65 |
-
public function toXPath(
|
66 |
{
|
67 |
-
return $this->
|
68 |
}
|
69 |
}
|
27 |
class CssSelectorConverter
|
28 |
{
|
29 |
private $translator;
|
|
|
|
|
|
|
|
|
30 |
|
31 |
/**
|
32 |
* @param bool $html Whether HTML support should be enabled. Disable it for XML documents
|
33 |
*/
|
34 |
+
public function __construct($html = true)
|
35 |
{
|
36 |
$this->translator = new Translator();
|
37 |
|
38 |
if ($html) {
|
39 |
$this->translator->registerExtension(new HtmlExtension($this->translator));
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
$this->translator
|
53 |
* Optionally, a prefix can be added to the resulting XPath
|
54 |
* expression with the $prefix parameter.
|
55 |
*
|
56 |
+
* @param string $cssExpr The CSS expression
|
57 |
+
* @param string $prefix An optional prefix for the XPath expression
|
58 |
+
*
|
59 |
* @return string
|
60 |
*/
|
61 |
+
public function toXPath($cssExpr, $prefix = 'descendant-or-self::')
|
62 |
{
|
63 |
+
return $this->translator->cssToXPath($cssExpr, $prefix);
|
64 |
}
|
65 |
}
|
vendor/symfony/css-selector/Exception/ExceptionInterface.php
CHANGED
@@ -19,6 +19,6 @@ namespace Symfony\Component\CssSelector\Exception;
|
|
19 |
*
|
20 |
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
21 |
*/
|
22 |
-
interface ExceptionInterface
|
23 |
{
|
24 |
}
|
19 |
*
|
20 |
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
21 |
*/
|
22 |
+
interface ExceptionInterface
|
23 |
{
|
24 |
}
|
vendor/symfony/css-selector/Exception/SyntaxErrorException.php
CHANGED
@@ -24,25 +24,32 @@ use Symfony\Component\CssSelector\Parser\Token;
|
|
24 |
class SyntaxErrorException extends ParseException
|
25 |
{
|
26 |
/**
|
|
|
|
|
27 |
* @return self
|
28 |
*/
|
29 |
-
public static function unexpectedToken(
|
30 |
{
|
31 |
return new self(sprintf('Expected %s, but %s found.', $expectedValue, $foundToken));
|
32 |
}
|
33 |
|
34 |
/**
|
|
|
|
|
|
|
35 |
* @return self
|
36 |
*/
|
37 |
-
public static function pseudoElementFound(
|
38 |
{
|
39 |
return new self(sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation));
|
40 |
}
|
41 |
|
42 |
/**
|
|
|
|
|
43 |
* @return self
|
44 |
*/
|
45 |
-
public static function unclosedString(
|
46 |
{
|
47 |
return new self(sprintf('Unclosed/invalid string at %s.', $position));
|
48 |
}
|
24 |
class SyntaxErrorException extends ParseException
|
25 |
{
|
26 |
/**
|
27 |
+
* @param string $expectedValue
|
28 |
+
*
|
29 |
* @return self
|
30 |
*/
|
31 |
+
public static function unexpectedToken($expectedValue, Token $foundToken)
|
32 |
{
|
33 |
return new self(sprintf('Expected %s, but %s found.', $expectedValue, $foundToken));
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
+
* @param string $pseudoElement
|
38 |
+
* @param string $unexpectedLocation
|
39 |
+
*
|
40 |
* @return self
|
41 |
*/
|
42 |
+
public static function pseudoElementFound($pseudoElement, $unexpectedLocation)
|
43 |
{
|
44 |
return new self(sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation));
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* @param int $position
|
49 |
+
*
|
50 |
* @return self
|
51 |
*/
|
52 |
+
public static function unclosedString($position)
|
53 |
{
|
54 |
return new self(sprintf('Unclosed/invalid string at %s.', $position));
|
55 |
}
|
vendor/symfony/css-selector/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
Copyright (c) 2004-
|
2 |
|
3 |
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
of this software and associated documentation files (the "Software"), to deal
|
1 |
+
Copyright (c) 2004-2020 Fabien Potencier
|
2 |
|
3 |
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4 |
of this software and associated documentation files (the "Software"), to deal
|
vendor/symfony/css-selector/Node/AbstractNode.php
CHANGED
@@ -28,7 +28,10 @@ abstract class AbstractNode implements NodeInterface
|
|
28 |
*/
|
29 |
private $nodeName;
|
30 |
|
31 |
-
|
|
|
|
|
|
|
32 |
{
|
33 |
if (null === $this->nodeName) {
|
34 |
$this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', static::class);
|
28 |
*/
|
29 |
private $nodeName;
|
30 |
|
31 |
+
/**
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public function getNodeName()
|
35 |
{
|
36 |
if (null === $this->nodeName) {
|
37 |
$this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', static::class);
|
vendor/symfony/css-selector/Node/AttributeNode.php
CHANGED
@@ -29,7 +29,13 @@ class AttributeNode extends AbstractNode
|
|
29 |
private $operator;
|
30 |
private $value;
|
31 |
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
{
|
34 |
$this->selector = $selector;
|
35 |
$this->namespace = $namespace;
|
@@ -38,27 +44,42 @@ class AttributeNode extends AbstractNode
|
|
38 |
$this->value = $value;
|
39 |
}
|
40 |
|
41 |
-
|
|
|
|
|
|
|
42 |
{
|
43 |
return $this->selector;
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
{
|
48 |
return $this->namespace;
|
49 |
}
|
50 |
|
51 |
-
|
|
|
|
|
|
|
52 |
{
|
53 |
return $this->attribute;
|
54 |
}
|
55 |
|
56 |
-
|
|
|
|
|
|
|
57 |
{
|
58 |
return $this->operator;
|
59 |
}
|
60 |
|
61 |
-
|
|
|
|
|
|
|
62 |
{
|
63 |
return $this->value;
|
64 |
}
|
@@ -66,7 +87,7 @@ class AttributeNode extends AbstractNode
|
|
66 |
/**
|
67 |
* {@inheritdoc}
|
68 |
*/
|
69 |
-
public function getSpecificity()
|
70 |
{
|
71 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
72 |
}
|
@@ -74,7 +95,7 @@ class AttributeNode extends AbstractNode
|
|
74 |
/**
|
75 |
* {@inheritdoc}
|
76 |
*/
|
77 |
-
public function __toString()
|
78 |
{
|
79 |
$attribute = $this->namespace ? $this->namespace.'|'.$this->attribute : $this->attribute;
|
80 |
|
29 |
private $operator;
|
30 |
private $value;
|
31 |
|
32 |
+
/**
|
33 |
+
* @param string $namespace
|
34 |
+
* @param string $attribute
|
35 |
+
* @param string $operator
|
36 |
+
* @param string $value
|
37 |
+
*/
|
38 |
+
public function __construct(NodeInterface $selector, $namespace, $attribute, $operator, $value)
|
39 |
{
|
40 |
$this->selector = $selector;
|
41 |
$this->namespace = $namespace;
|
44 |
$this->value = $value;
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* @return NodeInterface
|
49 |
+
*/
|
50 |
+
public function getSelector()
|
51 |
{
|
52 |
return $this->selector;
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
public function getNamespace()
|
59 |
{
|
60 |
return $this->namespace;
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* @return string
|
65 |
+
*/
|
66 |
+
public function getAttribute()
|
67 |
{
|
68 |
return $this->attribute;
|
69 |
}
|
70 |
|
71 |
+
/**
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
public function getOperator()
|
75 |
{
|
76 |
return $this->operator;
|
77 |
}
|
78 |
|
79 |
+
/**
|
80 |
+
* @return string
|
81 |
+
*/
|
82 |
+
public function getValue()
|
83 |
{
|
84 |
return $this->value;
|
85 |
}
|
87 |
/**
|
88 |
* {@inheritdoc}
|
89 |
*/
|
90 |
+
public function getSpecificity()
|
91 |
{
|
92 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
93 |
}
|
95 |
/**
|
96 |
* {@inheritdoc}
|
97 |
*/
|
98 |
+
public function __toString()
|
99 |
{
|
100 |
$attribute = $this->namespace ? $this->namespace.'|'.$this->attribute : $this->attribute;
|
101 |
|
vendor/symfony/css-selector/Node/ClassNode.php
CHANGED
@@ -26,18 +26,27 @@ class ClassNode extends AbstractNode
|
|
26 |
private $selector;
|
27 |
private $name;
|
28 |
|
29 |
-
|
|
|
|
|
|
|
30 |
{
|
31 |
$this->selector = $selector;
|
32 |
$this->name = $name;
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->selector;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->name;
|
43 |
}
|
@@ -45,7 +54,7 @@ class ClassNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
51 |
}
|
@@ -53,7 +62,7 @@ class ClassNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
return sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name);
|
59 |
}
|
26 |
private $selector;
|
27 |
private $name;
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string $name
|
31 |
+
*/
|
32 |
+
public function __construct(NodeInterface $selector, $name)
|
33 |
{
|
34 |
$this->selector = $selector;
|
35 |
$this->name = $name;
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* @return NodeInterface
|
40 |
+
*/
|
41 |
+
public function getSelector()
|
42 |
{
|
43 |
return $this->selector;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function getName()
|
50 |
{
|
51 |
return $this->name;
|
52 |
}
|
54 |
/**
|
55 |
* {@inheritdoc}
|
56 |
*/
|
57 |
+
public function getSpecificity()
|
58 |
{
|
59 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
60 |
}
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
65 |
+
public function __toString()
|
66 |
{
|
67 |
return sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name);
|
68 |
}
|
vendor/symfony/css-selector/Node/CombinedSelectorNode.php
CHANGED
@@ -27,24 +27,36 @@ class CombinedSelectorNode extends AbstractNode
|
|
27 |
private $combinator;
|
28 |
private $subSelector;
|
29 |
|
30 |
-
|
|
|
|
|
|
|
31 |
{
|
32 |
$this->selector = $selector;
|
33 |
$this->combinator = $combinator;
|
34 |
$this->subSelector = $subSelector;
|
35 |
}
|
36 |
|
37 |
-
|
|
|
|
|
|
|
38 |
{
|
39 |
return $this->selector;
|
40 |
}
|
41 |
|
42 |
-
|
|
|
|
|
|
|
43 |
{
|
44 |
return $this->combinator;
|
45 |
}
|
46 |
|
47 |
-
|
|
|
|
|
|
|
48 |
{
|
49 |
return $this->subSelector;
|
50 |
}
|
@@ -52,7 +64,7 @@ class CombinedSelectorNode extends AbstractNode
|
|
52 |
/**
|
53 |
* {@inheritdoc}
|
54 |
*/
|
55 |
-
public function getSpecificity()
|
56 |
{
|
57 |
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
58 |
}
|
@@ -60,7 +72,7 @@ class CombinedSelectorNode extends AbstractNode
|
|
60 |
/**
|
61 |
* {@inheritdoc}
|
62 |
*/
|
63 |
-
public function __toString()
|
64 |
{
|
65 |
$combinator = ' ' === $this->combinator ? '<followed>' : $this->combinator;
|
66 |
|
27 |
private $combinator;
|
28 |
private $subSelector;
|
29 |
|
30 |
+
/**
|
31 |
+
* @param string $combinator
|
32 |
+
*/
|
33 |
+
public function __construct(NodeInterface $selector, $combinator, NodeInterface $subSelector)
|
34 |
{
|
35 |
$this->selector = $selector;
|
36 |
$this->combinator = $combinator;
|
37 |
$this->subSelector = $subSelector;
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* @return NodeInterface
|
42 |
+
*/
|
43 |
+
public function getSelector()
|
44 |
{
|
45 |
return $this->selector;
|
46 |
}
|
47 |
|
48 |
+
/**
|
49 |
+
* @return string
|
50 |
+
*/
|
51 |
+
public function getCombinator()
|
52 |
{
|
53 |
return $this->combinator;
|
54 |
}
|
55 |
|
56 |
+
/**
|
57 |
+
* @return NodeInterface
|
58 |
+
*/
|
59 |
+
public function getSubSelector()
|
60 |
{
|
61 |
return $this->subSelector;
|
62 |
}
|
64 |
/**
|
65 |
* {@inheritdoc}
|
66 |
*/
|
67 |
+
public function getSpecificity()
|
68 |
{
|
69 |
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
70 |
}
|
72 |
/**
|
73 |
* {@inheritdoc}
|
74 |
*/
|
75 |
+
public function __toString()
|
76 |
{
|
77 |
$combinator = ' ' === $this->combinator ? '<followed>' : $this->combinator;
|
78 |
|
vendor/symfony/css-selector/Node/ElementNode.php
CHANGED
@@ -26,18 +26,28 @@ class ElementNode extends AbstractNode
|
|
26 |
private $namespace;
|
27 |
private $element;
|
28 |
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
{
|
31 |
$this->namespace = $namespace;
|
32 |
$this->element = $element;
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->namespace;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->element;
|
43 |
}
|
@@ -45,7 +55,7 @@ class ElementNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return new Specificity(0, 0, $this->element ? 1 : 0);
|
51 |
}
|
@@ -53,7 +63,7 @@ class ElementNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
$element = $this->element ?: '*';
|
59 |
|
26 |
private $namespace;
|
27 |
private $element;
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string|null $namespace
|
31 |
+
* @param string|null $element
|
32 |
+
*/
|
33 |
+
public function __construct($namespace = null, $element = null)
|
34 |
{
|
35 |
$this->namespace = $namespace;
|
36 |
$this->element = $element;
|
37 |
}
|
38 |
|
39 |
+
/**
|
40 |
+
* @return string|null
|
41 |
+
*/
|
42 |
+
public function getNamespace()
|
43 |
{
|
44 |
return $this->namespace;
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* @return string|null
|
49 |
+
*/
|
50 |
+
public function getElement()
|
51 |
{
|
52 |
return $this->element;
|
53 |
}
|
55 |
/**
|
56 |
* {@inheritdoc}
|
57 |
*/
|
58 |
+
public function getSpecificity()
|
59 |
{
|
60 |
return new Specificity(0, 0, $this->element ? 1 : 0);
|
61 |
}
|
63 |
/**
|
64 |
* {@inheritdoc}
|
65 |
*/
|
66 |
+
public function __toString()
|
67 |
{
|
68 |
$element = $this->element ?: '*';
|
69 |
|
vendor/symfony/css-selector/Node/FunctionNode.php
CHANGED
@@ -30,21 +30,28 @@ class FunctionNode extends AbstractNode
|
|
30 |
private $arguments;
|
31 |
|
32 |
/**
|
|
|
33 |
* @param Token[] $arguments
|
34 |
*/
|
35 |
-
public function __construct(NodeInterface $selector,
|
36 |
{
|
37 |
$this->selector = $selector;
|
38 |
$this->name = strtolower($name);
|
39 |
$this->arguments = $arguments;
|
40 |
}
|
41 |
|
42 |
-
|
|
|
|
|
|
|
43 |
{
|
44 |
return $this->selector;
|
45 |
}
|
46 |
|
47 |
-
|
|
|
|
|
|
|
48 |
{
|
49 |
return $this->name;
|
50 |
}
|
@@ -52,7 +59,7 @@ class FunctionNode extends AbstractNode
|
|
52 |
/**
|
53 |
* @return Token[]
|
54 |
*/
|
55 |
-
public function getArguments()
|
56 |
{
|
57 |
return $this->arguments;
|
58 |
}
|
@@ -60,7 +67,7 @@ class FunctionNode extends AbstractNode
|
|
60 |
/**
|
61 |
* {@inheritdoc}
|
62 |
*/
|
63 |
-
public function getSpecificity()
|
64 |
{
|
65 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
66 |
}
|
@@ -68,7 +75,7 @@ class FunctionNode extends AbstractNode
|
|
68 |
/**
|
69 |
* {@inheritdoc}
|
70 |
*/
|
71 |
-
public function __toString()
|
72 |
{
|
73 |
$arguments = implode(', ', array_map(function (Token $token) {
|
74 |
return "'".$token->getValue()."'";
|
30 |
private $arguments;
|
31 |
|
32 |
/**
|
33 |
+
* @param string $name
|
34 |
* @param Token[] $arguments
|
35 |
*/
|
36 |
+
public function __construct(NodeInterface $selector, $name, array $arguments = [])
|
37 |
{
|
38 |
$this->selector = $selector;
|
39 |
$this->name = strtolower($name);
|
40 |
$this->arguments = $arguments;
|
41 |
}
|
42 |
|
43 |
+
/**
|
44 |
+
* @return NodeInterface
|
45 |
+
*/
|
46 |
+
public function getSelector()
|
47 |
{
|
48 |
return $this->selector;
|
49 |
}
|
50 |
|
51 |
+
/**
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function getName()
|
55 |
{
|
56 |
return $this->name;
|
57 |
}
|
59 |
/**
|
60 |
* @return Token[]
|
61 |
*/
|
62 |
+
public function getArguments()
|
63 |
{
|
64 |
return $this->arguments;
|
65 |
}
|
67 |
/**
|
68 |
* {@inheritdoc}
|
69 |
*/
|
70 |
+
public function getSpecificity()
|
71 |
{
|
72 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
73 |
}
|
75 |
/**
|
76 |
* {@inheritdoc}
|
77 |
*/
|
78 |
+
public function __toString()
|
79 |
{
|
80 |
$arguments = implode(', ', array_map(function (Token $token) {
|
81 |
return "'".$token->getValue()."'";
|
vendor/symfony/css-selector/Node/HashNode.php
CHANGED
@@ -26,18 +26,27 @@ class HashNode extends AbstractNode
|
|
26 |
private $selector;
|
27 |
private $id;
|
28 |
|
29 |
-
|
|
|
|
|
|
|
30 |
{
|
31 |
$this->selector = $selector;
|
32 |
$this->id = $id;
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->selector;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->id;
|
43 |
}
|
@@ -45,7 +54,7 @@ class HashNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0));
|
51 |
}
|
@@ -53,7 +62,7 @@ class HashNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
return sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id);
|
59 |
}
|
26 |
private $selector;
|
27 |
private $id;
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string $id
|
31 |
+
*/
|
32 |
+
public function __construct(NodeInterface $selector, $id)
|
33 |
{
|
34 |
$this->selector = $selector;
|
35 |
$this->id = $id;
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* @return NodeInterface
|
40 |
+
*/
|
41 |
+
public function getSelector()
|
42 |
{
|
43 |
return $this->selector;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function getId()
|
50 |
{
|
51 |
return $this->id;
|
52 |
}
|
54 |
/**
|
55 |
* {@inheritdoc}
|
56 |
*/
|
57 |
+
public function getSpecificity()
|
58 |
{
|
59 |
return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0));
|
60 |
}
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
65 |
+
public function __toString()
|
66 |
{
|
67 |
return sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id);
|
68 |
}
|
vendor/symfony/css-selector/Node/NegationNode.php
CHANGED
@@ -32,12 +32,18 @@ class NegationNode extends AbstractNode
|
|
32 |
$this->subSelector = $subSelector;
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->selector;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->subSelector;
|
43 |
}
|
@@ -45,7 +51,7 @@ class NegationNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
51 |
}
|
@@ -53,7 +59,7 @@ class NegationNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
return sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector);
|
59 |
}
|
32 |
$this->subSelector = $subSelector;
|
33 |
}
|
34 |
|
35 |
+
/**
|
36 |
+
* @return NodeInterface
|
37 |
+
*/
|
38 |
+
public function getSelector()
|
39 |
{
|
40 |
return $this->selector;
|
41 |
}
|
42 |
|
43 |
+
/**
|
44 |
+
* @return NodeInterface
|
45 |
+
*/
|
46 |
+
public function getSubSelector()
|
47 |
{
|
48 |
return $this->subSelector;
|
49 |
}
|
51 |
/**
|
52 |
* {@inheritdoc}
|
53 |
*/
|
54 |
+
public function getSpecificity()
|
55 |
{
|
56 |
return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity());
|
57 |
}
|
59 |
/**
|
60 |
* {@inheritdoc}
|
61 |
*/
|
62 |
+
public function __toString()
|
63 |
{
|
64 |
return sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector);
|
65 |
}
|
vendor/symfony/css-selector/Node/NodeInterface.php
CHANGED
@@ -23,9 +23,24 @@ namespace Symfony\Component\CssSelector\Node;
|
|
23 |
*/
|
24 |
interface NodeInterface
|
25 |
{
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
23 |
*/
|
24 |
interface NodeInterface
|
25 |
{
|
26 |
+
/**
|
27 |
+
* Returns node's name.
|
28 |
+
*
|
29 |
+
* @return string
|
30 |
+
*/
|
31 |
+
public function getNodeName();
|
32 |
|
33 |
+
/**
|
34 |
+
* Returns node's specificity.
|
35 |
+
*
|
36 |
+
* @return Specificity
|
37 |
+
*/
|
38 |
+
public function getSpecificity();
|
39 |
|
40 |
+
/**
|
41 |
+
* Returns node's string representation.
|
42 |
+
*
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
public function __toString();
|
46 |
}
|
vendor/symfony/css-selector/Node/PseudoNode.php
CHANGED
@@ -26,18 +26,27 @@ class PseudoNode extends AbstractNode
|
|
26 |
private $selector;
|
27 |
private $identifier;
|
28 |
|
29 |
-
|
|
|
|
|
|
|
30 |
{
|
31 |
$this->selector = $selector;
|
32 |
$this->identifier = strtolower($identifier);
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->selector;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->identifier;
|
43 |
}
|
@@ -45,7 +54,7 @@ class PseudoNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
51 |
}
|
@@ -53,7 +62,7 @@ class PseudoNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
return sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier);
|
59 |
}
|
26 |
private $selector;
|
27 |
private $identifier;
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string $identifier
|
31 |
+
*/
|
32 |
+
public function __construct(NodeInterface $selector, $identifier)
|
33 |
{
|
34 |
$this->selector = $selector;
|
35 |
$this->identifier = strtolower($identifier);
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* @return NodeInterface
|
40 |
+
*/
|
41 |
+
public function getSelector()
|
42 |
{
|
43 |
return $this->selector;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function getIdentifier()
|
50 |
{
|
51 |
return $this->identifier;
|
52 |
}
|
54 |
/**
|
55 |
* {@inheritdoc}
|
56 |
*/
|
57 |
+
public function getSpecificity()
|
58 |
{
|
59 |
return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0));
|
60 |
}
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
65 |
+
public function __toString()
|
66 |
{
|
67 |
return sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier);
|
68 |
}
|
vendor/symfony/css-selector/Node/SelectorNode.php
CHANGED
@@ -26,18 +26,27 @@ class SelectorNode extends AbstractNode
|
|
26 |
private $tree;
|
27 |
private $pseudoElement;
|
28 |
|
29 |
-
|
|
|
|
|
|
|
30 |
{
|
31 |
$this->tree = $tree;
|
32 |
$this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null;
|
33 |
}
|
34 |
|
35 |
-
|
|
|
|
|
|
|
36 |
{
|
37 |
return $this->tree;
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
{
|
42 |
return $this->pseudoElement;
|
43 |
}
|
@@ -45,7 +54,7 @@ class SelectorNode extends AbstractNode
|
|
45 |
/**
|
46 |
* {@inheritdoc}
|
47 |
*/
|
48 |
-
public function getSpecificity()
|
49 |
{
|
50 |
return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0));
|
51 |
}
|
@@ -53,7 +62,7 @@ class SelectorNode extends AbstractNode
|
|
53 |
/**
|
54 |
* {@inheritdoc}
|
55 |
*/
|
56 |
-
public function __toString()
|
57 |
{
|
58 |
return sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : '');
|
59 |
}
|
26 |
private $tree;
|
27 |
private $pseudoElement;
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string|null $pseudoElement
|
31 |
+
*/
|
32 |
+
public function __construct(NodeInterface $tree, $pseudoElement = null)
|
33 |
{
|
34 |
$this->tree = $tree;
|
35 |
$this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null;
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* @return NodeInterface
|
40 |
+
*/
|
41 |
+
public function getTree()
|
42 |
{
|
43 |
return $this->tree;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @return string|null
|
48 |
+
*/
|
49 |
+
public function getPseudoElement()
|
50 |
{
|
51 |
return $this->pseudoElement;
|
52 |
}
|
54 |
/**
|
55 |
* {@inheritdoc}
|
56 |
*/
|
57 |
+
public function getSpecificity()
|
58 |
{
|
59 |
return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0));
|
60 |
}
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
65 |
+
public function __toString()
|
66 |
{
|
67 |
return sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : '');
|
68 |
}
|
vendor/symfony/css-selector/Node/Specificity.php
CHANGED
@@ -25,27 +25,40 @@ namespace Symfony\Component\CssSelector\Node;
|
|
25 |
*/
|
26 |
class Specificity
|
27 |
{
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
|
32 |
private $a;
|
33 |
private $b;
|
34 |
private $c;
|
35 |
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
37 |
{
|
38 |
$this->a = $a;
|
39 |
$this->b = $b;
|
40 |
$this->c = $c;
|
41 |
}
|
42 |
|
43 |
-
|
|
|
|
|
|
|
44 |
{
|
45 |
return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c);
|
46 |
}
|
47 |
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
49 |
{
|
50 |
return $this->a * self::A_FACTOR + $this->b * self::B_FACTOR + $this->c * self::C_FACTOR;
|
51 |
}
|
@@ -53,8 +66,10 @@ class Specificity
|
|
53 |
/**
|
54 |
* Returns -1 if the object specificity is lower than the argument,
|
55 |
* 0 if they are equal, and 1 if the argument is lower.
|
|
|
|
|
56 |
*/
|
57 |
-
public function compareTo(self $specificity)
|
58 |
{
|
59 |
if ($this->a !== $specificity->a) {
|
60 |
return $this->a > $specificity->a ? 1 : -1;
|
25 |
*/
|
26 |
class Specificity
|
27 |
{
|
28 |
+
const A_FACTOR = 100;
|
29 |
+
const B_FACTOR = 10;
|
30 |
+
const C_FACTOR = 1;
|
31 |
|
32 |
private $a;
|
33 |
private $b;
|
34 |
private $c;
|
35 |
|
36 |
+
/**
|
37 |
+
* @param int $a
|
38 |
+
* @param int $b
|
39 |
+
* @param int $c
|
40 |
+
*/
|
41 |
+
public function __construct($a, $b, $c)
|
42 |
{
|
43 |
$this->a = $a;
|
44 |
$this->b = $b;
|
45 |
$this->c = $c;
|
46 |
}
|
47 |
|
48 |
+
/**
|
49 |
+
* @return self
|
50 |
+
*/
|
51 |
+
public function plus(self $specificity)
|
52 |
{
|
53 |
return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c);
|
54 |
}
|
55 |
|
56 |
+
/**
|
57 |
+
* Returns global specificity value.
|
58 |
+
*
|
59 |
+
* @return int
|
60 |
+
*/
|
61 |
+
public function getValue()
|
62 |
{
|
63 |
return $this->a * self::A_FACTOR + $this->b * self::B_FACTOR + $this->c * self::C_FACTOR;
|
64 |
}
|
66 |
/**
|
67 |
* Returns -1 if the object specificity is lower than the argument,
|
68 |
* 0 if they are equal, and 1 if the argument is lower.
|
69 |
+
*
|
70 |
+
* @return int
|
71 |
*/
|
72 |
+
public function compareTo(self $specificity)
|
73 |
{
|
74 |
if ($this->a !== $specificity->a) {
|
75 |
return $this->a > $specificity->a ? 1 : -1;
|
vendor/symfony/css-selector/Parser/Handler/CommentHandler.php
CHANGED
@@ -29,7 +29,7 @@ class CommentHandler implements HandlerInterface
|
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
-
public function handle(Reader $reader, TokenStream $stream)
|
33 |
{
|
34 |
if ('/*' !== $reader->getSubstring(2)) {
|
35 |
return false;
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
+
public function handle(Reader $reader, TokenStream $stream)
|
33 |
{
|
34 |
if ('/*' !== $reader->getSubstring(2)) {
|
35 |
return false;
|
vendor/symfony/css-selector/Parser/Handler/HandlerInterface.php
CHANGED
@@ -26,5 +26,8 @@ use Symfony\Component\CssSelector\Parser\TokenStream;
|
|
26 |
*/
|
27 |
interface HandlerInterface
|
28 |
{
|
29 |
-
|
|
|
|
|
|
|
30 |
}
|
26 |
*/
|
27 |
interface HandlerInterface
|
28 |
{
|
29 |
+
/**
|
30 |
+
* @return bool
|
31 |
+
*/
|
32 |
+
public function handle(Reader $reader, TokenStream $stream);
|
33 |
}
|
vendor/symfony/css-selector/Parser/Handler/HashHandler.php
CHANGED
@@ -41,7 +41,7 @@ class HashHandler implements HandlerInterface
|
|
41 |
/**
|
42 |
* {@inheritdoc}
|
43 |
*/
|
44 |
-
public function handle(Reader $reader, TokenStream $stream)
|
45 |
{
|
46 |
$match = $reader->findPattern($this->patterns->getHashPattern());
|
47 |
|
41 |
/**
|
42 |
* {@inheritdoc}
|
43 |
*/
|
44 |
+
public function handle(Reader $reader, TokenStream $stream)
|
45 |
{
|
46 |
$match = $reader->findPattern($this->patterns->getHashPattern());
|
47 |
|
vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php
CHANGED
@@ -41,7 +41,7 @@ class IdentifierHandler implements HandlerInterface
|
|
41 |
/**
|
42 |
* {@inheritdoc}
|
43 |
*/
|
44 |
-
public function handle(Reader $reader, TokenStream $stream)
|
45 |
{
|
46 |
$match = $reader->findPattern($this->patterns->getIdentifierPattern());
|
47 |
|
41 |
/**
|
42 |
* {@inheritdoc}
|
43 |
*/
|
44 |
+
public function handle(Reader $reader, TokenStream $stream)
|
45 |
{
|
46 |
$match = $reader->findPattern($this->patterns->getIdentifierPattern());
|
47 |
|
vendor/symfony/css-selector/Parser/Handler/NumberHandler.php
CHANGED
@@ -38,7 +38,7 @@ class NumberHandler implements HandlerInterface
|
|
38 |
/**
|
39 |
* {@inheritdoc}
|
40 |
*/
|
41 |
-
public function handle(Reader $reader, TokenStream $stream)
|
42 |
{
|
43 |
$match = $reader->findPattern($this->patterns->getNumberPattern());
|
44 |
|
38 |
/**
|
39 |
* {@inheritdoc}
|
40 |
*/
|
41 |
+
public function handle(Reader $reader, TokenStream $stream)
|
42 |
{
|
43 |
$match = $reader->findPattern($this->patterns->getNumberPattern());
|
44 |
|
vendor/symfony/css-selector/Parser/Handler/StringHandler.php
CHANGED
@@ -43,7 +43,7 @@ class StringHandler implements HandlerInterface
|
|
43 |
/**
|
44 |
* {@inheritdoc}
|
45 |
*/
|
46 |
-
public function handle(Reader $reader, TokenStream $stream)
|
47 |
{
|
48 |
$quote = $reader->getSubstring(1);
|
49 |
|
43 |
/**
|
44 |
* {@inheritdoc}
|
45 |
*/
|
46 |
+
public function handle(Reader $reader, TokenStream $stream)
|
47 |
{
|
48 |
$quote = $reader->getSubstring(1);
|
49 |
|
vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php
CHANGED
@@ -30,7 +30,7 @@ class WhitespaceHandler implements HandlerInterface
|
|
30 |
/**
|
31 |
* {@inheritdoc}
|
32 |
*/
|
33 |
-
public function handle(Reader $reader, TokenStream $stream)
|
34 |
{
|
35 |
$match = $reader->findPattern('~^[ \t\r\n\f]+~');
|
36 |
|
30 |
/**
|
31 |
* {@inheritdoc}
|
32 |
*/
|
33 |
+
public function handle(Reader $reader, TokenStream $stream)
|
34 |
{
|
35 |
$match = $reader->findPattern('~^[ \t\r\n\f]+~');
|
36 |
|
vendor/symfony/css-selector/Parser/Parser.php
CHANGED
@@ -31,13 +31,13 @@ class Parser implements ParserInterface
|
|
31 |
|
32 |
public function __construct(Tokenizer $tokenizer = null)
|
33 |
{
|
34 |
-
$this->tokenizer = $tokenizer
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
* {@inheritdoc}
|
39 |
*/
|
40 |
-
public function parse(
|
41 |
{
|
42 |
$reader = new Reader($source);
|
43 |
$stream = $this->tokenizer->tokenize($reader);
|
@@ -50,9 +50,11 @@ class Parser implements ParserInterface
|
|
50 |
*
|
51 |
* @param Token[] $tokens
|
52 |
*
|
|
|
|
|
53 |
* @throws SyntaxErrorException
|
54 |
*/
|
55 |
-
public static function parseSeries(array $tokens)
|
56 |
{
|
57 |
foreach ($tokens as $token) {
|
58 |
if ($token->isString()) {
|
@@ -84,7 +86,7 @@ class Parser implements ParserInterface
|
|
84 |
}
|
85 |
|
86 |
$split = explode('n', $joined);
|
87 |
-
$first = $split[0]
|
88 |
|
89 |
return [
|
90 |
$first ? ('-' === $first || '+' === $first ? $int($first.'1') : $int($first)) : 1,
|
@@ -92,7 +94,12 @@ class Parser implements ParserInterface
|
|
92 |
];
|
93 |
}
|
94 |
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
96 |
{
|
97 |
$stream->skipWhitespace();
|
98 |
$selectors = [];
|
@@ -111,9 +118,16 @@ class Parser implements ParserInterface
|
|
111 |
return $selectors;
|
112 |
}
|
113 |
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
{
|
116 |
-
|
117 |
|
118 |
while (true) {
|
119 |
$stream->skipWhitespace();
|
@@ -134,7 +148,7 @@ class Parser implements ParserInterface
|
|
134 |
$combinator = ' ';
|
135 |
}
|
136 |
|
137 |
-
|
138 |
$result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector);
|
139 |
}
|
140 |
|
@@ -144,9 +158,13 @@ class Parser implements ParserInterface
|
|
144 |
/**
|
145 |
* Parses next simple node (hash, class, pseudo, negation).
|
146 |
*
|
|
|
|
|
|
|
|
|
147 |
* @throws SyntaxErrorException
|
148 |
*/
|
149 |
-
private function parseSimpleSelector(TokenStream $stream,
|
150 |
{
|
151 |
$stream->skipWhitespace();
|
152 |
|
@@ -209,7 +227,7 @@ class Parser implements ParserInterface
|
|
209 |
throw SyntaxErrorException::nestedNot();
|
210 |
}
|
211 |
|
212 |
-
|
213 |
$next = $stream->getNext();
|
214 |
|
215 |
if (null !== $argumentPseudoElement) {
|
@@ -260,7 +278,12 @@ class Parser implements ParserInterface
|
|
260 |
return [$result, $pseudoElement];
|
261 |
}
|
262 |
|
263 |
-
|
|
|
|
|
|
|
|
|
|
|
264 |
{
|
265 |
$peek = $stream->getPeek();
|
266 |
|
@@ -286,7 +309,14 @@ class Parser implements ParserInterface
|
|
286 |
return new Node\ElementNode($namespace, $element);
|
287 |
}
|
288 |
|
289 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
{
|
291 |
$stream->skipWhitespace();
|
292 |
$attribute = $stream->getNextIdentifierOrStar();
|
31 |
|
32 |
public function __construct(Tokenizer $tokenizer = null)
|
33 |
{
|
34 |
+
$this->tokenizer = $tokenizer ?: new Tokenizer();
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
* {@inheritdoc}
|
39 |
*/
|
40 |
+
public function parse($source)
|
41 |
{
|
42 |
$reader = new Reader($source);
|
43 |
$stream = $this->tokenizer->tokenize($reader);
|
50 |
*
|
51 |
* @param Token[] $tokens
|
52 |
*
|
53 |
+
* @return array
|
54 |
+
*
|
55 |
* @throws SyntaxErrorException
|
56 |
*/
|
57 |
+
public static function parseSeries(array $tokens)
|
58 |
{
|
59 |
foreach ($tokens as $token) {
|
60 |
if ($token->isString()) {
|
86 |
}
|
87 |
|
88 |
$split = explode('n', $joined);
|
89 |
+
$first = isset($split[0]) ? $split[0] : null;
|
90 |
|
91 |
return [
|
92 |
$first ? ('-' === $first || '+' === $first ? $int($first.'1') : $int($first)) : 1,
|
94 |
];
|
95 |
}
|
96 |
|
97 |
+
/**
|
98 |
+
* Parses selector nodes.
|
99 |
+
*
|
100 |
+
* @return array
|
101 |
+
*/
|
102 |
+
private function parseSelectorList(TokenStream $stream)
|
103 |
{
|
104 |
$stream->skipWhitespace();
|
105 |
$selectors = [];
|
118 |
return $selectors;
|
119 |
}
|
120 |
|
121 |
+
/**
|
122 |
+
* Parses next selector or combined node.
|
123 |
+
*
|
124 |
+
* @return Node\SelectorNode
|
125 |
+
*
|
126 |
+
* @throws SyntaxErrorException
|
127 |
+
*/
|
128 |
+
private function parserSelectorNode(TokenStream $stream)
|
129 |
{
|
130 |
+
list($result, $pseudoElement) = $this->parseSimpleSelector($stream);
|
131 |
|
132 |
while (true) {
|
133 |
$stream->skipWhitespace();
|
148 |
$combinator = ' ';
|
149 |
}
|
150 |
|
151 |
+
list($nextSelector, $pseudoElement) = $this->parseSimpleSelector($stream);
|
152 |
$result = new Node\CombinedSelectorNode($result, $combinator, $nextSelector);
|
153 |
}
|
154 |
|
158 |
/**
|
159 |
* Parses next simple node (hash, class, pseudo, negation).
|
160 |
*
|
161 |
+
* @param bool $insideNegation
|
162 |
+
*
|
163 |
+
* @return array
|
164 |
+
*
|
165 |
* @throws SyntaxErrorException
|
166 |
*/
|
167 |
+
private function parseSimpleSelector(TokenStream $stream, $insideNegation = false)
|
168 |
{
|
169 |
$stream->skipWhitespace();
|
170 |
|
227 |
throw SyntaxErrorException::nestedNot();
|
228 |
}
|
229 |
|
230 |
+
list($argument, $argumentPseudoElement) = $this->parseSimpleSelector($stream, true);
|
231 |
$next = $stream->getNext();
|
232 |
|
233 |
if (null !== $argumentPseudoElement) {
|
278 |
return [$result, $pseudoElement];
|
279 |
}
|
280 |
|
281 |
+
/**
|
282 |
+
* Parses next element node.
|
283 |
+
*
|
284 |
+
* @return Node\ElementNode
|
285 |
+
*/
|
286 |
+
private function parseElementNode(TokenStream $stream)
|
287 |
{
|
288 |
$peek = $stream->getPeek();
|
289 |
|
309 |
return new Node\ElementNode($namespace, $element);
|
310 |
}
|
311 |
|
312 |
+
/**
|
313 |
+
* Parses next attribute node.
|
314 |
+
*
|
315 |
+
* @return Node\AttributeNode
|
316 |
+
*
|
317 |
+
* @throws SyntaxErrorException
|
318 |
+
*/
|
319 |
+
private function parseAttributeNode(Node\NodeInterface $selector, TokenStream $stream)
|
320 |
{
|
321 |
$stream->skipWhitespace();
|
322 |
$attribute = $stream->getNextIdentifierOrStar();
|
vendor/symfony/css-selector/Parser/ParserInterface.php
CHANGED
@@ -28,7 +28,9 @@ interface ParserInterface
|
|
28 |
/**
|
29 |
* Parses given selector source into an array of tokens.
|
30 |
*
|
|
|
|
|
31 |
* @return SelectorNode[]
|
32 |
*/
|
33 |
-
public function parse(
|
34 |
}
|
28 |
/**
|
29 |
* Parses given selector source into an array of tokens.
|
30 |
*
|
31 |
+
* @param string $source
|
32 |
+
*
|
33 |
* @return SelectorNode[]
|
34 |
*/
|
35 |
+
public function parse($source);
|
36 |
}
|
vendor/symfony/css-selector/Parser/Reader.php
CHANGED
@@ -27,33 +27,56 @@ class Reader
|
|
27 |
private $length;
|
28 |
private $position = 0;
|
29 |
|
30 |
-
|
|
|
|
|
|
|
31 |
{
|
32 |
$this->source = $source;
|
33 |
$this->length = \strlen($source);
|
34 |
}
|
35 |
|
36 |
-
|
|
|
|
|
|
|
37 |
{
|
38 |
return $this->position >= $this->length;
|
39 |
}
|
40 |
|
41 |
-
|
|
|
|
|
|
|
42 |
{
|
43 |
return $this->position;
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
{
|
48 |
return $this->length - $this->position;
|
49 |
}
|
50 |
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
{
|
53 |
return substr($this->source, $this->position + $offset, $length);
|
54 |
}
|
55 |
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
{
|
58 |
$position = strpos($this->source, $string, $this->position);
|
59 |
|
@@ -61,9 +84,11 @@ class Reader
|
|
61 |
}
|
62 |
|
63 |
/**
|
|
|
|
|
64 |
* @return array|false
|
65 |
*/
|
66 |
-
public function findPattern(
|
67 |
{
|
68 |
$source = substr($this->source, $this->position);
|
69 |
|
@@ -74,7 +99,10 @@ class Reader
|
|
74 |
return false;
|
75 |
}
|
76 |
|
77 |
-
|
|
|
|
|
|
|
78 |
{
|
79 |
$this->position += $length;
|
80 |
}
|
27 |
private $length;
|
28 |
private $position = 0;
|
29 |
|
30 |
+
/**
|
31 |
+
* @param string $source
|
32 |
+
*/
|
33 |
+
public function __construct($source)
|
34 |
{
|
35 |
$this->source = $source;
|
36 |
$this->length = \strlen($source);
|
37 |
}
|
38 |
|
39 |
+
/**
|
40 |
+
* @return bool
|
41 |
+
*/
|
42 |
+
public function isEOF()
|
43 |
{
|
44 |
return $this->position >= $this->length;
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* @return int
|
49 |
+
*/
|
50 |
+
public function getPosition()
|
51 |
{
|
52 |
return $this->position;
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @return int
|
57 |
+
*/
|
58 |
+
public function getRemainingLength()
|
59 |
{
|
60 |
return $this->length - $this->position;
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* @param int $length
|
65 |
+
* @param int $offset
|
66 |
+
*
|
67 |
+
* @return string
|
68 |
+
*/
|
69 |
+
public function getSubstring($length, $offset = 0)
|
70 |
{
|
71 |
return substr($this->source, $this->position + $offset, $length);
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* @param string $string
|
76 |
+
*
|
77 |
+
* @return int
|
78 |
+
*/
|
79 |
+
public function getOffset($string)
|
80 |
{
|
81 |
$position = strpos($this->source, $string, $this->position);
|
82 |
|
84 |
}
|
85 |
|
86 |
/**
|
87 |
+
* @param string $pattern
|
88 |
+
*
|
89 |
* @return array|false
|
90 |
*/
|
91 |
+
public function findPattern($pattern)
|
92 |
{
|
93 |
$source = substr($this->source, $this->position);
|
94 |
|
99 |
return false;
|
100 |
}
|
101 |
|
102 |
+
/**
|
103 |
+
* @param int $length
|
104 |
+
*/
|
105 |
+
public function moveForward($length)
|
106 |
{
|
107 |
$this->position += $length;
|
108 |
}
|
vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php
CHANGED
@@ -31,7 +31,7 @@ class ClassParser implements ParserInterface
|
|
31 |
/**
|
32 |
* {@inheritdoc}
|
33 |
*/
|
34 |
-
public function parse(
|
35 |
{
|
36 |
// Matches an optional namespace, optional element, and required class
|
37 |
// $source = 'test|input.ab6bd_field';
|
31 |
/**
|
32 |
* {@inheritdoc}
|
33 |
*/
|
34 |
+
public function parse($source)
|
35 |
{
|
36 |
// Matches an optional namespace, optional element, and required class
|
37 |
// $source = 'test|input.ab6bd_field';
|
vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php
CHANGED
@@ -30,7 +30,7 @@ class ElementParser implements ParserInterface
|
|
30 |
/**
|
31 |
* {@inheritdoc}
|
32 |
*/
|
33 |
-
public function parse(
|
34 |
{
|
35 |
// Matches an optional namespace, required element or `*`
|
36 |
// $source = 'testns|testel';
|
30 |
/**
|
31 |
* {@inheritdoc}
|
32 |
*/
|
33 |
+
public function parse($source)
|
34 |
{
|
35 |
// Matches an optional namespace, required element or `*`
|
36 |
// $source = 'testns|testel';
|
vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php
CHANGED
@@ -34,7 +34,7 @@ class EmptyStringParser implements ParserInterface
|
|
34 |
/**
|
35 |
* {@inheritdoc}
|
36 |
*/
|
37 |
-
public function parse(
|
38 |
{
|
39 |
// Matches an empty string
|
40 |
if ('' == $source) {
|
34 |
/**
|
35 |
* {@inheritdoc}
|
36 |
*/
|
37 |
+
public function parse($source)
|
38 |
{
|
39 |
// Matches an empty string
|
40 |
if ('' == $source) {
|
vendor/symfony/css-selector/Parser/Shortcut/HashParser.php
CHANGED
@@ -31,7 +31,7 @@ class HashParser implements ParserInterface
|
|
31 |
/**
|
32 |
* {@inheritdoc}
|
33 |
*/
|
34 |
-
public function parse(
|
35 |
{
|
36 |
// Matches an optional namespace, optional element, and required id
|
37 |
// $source = 'test|input#ab6bd_field';
|
31 |
/**
|
32 |
* {@inheritdoc}
|
33 |
*/
|
34 |
+
public function parse($source)
|
35 |
{
|
36 |
// Matches an optional namespace, optional element, and required id
|
37 |
// $source = 'test|input#ab6bd_field';
|
vendor/symfony/css-selector/Parser/Token.php
CHANGED
@@ -23,46 +23,66 @@ namespace Symfony\Component\CssSelector\Parser;
|
|
23 |
*/
|
24 |
class Token
|
25 |
{
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
|
34 |
private $type;
|
35 |
private $value;
|
36 |
private $position;
|
37 |
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
39 |
{
|
40 |
$this->type = $type;
|
41 |
$this->value = $value;
|
42 |
$this->position = $position;
|
43 |
}
|
44 |
|
45 |
-
|
|
|
|
|
|
|
46 |
{
|
47 |
return $this->type;
|
48 |
}
|
49 |
|
50 |
-
|
|
|
|
|
|
|
51 |
{
|
52 |
return $this->value;
|
53 |
}
|
54 |
|
55 |
-
|
|
|
|
|
|
|
56 |
{
|
57 |
return $this->position;
|
58 |
}
|
59 |
|
60 |
-
|
|
|
|
|
|
|
61 |
{
|
62 |
return self::TYPE_FILE_END === $this->type;
|
63 |
}
|
64 |
|
65 |
-
|
|
|
|
|
|
|
66 |
{
|
67 |
if (self::TYPE_DELIMITER !== $this->type) {
|
68 |
return false;
|
@@ -75,32 +95,50 @@ class Token
|
|
75 |
return \in_array($this->value, $values);
|
76 |
}
|
77 |
|
78 |
-
|
|
|
|
|
|
|
79 |
{
|
80 |
return self::TYPE_WHITESPACE === $this->type;
|
81 |
}
|
82 |
|
83 |
-
|
|
|
|
|
|
|
84 |
{
|
85 |
return self::TYPE_IDENTIFIER === $this->type;
|
86 |
}
|
87 |
|
88 |
-
|
|
|
|
|
|
|
89 |
{
|
90 |
return self::TYPE_HASH === $this->type;
|
91 |
}
|
92 |
|
93 |
-
|
|
|
|
|
|
|
94 |
{
|
95 |
return self::TYPE_NUMBER === $this->type;
|
96 |
}
|
97 |
|
98 |
-
|
|
|
|
|
|
|
99 |
{
|
100 |
return self::TYPE_STRING === $this->type;
|
101 |
}
|
102 |
|
103 |
-
|
|
|
|
|
|
|
104 |
{
|
105 |
if ($this->value) {
|
106 |
return sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position);
|
23 |
*/
|
24 |
class Token
|
25 |
{
|
26 |
+
const TYPE_FILE_END = 'eof';
|
27 |
+
const TYPE_DELIMITER = 'delimiter';
|
28 |
+
const TYPE_WHITESPACE = 'whitespace';
|
29 |
+
const TYPE_IDENTIFIER = 'identifier';
|
30 |
+
const TYPE_HASH = 'hash';
|
31 |
+
const TYPE_NUMBER = 'number';
|
32 |
+
const TYPE_STRING = 'string';
|
33 |
|
34 |
private $type;
|
35 |
private $value;
|
36 |
private $position;
|
37 |
|
38 |
+
/**
|
39 |
+
* @param int $type
|
40 |
+
* @param string $value
|
41 |
+
* @param int $position
|
42 |
+
*/
|
43 |
+
public function __construct($type, $value, $position)
|
44 |
{
|
45 |
$this->type = $type;
|
46 |
$this->value = $value;
|
47 |
$this->position = $position;
|
48 |
}
|
49 |
|
50 |
+
/**
|
51 |
+
* @return int
|
52 |
+
*/
|
53 |
+
public function getType()
|
54 |
{
|
55 |
return $this->type;
|
56 |
}
|
57 |
|
58 |
+
/**
|
59 |
+
* @return string
|
60 |
+
*/
|
61 |
+
public function getValue()
|
62 |
{
|
63 |
return $this->value;
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
* @return int
|
68 |
+
*/
|
69 |
+
public function getPosition()
|
70 |
{
|
71 |
return $this->position;
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* @return bool
|
76 |
+
*/
|
77 |
+
public function isFileEnd()
|
78 |
{
|
79 |
return self::TYPE_FILE_END === $this->type;
|
80 |
}
|
81 |
|
82 |
+
/**
|
83 |
+
* @return bool
|
84 |
+
*/
|
85 |
+
public function isDelimiter(array $values = [])
|
86 |
{
|
87 |
if (self::TYPE_DELIMITER !== $this->type) {
|
88 |
return false;
|
95 |
return \in_array($this->value, $values);
|
96 |
}
|
97 |
|
98 |
+
/**
|
99 |
+
* @return bool
|
100 |
+
*/
|
101 |
+
public function isWhitespace()
|
102 |
{
|
103 |
return self::TYPE_WHITESPACE === $this->type;
|
104 |
}
|
105 |
|
106 |
+
/**
|
107 |
+
* @return bool
|
108 |
+
*/
|
109 |
+
public function isIdentifier()
|
110 |
{
|
111 |
return self::TYPE_IDENTIFIER === $this->type;
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* @return bool
|
116 |
+
*/
|
117 |
+
public function isHash()
|
118 |
{
|
119 |
return self::TYPE_HASH === $this->type;
|
120 |
}
|
121 |
|
122 |
+
/**
|
123 |
+
* @return bool
|
124 |
+
*/
|
125 |
+
public function isNumber()
|
126 |
{
|
127 |
return self::TYPE_NUMBER === $this->type;
|
128 |
}
|
129 |
|
130 |
+
/**
|
131 |
+
* @return bool
|
132 |
+
*/
|
133 |
+
public function isString()
|
134 |
{
|
135 |
return self::TYPE_STRING === $this->type;
|
136 |
}
|
137 |
|
138 |
+
/**
|
139 |
+
* @return string
|
140 |
+
*/
|
141 |
+
public function __toString()
|
142 |
{
|
143 |
if ($this->value) {
|
144 |
return sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position);
|
vendor/symfony/css-selector/Parser/TokenStream.php
CHANGED
@@ -56,7 +56,7 @@ class TokenStream
|
|
56 |
*
|
57 |
* @return $this
|
58 |
*/
|
59 |
-
public function push(Token $token)
|
60 |
{
|
61 |
$this->tokens[] = $token;
|
62 |
|
@@ -68,7 +68,7 @@ class TokenStream
|
|
68 |
*
|
69 |
* @return $this
|
70 |
*/
|
71 |
-
public function freeze()
|
72 |
{
|
73 |
return $this;
|
74 |
}
|
@@ -76,9 +76,11 @@ class TokenStream
|
|
76 |
/**
|
77 |
* Returns next token.
|
78 |
*
|
|
|
|
|
79 |
* @throws InternalErrorException If there is no more token
|
80 |
*/
|
81 |
-
public function getNext()
|
82 |
{
|
83 |
if ($this->peeking) {
|
84 |
$this->peeking = false;
|
@@ -96,8 +98,10 @@ class TokenStream
|
|
96 |
|
97 |
/**
|
98 |
* Returns peeked token.
|
|
|
|
|
99 |
*/
|
100 |
-
public function getPeek()
|
101 |
{
|
102 |
if (!$this->peeking) {
|
103 |
$this->peeked = $this->getNext();
|
@@ -112,7 +116,7 @@ class TokenStream
|
|
112 |
*
|
113 |
* @return Token[]
|
114 |
*/
|
115 |
-
public function getUsed()
|
116 |
{
|
117 |
return $this->used;
|
118 |
}
|
@@ -124,7 +128,7 @@ class TokenStream
|
|
124 |
*
|
125 |
* @throws SyntaxErrorException If next token is not an identifier
|
126 |
*/
|
127 |
-
public function getNextIdentifier()
|
128 |
{
|
129 |
$next = $this->getNext();
|
130 |
|
@@ -142,7 +146,7 @@ class TokenStream
|
|
142 |
*
|
143 |
* @throws SyntaxErrorException If next token is not an identifier or a star delimiter
|
144 |
*/
|
145 |
-
public function getNextIdentifierOrStar()
|
146 |
{
|
147 |
$next = $this->getNext();
|
148 |
|
56 |
*
|
57 |
* @return $this
|
58 |
*/
|
59 |
+
public function push(Token $token)
|
60 |
{
|
61 |
$this->tokens[] = $token;
|
62 |
|
68 |
*
|
69 |
* @return $this
|
70 |
*/
|
71 |
+
public function freeze()
|
72 |
{
|
73 |
return $this;
|
74 |
}
|
76 |
/**
|
77 |
* Returns next token.
|
78 |
*
|
79 |
+
* @return Token
|
80 |
+
*
|
81 |
* @throws InternalErrorException If there is no more token
|
82 |
*/
|
83 |
+
public function getNext()
|
84 |
{
|
85 |
if ($this->peeking) {
|
86 |
$this->peeking = false;
|
98 |
|
99 |
/**
|
100 |
* Returns peeked token.
|
101 |
+
*
|
102 |
+
* @return Token
|
103 |
*/
|
104 |
+
public function getPeek()
|
105 |
{
|
106 |
if (!$this->peeking) {
|
107 |
$this->peeked = $this->getNext();
|
116 |
*
|
117 |
* @return Token[]
|
118 |
*/
|
119 |
+
public function getUsed()
|
120 |
{
|
121 |
return $this->used;
|
122 |
}
|
128 |
*
|
129 |
* @throws SyntaxErrorException If next token is not an identifier
|
130 |
*/
|
131 |
+
public function getNextIdentifier()
|
132 |
{
|
133 |
$next = $this->getNext();
|
134 |
|
146 |
*
|
147 |
* @throws SyntaxErrorException If next token is not an identifier or a star delimiter
|
148 |
*/
|
149 |
+
public function getNextIdentifierOrStar()
|
150 |
{
|
151 |
$next = $this->getNext();
|
152 |
|
vendor/symfony/css-selector/Parser/Tokenizer/Tokenizer.php
CHANGED
@@ -50,8 +50,10 @@ class Tokenizer
|
|
50 |
|
51 |
/**
|
52 |
* Tokenize selector source code.
|
|
|
|
|
53 |
*/
|
54 |
-
public function tokenize(Reader $reader)
|
55 |
{
|
56 |
$stream = new TokenStream();
|
57 |
|
50 |
|
51 |
/**
|
52 |
* Tokenize selector source code.
|
53 |
+
*
|
54 |
+
* @return TokenStream
|
55 |
*/
|
56 |
+
public function tokenize(Reader $reader)
|
57 |
{
|
58 |
$stream = new TokenStream();
|
59 |
|
vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php
CHANGED
@@ -30,21 +30,36 @@ class TokenizerEscaping
|
|
30 |
$this->patterns = $patterns;
|
31 |
}
|
32 |
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
34 |
{
|
35 |
$value = $this->replaceUnicodeSequences($value);
|
36 |
|
37 |
return preg_replace($this->patterns->getSimpleEscapePattern(), '$1', $value);
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
41 |
{
|
42 |
$value = preg_replace($this->patterns->getNewLineEscapePattern(), '', $value);
|
43 |
|
44 |
return $this->escapeUnicode($value);
|
45 |
}
|
46 |
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
48 |
{
|
49 |
return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) {
|
50 |
$c = hexdec($match[1]);
|
30 |
$this->patterns = $patterns;
|
31 |
}
|
32 |
|
33 |
+
/**
|
34 |
+
* @param string $value
|
35 |
+
*
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
public function escapeUnicode($value)
|
39 |
{
|
40 |
$value = $this->replaceUnicodeSequences($value);
|
41 |
|
42 |
return preg_replace($this->patterns->getSimpleEscapePattern(), '$1', $value);
|
43 |
}
|
44 |
|
45 |
+
/**
|
46 |
+
* @param string $value
|
47 |
+
*
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function escapeUnicodeAndNewLine($value)
|
51 |
{
|
52 |
$value = preg_replace($this->patterns->getNewLineEscapePattern(), '', $value);
|
53 |
|
54 |
return $this->escapeUnicode($value);
|
55 |
}
|
56 |
|
57 |
+
/**
|
58 |
+
* @param string $value
|
59 |
+
*
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
private function replaceUnicodeSequences($value)
|
63 |
{
|
64 |
return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) {
|
65 |
$c = hexdec($match[1]);
|
vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php
CHANGED
@@ -52,37 +52,60 @@ class TokenizerPatterns
|
|
52 |
$this->quotedStringPattern = '([^\n\r\f%s]|'.$this->stringEscapePattern.')*';
|
53 |
}
|
54 |
|
55 |
-
|
|
|
|
|
|
|
56 |
{
|
57 |
return '~^'.$this->newLineEscapePattern.'~';
|
58 |
}
|
59 |
|
60 |
-
|
|
|
|
|
|
|
61 |
{
|
62 |
return '~^'.$this->simpleEscapePattern.'~';
|
63 |
}
|
64 |
|
65 |
-
|
|
|
|
|
|
|
66 |
{
|
67 |
return '~^'.$this->unicodeEscapePattern.'~i';
|
68 |
}
|
69 |
|
70 |
-
|
|
|
|
|
|
|
71 |
{
|
72 |
return '~^'.$this->identifierPattern.'~i';
|
73 |
}
|
74 |
|
75 |
-
|
|
|
|
|
|
|
76 |
{
|
77 |
return '~^'.$this->hashPattern.'~i';
|
78 |
}
|
79 |
|
80 |
-
|
|
|
|
|
|
|
81 |
{
|
82 |
return '~^'.$this->numberPattern.'~';
|
83 |
}
|
84 |
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
86 |
{
|
87 |
return '~^'.sprintf($this->quotedStringPattern, $quote).'~i';
|
88 |
}
|
52 |
$this->quotedStringPattern = '([^\n\r\f%s]|'.$this->stringEscapePattern.')*';
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
public function getNewLineEscapePattern()
|
59 |
{
|
60 |
return '~^'.$this->newLineEscapePattern.'~';
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* @return string
|
65 |
+
*/
|
66 |
+
public function getSimpleEscapePattern()
|
67 |
{
|
68 |
return '~^'.$this->simpleEscapePattern.'~';
|
69 |
}
|
70 |
|
71 |
+
/**
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
public function getUnicodeEscapePattern()
|
75 |
{
|
76 |
return '~^'.$this->unicodeEscapePattern.'~i';
|
77 |
}
|
78 |
|
79 |
+
/**
|
80 |
+
* @return string
|
81 |
+
*/
|
82 |
+
public function getIdentifierPattern()
|
83 |
{
|
84 |
return '~^'.$this->identifierPattern.'~i';
|
85 |
}
|
86 |
|
87 |
+
/**
|
88 |
+
* @return string
|
89 |
+
*/
|
90 |
+
public function getHashPattern()
|
91 |
{
|
92 |
return '~^'.$this->hashPattern.'~i';
|
93 |
}
|
94 |
|
95 |
+
/**
|
96 |
+
* @return string
|
97 |
+
*/
|
98 |
+
public function getNumberPattern()
|
99 |
{
|
100 |
return '~^'.$this->numberPattern.'~';
|
101 |
}
|
102 |
|
103 |
+
/**
|
104 |
+
* @param string $quote
|
105 |
+
*
|
106 |
+
* @return string
|
107 |
+
*/
|
108 |
+
public function getQuotedStringPattern($quote)
|
109 |
{
|
110 |
return '~^'.sprintf($this->quotedStringPattern, $quote).'~i';
|
111 |
}
|
vendor/symfony/css-selector/README.md
CHANGED
@@ -6,11 +6,11 @@ The CssSelector component converts CSS selectors to XPath expressions.
|
|
6 |
Resources
|
7 |
---------
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
|
15 |
Credits
|
16 |
-------
|
6 |
Resources
|
7 |
---------
|
8 |
|
9 |
+
* [Documentation](https://symfony.com/doc/current/components/css_selector.html)
|
10 |
+
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
11 |
+
* [Report issues](https://github.com/symfony/symfony/issues) and
|
12 |
+
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
13 |
+
in the [main Symfony repository](https://github.com/symfony/symfony)
|
14 |
|
15 |
Credits
|
16 |
-------
|
vendor/symfony/css-selector/Tests/CssSelectorConverterTest.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\CssSelectorConverter;
|
16 |
+
|
17 |
+
class CssSelectorConverterTest extends TestCase
|
18 |
+
{
|
19 |
+
public function testCssToXPath()
|
20 |
+
{
|
21 |
+
$converter = new CssSelectorConverter();
|
22 |
+
|
23 |
+
$this->assertEquals('descendant-or-self::*', $converter->toXPath(''));
|
24 |
+
$this->assertEquals('descendant-or-self::h1', $converter->toXPath('h1'));
|
25 |
+
$this->assertEquals("descendant-or-self::h1[@id = 'foo']", $converter->toXPath('h1#foo'));
|
26 |
+
$this->assertEquals("descendant-or-self::h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", $converter->toXPath('h1.foo'));
|
27 |
+
$this->assertEquals('descendant-or-self::foo:h1', $converter->toXPath('foo|h1'));
|
28 |
+
$this->assertEquals('descendant-or-self::h1', $converter->toXPath('H1'));
|
29 |
+
}
|
30 |
+
|
31 |
+
public function testCssToXPathXml()
|
32 |
+
{
|
33 |
+
$converter = new CssSelectorConverter(false);
|
34 |
+
|
35 |
+
$this->assertEquals('descendant-or-self::H1', $converter->toXPath('H1'));
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testParseExceptions()
|
39 |
+
{
|
40 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ParseException');
|
41 |
+
$this->expectExceptionMessage('Expected identifier, but <eof at 3> found.');
|
42 |
+
$converter = new CssSelectorConverter();
|
43 |
+
$converter->toXPath('h1:');
|
44 |
+
}
|
45 |
+
|
46 |
+
/** @dataProvider getCssToXPathWithoutPrefixTestData */
|
47 |
+
public function testCssToXPathWithoutPrefix($css, $xpath)
|
48 |
+
{
|
49 |
+
$converter = new CssSelectorConverter();
|
50 |
+
|
51 |
+
$this->assertEquals($xpath, $converter->toXPath($css, ''), '->parse() parses an input string and returns a node');
|
52 |
+
}
|
53 |
+
|
54 |
+
public function getCssToXPathWithoutPrefixTestData()
|
55 |
+
{
|
56 |
+
return [
|
57 |
+
['h1', 'h1'],
|
58 |
+
['foo|h1', 'foo:h1'],
|
59 |
+
['h1, h2, h3', 'h1 | h2 | h3'],
|
60 |
+
['h1:nth-child(3n+1)', "*/*[(name() = 'h1') and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"],
|
61 |
+
['h1 > p', 'h1/p'],
|
62 |
+
['h1#foo', "h1[@id = 'foo']"],
|
63 |
+
['h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"],
|
64 |
+
['h1[class*="foo bar"]', "h1[@class and contains(@class, 'foo bar')]"],
|
65 |
+
['h1[foo|class*="foo bar"]', "h1[@foo:class and contains(@foo:class, 'foo bar')]"],
|
66 |
+
['h1[class]', 'h1[@class]'],
|
67 |
+
['h1 .foo', "h1/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"],
|
68 |
+
['h1 #foo', "h1/descendant-or-self::*/*[@id = 'foo']"],
|
69 |
+
['h1 [class*=foo]', "h1/descendant-or-self::*/*[@class and contains(@class, 'foo')]"],
|
70 |
+
['div>.foo', "div/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"],
|
71 |
+
['div > .foo', "div/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"],
|
72 |
+
];
|
73 |
+
}
|
74 |
+
}
|
vendor/symfony/css-selector/Tests/Node/AbstractNodeTest.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\NodeInterface;
|
16 |
+
|
17 |
+
abstract class AbstractNodeTest extends TestCase
|
18 |
+
{
|
19 |
+
/** @dataProvider getToStringConversionTestData */
|
20 |
+
public function testToStringConversion(NodeInterface $node, $representation)
|
21 |
+
{
|
22 |
+
$this->assertEquals($representation, (string) $node);
|
23 |
+
}
|
24 |
+
|
25 |
+
/** @dataProvider getSpecificityValueTestData */
|
26 |
+
public function testSpecificityValue(NodeInterface $node, $value)
|
27 |
+
{
|
28 |
+
$this->assertEquals($value, $node->getSpecificity()->getValue());
|
29 |
+
}
|
30 |
+
|
31 |
+
abstract public function getToStringConversionTestData();
|
32 |
+
|
33 |
+
abstract public function getSpecificityValueTestData();
|
34 |
+
}
|
vendor/symfony/css-selector/Tests/Node/AttributeNodeTest.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\AttributeNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
16 |
+
|
17 |
+
class AttributeNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new AttributeNode(new ElementNode(), null, 'attribute', 'exists', null), 'Attribute[Element[*][attribute]]'],
|
23 |
+
[new AttributeNode(new ElementNode(), null, 'attribute', '$=', 'value'), "Attribute[Element[*][attribute $= 'value']]"],
|
24 |
+
[new AttributeNode(new ElementNode(), 'namespace', 'attribute', '$=', 'value'), "Attribute[Element[*][namespace|attribute $= 'value']]"],
|
25 |
+
];
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getSpecificityValueTestData()
|
29 |
+
{
|
30 |
+
return [
|
31 |
+
[new AttributeNode(new ElementNode(), null, 'attribute', 'exists', null), 10],
|
32 |
+
[new AttributeNode(new ElementNode(null, 'element'), null, 'attribute', 'exists', null), 11],
|
33 |
+
[new AttributeNode(new ElementNode(), null, 'attribute', '$=', 'value'), 10],
|
34 |
+
[new AttributeNode(new ElementNode(), 'namespace', 'attribute', '$=', 'value'), 10],
|
35 |
+
];
|
36 |
+
}
|
37 |
+
}
|
vendor/symfony/css-selector/Tests/Node/ClassNodeTest.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ClassNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
16 |
+
|
17 |
+
class ClassNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new ClassNode(new ElementNode(), 'class'), 'Class[Element[*].class]'],
|
23 |
+
];
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getSpecificityValueTestData()
|
27 |
+
{
|
28 |
+
return [
|
29 |
+
[new ClassNode(new ElementNode(), 'class'), 10],
|
30 |
+
[new ClassNode(new ElementNode(null, 'element'), 'class'), 11],
|
31 |
+
];
|
32 |
+
}
|
33 |
+
}
|
vendor/symfony/css-selector/Tests/Node/CombinedSelectorNodeTest.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\CombinedSelectorNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
16 |
+
|
17 |
+
class CombinedSelectorNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new CombinedSelectorNode(new ElementNode(), '>', new ElementNode()), 'CombinedSelector[Element[*] > Element[*]]'],
|
23 |
+
[new CombinedSelectorNode(new ElementNode(), ' ', new ElementNode()), 'CombinedSelector[Element[*] <followed> Element[*]]'],
|
24 |
+
];
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getSpecificityValueTestData()
|
28 |
+
{
|
29 |
+
return [
|
30 |
+
[new CombinedSelectorNode(new ElementNode(), '>', new ElementNode()), 0],
|
31 |
+
[new CombinedSelectorNode(new ElementNode(null, 'element'), '>', new ElementNode()), 1],
|
32 |
+
[new CombinedSelectorNode(new ElementNode(null, 'element'), '>', new ElementNode(null, 'element')), 2],
|
33 |
+
];
|
34 |
+
}
|
35 |
+
}
|
vendor/symfony/css-selector/Tests/Node/ElementNodeTest.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
15 |
+
|
16 |
+
class ElementNodeTest extends AbstractNodeTest
|
17 |
+
{
|
18 |
+
public function getToStringConversionTestData()
|
19 |
+
{
|
20 |
+
return [
|
21 |
+
[new ElementNode(), 'Element[*]'],
|
22 |
+
[new ElementNode(null, 'element'), 'Element[element]'],
|
23 |
+
[new ElementNode('namespace', 'element'), 'Element[namespace|element]'],
|
24 |
+
];
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getSpecificityValueTestData()
|
28 |
+
{
|
29 |
+
return [
|
30 |
+
[new ElementNode(), 0],
|
31 |
+
[new ElementNode(null, 'element'), 1],
|
32 |
+
[new ElementNode('namespace', 'element'), 1],
|
33 |
+
];
|
34 |
+
}
|
35 |
+
}
|
vendor/symfony/css-selector/Tests/Node/FunctionNodeTest.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\FunctionNode;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
17 |
+
|
18 |
+
class FunctionNodeTest extends AbstractNodeTest
|
19 |
+
{
|
20 |
+
public function getToStringConversionTestData()
|
21 |
+
{
|
22 |
+
return [
|
23 |
+
[new FunctionNode(new ElementNode(), 'function'), 'Function[Element[*]:function()]'],
|
24 |
+
[new FunctionNode(new ElementNode(), 'function', [
|
25 |
+
new Token(Token::TYPE_IDENTIFIER, 'value', 0),
|
26 |
+
]), "Function[Element[*]:function(['value'])]"],
|
27 |
+
[new FunctionNode(new ElementNode(), 'function', [
|
28 |
+
new Token(Token::TYPE_STRING, 'value1', 0),
|
29 |
+
new Token(Token::TYPE_NUMBER, 'value2', 0),
|
30 |
+
]), "Function[Element[*]:function(['value1', 'value2'])]"],
|
31 |
+
];
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getSpecificityValueTestData()
|
35 |
+
{
|
36 |
+
return [
|
37 |
+
[new FunctionNode(new ElementNode(), 'function'), 10],
|
38 |
+
[new FunctionNode(new ElementNode(), 'function', [
|
39 |
+
new Token(Token::TYPE_IDENTIFIER, 'value', 0),
|
40 |
+
]), 10],
|
41 |
+
[new FunctionNode(new ElementNode(), 'function', [
|
42 |
+
new Token(Token::TYPE_STRING, 'value1', 0),
|
43 |
+
new Token(Token::TYPE_NUMBER, 'value2', 0),
|
44 |
+
]), 10],
|
45 |
+
];
|
46 |
+
}
|
47 |
+
}
|
vendor/symfony/css-selector/Tests/Node/HashNodeTest.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\HashNode;
|
16 |
+
|
17 |
+
class HashNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new HashNode(new ElementNode(), 'id'), 'Hash[Element[*]#id]'],
|
23 |
+
];
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getSpecificityValueTestData()
|
27 |
+
{
|
28 |
+
return [
|
29 |
+
[new HashNode(new ElementNode(), 'id'), 100],
|
30 |
+
[new HashNode(new ElementNode(null, 'id'), 'class'), 101],
|
31 |
+
];
|
32 |
+
}
|
33 |
+
}
|
vendor/symfony/css-selector/Tests/Node/NegationNodeTest.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ClassNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
16 |
+
use Symfony\Component\CssSelector\Node\NegationNode;
|
17 |
+
|
18 |
+
class NegationNodeTest extends AbstractNodeTest
|
19 |
+
{
|
20 |
+
public function getToStringConversionTestData()
|
21 |
+
{
|
22 |
+
return [
|
23 |
+
[new NegationNode(new ElementNode(), new ClassNode(new ElementNode(), 'class')), 'Negation[Element[*]:not(Class[Element[*].class])]'],
|
24 |
+
];
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getSpecificityValueTestData()
|
28 |
+
{
|
29 |
+
return [
|
30 |
+
[new NegationNode(new ElementNode(), new ClassNode(new ElementNode(), 'class')), 10],
|
31 |
+
];
|
32 |
+
}
|
33 |
+
}
|
vendor/symfony/css-selector/Tests/Node/PseudoNodeTest.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\PseudoNode;
|
16 |
+
|
17 |
+
class PseudoNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new PseudoNode(new ElementNode(), 'pseudo'), 'Pseudo[Element[*]:pseudo]'],
|
23 |
+
];
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getSpecificityValueTestData()
|
27 |
+
{
|
28 |
+
return [
|
29 |
+
[new PseudoNode(new ElementNode(), 'pseudo'), 10],
|
30 |
+
];
|
31 |
+
}
|
32 |
+
}
|
vendor/symfony/css-selector/Tests/Node/SelectorNodeTest.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
15 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
16 |
+
|
17 |
+
class SelectorNodeTest extends AbstractNodeTest
|
18 |
+
{
|
19 |
+
public function getToStringConversionTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[new SelectorNode(new ElementNode()), 'Selector[Element[*]]'],
|
23 |
+
[new SelectorNode(new ElementNode(), 'pseudo'), 'Selector[Element[*]::pseudo]'],
|
24 |
+
];
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getSpecificityValueTestData()
|
28 |
+
{
|
29 |
+
return [
|
30 |
+
[new SelectorNode(new ElementNode()), 0],
|
31 |
+
[new SelectorNode(new ElementNode(), 'pseudo'), 1],
|
32 |
+
];
|
33 |
+
}
|
34 |
+
}
|
vendor/symfony/css-selector/Tests/Node/SpecificityTest.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Node;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\Specificity;
|
16 |
+
|
17 |
+
class SpecificityTest extends TestCase
|
18 |
+
{
|
19 |
+
/** @dataProvider getValueTestData */
|
20 |
+
public function testValue(Specificity $specificity, $value)
|
21 |
+
{
|
22 |
+
$this->assertEquals($value, $specificity->getValue());
|
23 |
+
}
|
24 |
+
|
25 |
+
/** @dataProvider getValueTestData */
|
26 |
+
public function testPlusValue(Specificity $specificity, $value)
|
27 |
+
{
|
28 |
+
$this->assertEquals($value + 123, $specificity->plus(new Specificity(1, 2, 3))->getValue());
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getValueTestData()
|
32 |
+
{
|
33 |
+
return [
|
34 |
+
[new Specificity(0, 0, 0), 0],
|
35 |
+
[new Specificity(0, 0, 2), 2],
|
36 |
+
[new Specificity(0, 3, 0), 30],
|
37 |
+
[new Specificity(4, 0, 0), 400],
|
38 |
+
[new Specificity(4, 3, 2), 432],
|
39 |
+
];
|
40 |
+
}
|
41 |
+
|
42 |
+
/** @dataProvider getCompareTestData */
|
43 |
+
public function testCompareTo(Specificity $a, Specificity $b, $result)
|
44 |
+
{
|
45 |
+
$this->assertEquals($result, $a->compareTo($b));
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getCompareTestData()
|
49 |
+
{
|
50 |
+
return [
|
51 |
+
[new Specificity(0, 0, 0), new Specificity(0, 0, 0), 0],
|
52 |
+
[new Specificity(0, 0, 1), new Specificity(0, 0, 1), 0],
|
53 |
+
[new Specificity(0, 0, 2), new Specificity(0, 0, 1), 1],
|
54 |
+
[new Specificity(0, 0, 2), new Specificity(0, 0, 3), -1],
|
55 |
+
[new Specificity(0, 4, 0), new Specificity(0, 4, 0), 0],
|
56 |
+
[new Specificity(0, 6, 0), new Specificity(0, 5, 11), 1],
|
57 |
+
[new Specificity(0, 7, 0), new Specificity(0, 8, 0), -1],
|
58 |
+
[new Specificity(9, 0, 0), new Specificity(9, 0, 0), 0],
|
59 |
+
[new Specificity(11, 0, 0), new Specificity(10, 11, 0), 1],
|
60 |
+
[new Specificity(12, 11, 0), new Specificity(13, 0, 0), -1],
|
61 |
+
];
|
62 |
+
}
|
63 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/AbstractHandlerTest.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Reader;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
17 |
+
use Symfony\Component\CssSelector\Parser\TokenStream;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @author Jean-François Simon <contact@jfsimon.fr>
|
21 |
+
*/
|
22 |
+
abstract class AbstractHandlerTest extends TestCase
|
23 |
+
{
|
24 |
+
/** @dataProvider getHandleValueTestData */
|
25 |
+
public function testHandleValue($value, Token $expectedToken, $remainingContent)
|
26 |
+
{
|
27 |
+
$reader = new Reader($value);
|
28 |
+
$stream = new TokenStream();
|
29 |
+
|
30 |
+
$this->assertTrue($this->generateHandler()->handle($reader, $stream));
|
31 |
+
$this->assertEquals($expectedToken, $stream->getNext());
|
32 |
+
$this->assertRemainingContent($reader, $remainingContent);
|
33 |
+
}
|
34 |
+
|
35 |
+
/** @dataProvider getDontHandleValueTestData */
|
36 |
+
public function testDontHandleValue($value)
|
37 |
+
{
|
38 |
+
$reader = new Reader($value);
|
39 |
+
$stream = new TokenStream();
|
40 |
+
|
41 |
+
$this->assertFalse($this->generateHandler()->handle($reader, $stream));
|
42 |
+
$this->assertStreamEmpty($stream);
|
43 |
+
$this->assertRemainingContent($reader, $value);
|
44 |
+
}
|
45 |
+
|
46 |
+
abstract public function getHandleValueTestData();
|
47 |
+
|
48 |
+
abstract public function getDontHandleValueTestData();
|
49 |
+
|
50 |
+
abstract protected function generateHandler();
|
51 |
+
|
52 |
+
protected function assertStreamEmpty(TokenStream $stream)
|
53 |
+
{
|
54 |
+
$property = new \ReflectionProperty($stream, 'tokens');
|
55 |
+
$property->setAccessible(true);
|
56 |
+
|
57 |
+
$this->assertEquals([], $property->getValue($stream));
|
58 |
+
}
|
59 |
+
|
60 |
+
protected function assertRemainingContent(Reader $reader, $remainingContent)
|
61 |
+
{
|
62 |
+
if ('' === $remainingContent) {
|
63 |
+
$this->assertEquals(0, $reader->getRemainingLength());
|
64 |
+
$this->assertTrue($reader->isEOF());
|
65 |
+
} else {
|
66 |
+
$this->assertEquals(\strlen($remainingContent), $reader->getRemainingLength());
|
67 |
+
$this->assertEquals(0, $reader->getOffset($remainingContent));
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/CommentHandlerTest.php
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\CommentHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Reader;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
17 |
+
use Symfony\Component\CssSelector\Parser\TokenStream;
|
18 |
+
|
19 |
+
class CommentHandlerTest extends AbstractHandlerTest
|
20 |
+
{
|
21 |
+
/** @dataProvider getHandleValueTestData */
|
22 |
+
public function testHandleValue($value, Token $unusedArgument, $remainingContent)
|
23 |
+
{
|
24 |
+
$reader = new Reader($value);
|
25 |
+
$stream = new TokenStream();
|
26 |
+
|
27 |
+
$this->assertTrue($this->generateHandler()->handle($reader, $stream));
|
28 |
+
// comments are ignored (not pushed as token in stream)
|
29 |
+
$this->assertStreamEmpty($stream);
|
30 |
+
$this->assertRemainingContent($reader, $remainingContent);
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getHandleValueTestData()
|
34 |
+
{
|
35 |
+
return [
|
36 |
+
// 2nd argument only exists for inherited method compatibility
|
37 |
+
['/* comment */', new Token(null, null, null), ''],
|
38 |
+
['/* comment */foo', new Token(null, null, null), 'foo'],
|
39 |
+
];
|
40 |
+
}
|
41 |
+
|
42 |
+
public function getDontHandleValueTestData()
|
43 |
+
{
|
44 |
+
return [
|
45 |
+
['>'],
|
46 |
+
['+'],
|
47 |
+
[' '],
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
51 |
+
protected function generateHandler()
|
52 |
+
{
|
53 |
+
return new CommentHandler();
|
54 |
+
}
|
55 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/HashHandlerTest.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\HashHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerEscaping;
|
17 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerPatterns;
|
18 |
+
|
19 |
+
class HashHandlerTest extends AbstractHandlerTest
|
20 |
+
{
|
21 |
+
public function getHandleValueTestData()
|
22 |
+
{
|
23 |
+
return [
|
24 |
+
['#id', new Token(Token::TYPE_HASH, 'id', 0), ''],
|
25 |
+
['#123', new Token(Token::TYPE_HASH, '123', 0), ''],
|
26 |
+
|
27 |
+
['#id.class', new Token(Token::TYPE_HASH, 'id', 0), '.class'],
|
28 |
+
['#id element', new Token(Token::TYPE_HASH, 'id', 0), ' element'],
|
29 |
+
];
|
30 |
+
}
|
31 |
+
|
32 |
+
public function getDontHandleValueTestData()
|
33 |
+
{
|
34 |
+
return [
|
35 |
+
['id'],
|
36 |
+
['123'],
|
37 |
+
['<'],
|
38 |
+
['<'],
|
39 |
+
['#'],
|
40 |
+
];
|
41 |
+
}
|
42 |
+
|
43 |
+
protected function generateHandler()
|
44 |
+
{
|
45 |
+
$patterns = new TokenizerPatterns();
|
46 |
+
|
47 |
+
return new HashHandler($patterns, new TokenizerEscaping($patterns));
|
48 |
+
}
|
49 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/IdentifierHandlerTest.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\IdentifierHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerEscaping;
|
17 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerPatterns;
|
18 |
+
|
19 |
+
class IdentifierHandlerTest extends AbstractHandlerTest
|
20 |
+
{
|
21 |
+
public function getHandleValueTestData()
|
22 |
+
{
|
23 |
+
return [
|
24 |
+
['foo', new Token(Token::TYPE_IDENTIFIER, 'foo', 0), ''],
|
25 |
+
['foo|bar', new Token(Token::TYPE_IDENTIFIER, 'foo', 0), '|bar'],
|
26 |
+
['foo.class', new Token(Token::TYPE_IDENTIFIER, 'foo', 0), '.class'],
|
27 |
+
['foo[attr]', new Token(Token::TYPE_IDENTIFIER, 'foo', 0), '[attr]'],
|
28 |
+
['foo bar', new Token(Token::TYPE_IDENTIFIER, 'foo', 0), ' bar'],
|
29 |
+
];
|
30 |
+
}
|
31 |
+
|
32 |
+
public function getDontHandleValueTestData()
|
33 |
+
{
|
34 |
+
return [
|
35 |
+
['>'],
|
36 |
+
['+'],
|
37 |
+
[' '],
|
38 |
+
['*|foo'],
|
39 |
+
['/* comment */'],
|
40 |
+
];
|
41 |
+
}
|
42 |
+
|
43 |
+
protected function generateHandler()
|
44 |
+
{
|
45 |
+
$patterns = new TokenizerPatterns();
|
46 |
+
|
47 |
+
return new IdentifierHandler($patterns, new TokenizerEscaping($patterns));
|
48 |
+
}
|
49 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/NumberHandlerTest.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\NumberHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerPatterns;
|
17 |
+
|
18 |
+
class NumberHandlerTest extends AbstractHandlerTest
|
19 |
+
{
|
20 |
+
public function getHandleValueTestData()
|
21 |
+
{
|
22 |
+
return [
|
23 |
+
['12', new Token(Token::TYPE_NUMBER, '12', 0), ''],
|
24 |
+
['12.34', new Token(Token::TYPE_NUMBER, '12.34', 0), ''],
|
25 |
+
['+12.34', new Token(Token::TYPE_NUMBER, '+12.34', 0), ''],
|
26 |
+
['-12.34', new Token(Token::TYPE_NUMBER, '-12.34', 0), ''],
|
27 |
+
|
28 |
+
['12 arg', new Token(Token::TYPE_NUMBER, '12', 0), ' arg'],
|
29 |
+
['12]', new Token(Token::TYPE_NUMBER, '12', 0), ']'],
|
30 |
+
];
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getDontHandleValueTestData()
|
34 |
+
{
|
35 |
+
return [
|
36 |
+
['hello'],
|
37 |
+
['>'],
|
38 |
+
['+'],
|
39 |
+
[' '],
|
40 |
+
['/* comment */'],
|
41 |
+
];
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function generateHandler()
|
45 |
+
{
|
46 |
+
$patterns = new TokenizerPatterns();
|
47 |
+
|
48 |
+
return new NumberHandler($patterns);
|
49 |
+
}
|
50 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/StringHandlerTest.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\StringHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerEscaping;
|
17 |
+
use Symfony\Component\CssSelector\Parser\Tokenizer\TokenizerPatterns;
|
18 |
+
|
19 |
+
class StringHandlerTest extends AbstractHandlerTest
|
20 |
+
{
|
21 |
+
public function getHandleValueTestData()
|
22 |
+
{
|
23 |
+
return [
|
24 |
+
['"hello"', new Token(Token::TYPE_STRING, 'hello', 1), ''],
|
25 |
+
['"1"', new Token(Token::TYPE_STRING, '1', 1), ''],
|
26 |
+
['" "', new Token(Token::TYPE_STRING, ' ', 1), ''],
|
27 |
+
['""', new Token(Token::TYPE_STRING, '', 1), ''],
|
28 |
+
["'hello'", new Token(Token::TYPE_STRING, 'hello', 1), ''],
|
29 |
+
|
30 |
+
["'foo'bar", new Token(Token::TYPE_STRING, 'foo', 1), 'bar'],
|
31 |
+
];
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getDontHandleValueTestData()
|
35 |
+
{
|
36 |
+
return [
|
37 |
+
['hello'],
|
38 |
+
['>'],
|
39 |
+
['1'],
|
40 |
+
[' '],
|
41 |
+
];
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function generateHandler()
|
45 |
+
{
|
46 |
+
$patterns = new TokenizerPatterns();
|
47 |
+
|
48 |
+
return new StringHandler($patterns, new TokenizerEscaping($patterns));
|
49 |
+
}
|
50 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Handler/WhitespaceHandlerTest.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Handler;
|
13 |
+
|
14 |
+
use Symfony\Component\CssSelector\Parser\Handler\WhitespaceHandler;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
|
17 |
+
class WhitespaceHandlerTest extends AbstractHandlerTest
|
18 |
+
{
|
19 |
+
public function getHandleValueTestData()
|
20 |
+
{
|
21 |
+
return [
|
22 |
+
[' ', new Token(Token::TYPE_WHITESPACE, ' ', 0), ''],
|
23 |
+
["\n", new Token(Token::TYPE_WHITESPACE, "\n", 0), ''],
|
24 |
+
["\t", new Token(Token::TYPE_WHITESPACE, "\t", 0), ''],
|
25 |
+
|
26 |
+
[' foo', new Token(Token::TYPE_WHITESPACE, ' ', 0), 'foo'],
|
27 |
+
[' .foo', new Token(Token::TYPE_WHITESPACE, ' ', 0), '.foo'],
|
28 |
+
];
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getDontHandleValueTestData()
|
32 |
+
{
|
33 |
+
return [
|
34 |
+
['>'],
|
35 |
+
['1'],
|
36 |
+
['a'],
|
37 |
+
];
|
38 |
+
}
|
39 |
+
|
40 |
+
protected function generateHandler()
|
41 |
+
{
|
42 |
+
return new WhitespaceHandler();
|
43 |
+
}
|
44 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/ParserTest.php
ADDED
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Exception\SyntaxErrorException;
|
16 |
+
use Symfony\Component\CssSelector\Node\FunctionNode;
|
17 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
18 |
+
use Symfony\Component\CssSelector\Parser\Parser;
|
19 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
20 |
+
|
21 |
+
class ParserTest extends TestCase
|
22 |
+
{
|
23 |
+
/** @dataProvider getParserTestData */
|
24 |
+
public function testParser($source, $representation)
|
25 |
+
{
|
26 |
+
$parser = new Parser();
|
27 |
+
|
28 |
+
$this->assertEquals($representation, array_map(function (SelectorNode $node) {
|
29 |
+
return (string) $node->getTree();
|
30 |
+
}, $parser->parse($source)));
|
31 |
+
}
|
32 |
+
|
33 |
+
/** @dataProvider getParserExceptionTestData */
|
34 |
+
public function testParserException($source, $message)
|
35 |
+
{
|
36 |
+
$parser = new Parser();
|
37 |
+
|
38 |
+
try {
|
39 |
+
$parser->parse($source);
|
40 |
+
$this->fail('Parser should throw a SyntaxErrorException.');
|
41 |
+
} catch (SyntaxErrorException $e) {
|
42 |
+
$this->assertEquals($message, $e->getMessage());
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/** @dataProvider getPseudoElementsTestData */
|
47 |
+
public function testPseudoElements($source, $element, $pseudo)
|
48 |
+
{
|
49 |
+
$parser = new Parser();
|
50 |
+
$selectors = $parser->parse($source);
|
51 |
+
$this->assertCount(1, $selectors);
|
52 |
+
|
53 |
+
/** @var SelectorNode $selector */
|
54 |
+
$selector = $selectors[0];
|
55 |
+
$this->assertEquals($element, (string) $selector->getTree());
|
56 |
+
$this->assertEquals($pseudo, (string) $selector->getPseudoElement());
|
57 |
+
}
|
58 |
+
|
59 |
+
/** @dataProvider getSpecificityTestData */
|
60 |
+
public function testSpecificity($source, $value)
|
61 |
+
{
|
62 |
+
$parser = new Parser();
|
63 |
+
$selectors = $parser->parse($source);
|
64 |
+
$this->assertCount(1, $selectors);
|
65 |
+
|
66 |
+
/** @var SelectorNode $selector */
|
67 |
+
$selector = $selectors[0];
|
68 |
+
$this->assertEquals($value, $selector->getSpecificity()->getValue());
|
69 |
+
}
|
70 |
+
|
71 |
+
/** @dataProvider getParseSeriesTestData */
|
72 |
+
public function testParseSeries($series, $a, $b)
|
73 |
+
{
|
74 |
+
$parser = new Parser();
|
75 |
+
$selectors = $parser->parse(sprintf(':nth-child(%s)', $series));
|
76 |
+
$this->assertCount(1, $selectors);
|
77 |
+
|
78 |
+
/** @var FunctionNode $function */
|
79 |
+
$function = $selectors[0]->getTree();
|
80 |
+
$this->assertEquals([$a, $b], Parser::parseSeries($function->getArguments()));
|
81 |
+
}
|
82 |
+
|
83 |
+
/** @dataProvider getParseSeriesExceptionTestData */
|
84 |
+
public function testParseSeriesException($series)
|
85 |
+
{
|
86 |
+
$parser = new Parser();
|
87 |
+
$selectors = $parser->parse(sprintf(':nth-child(%s)', $series));
|
88 |
+
$this->assertCount(1, $selectors);
|
89 |
+
|
90 |
+
/** @var FunctionNode $function */
|
91 |
+
$function = $selectors[0]->getTree();
|
92 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\SyntaxErrorException');
|
93 |
+
Parser::parseSeries($function->getArguments());
|
94 |
+
}
|
95 |
+
|
96 |
+
public function getParserTestData()
|
97 |
+
{
|
98 |
+
return [
|
99 |
+
['*', ['Element[*]']],
|
100 |
+
['*|*', ['Element[*]']],
|
101 |
+
['*|foo', ['Element[foo]']],
|
102 |
+
['foo|*', ['Element[foo|*]']],
|
103 |
+
['foo|bar', ['Element[foo|bar]']],
|
104 |
+
['#foo#bar', ['Hash[Hash[Element[*]#foo]#bar]']],
|
105 |
+
['div>.foo', ['CombinedSelector[Element[div] > Class[Element[*].foo]]']],
|
106 |
+
['div> .foo', ['CombinedSelector[Element[div] > Class[Element[*].foo]]']],
|
107 |
+
['div >.foo', ['CombinedSelector[Element[div] > Class[Element[*].foo]]']],
|
108 |
+
['div > .foo', ['CombinedSelector[Element[div] > Class[Element[*].foo]]']],
|
109 |
+
["div \n> \t \t .foo", ['CombinedSelector[Element[div] > Class[Element[*].foo]]']],
|
110 |
+
['td.foo,.bar', ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
111 |
+
['td.foo, .bar', ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
112 |
+
["td.foo\t\r\n\f ,\t\r\n\f .bar", ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
113 |
+
['td.foo,.bar', ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
114 |
+
['td.foo, .bar', ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
115 |
+
["td.foo\t\r\n\f ,\t\r\n\f .bar", ['Class[Element[td].foo]', 'Class[Element[*].bar]']],
|
116 |
+
['div, td.foo, div.bar span', ['Element[div]', 'Class[Element[td].foo]', 'CombinedSelector[Class[Element[div].bar] <followed> Element[span]]']],
|
117 |
+
['div > p', ['CombinedSelector[Element[div] > Element[p]]']],
|
118 |
+
['td:first', ['Pseudo[Element[td]:first]']],
|
119 |
+
['td :first', ['CombinedSelector[Element[td] <followed> Pseudo[Element[*]:first]]']],
|
120 |
+
['a[name]', ['Attribute[Element[a][name]]']],
|
121 |
+
["a[ name\t]", ['Attribute[Element[a][name]]']],
|
122 |
+
['a [name]', ['CombinedSelector[Element[a] <followed> Attribute[Element[*][name]]]']],
|
123 |
+
['[name="foo"]', ["Attribute[Element[*][name = 'foo']]"]],
|
124 |
+
["[name='foo[1]']", ["Attribute[Element[*][name = 'foo[1]']]"]],
|
125 |
+
["[name='foo[0][bar]']", ["Attribute[Element[*][name = 'foo[0][bar]']]"]],
|
126 |
+
['a[rel="include"]', ["Attribute[Element[a][rel = 'include']]"]],
|
127 |
+
['a[rel = include]', ["Attribute[Element[a][rel = 'include']]"]],
|
128 |
+
["a[hreflang |= 'en']", ["Attribute[Element[a][hreflang |= 'en']]"]],
|
129 |
+
['a[hreflang|=en]', ["Attribute[Element[a][hreflang |= 'en']]"]],
|
130 |
+
['div:nth-child(10)', ["Function[Element[div]:nth-child(['10'])]"]],
|
131 |
+
[':nth-child(2n+2)', ["Function[Element[*]:nth-child(['2', 'n', '+2'])]"]],
|
132 |
+
['div:nth-of-type(10)', ["Function[Element[div]:nth-of-type(['10'])]"]],
|
133 |
+
['div div:nth-of-type(10) .aclass', ["CombinedSelector[CombinedSelector[Element[div] <followed> Function[Element[div]:nth-of-type(['10'])]] <followed> Class[Element[*].aclass]]"]],
|
134 |
+
['label:only', ['Pseudo[Element[label]:only]']],
|
135 |
+
['a:lang(fr)', ["Function[Element[a]:lang(['fr'])]"]],
|
136 |
+
['div:contains("foo")', ["Function[Element[div]:contains(['foo'])]"]],
|
137 |
+
['div#foobar', ['Hash[Element[div]#foobar]']],
|
138 |
+
['div:not(div.foo)', ['Negation[Element[div]:not(Class[Element[div].foo])]']],
|
139 |
+
['td ~ th', ['CombinedSelector[Element[td] ~ Element[th]]']],
|
140 |
+
['.foo[data-bar][data-baz=0]', ["Attribute[Attribute[Class[Element[*].foo][data-bar]][data-baz = '0']]"]],
|
141 |
+
];
|
142 |
+
}
|
143 |
+
|
144 |
+
public function getParserExceptionTestData()
|
145 |
+
{
|
146 |
+
return [
|
147 |
+
['attributes(href)/html/body/a', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '(', 10))->getMessage()],
|
148 |
+
['attributes(href)', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '(', 10))->getMessage()],
|
149 |
+
['html/body/a', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '/', 4))->getMessage()],
|
150 |
+
[' ', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_FILE_END, '', 1))->getMessage()],
|
151 |
+
['div, ', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_FILE_END, '', 5))->getMessage()],
|
152 |
+
[' , div', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, ',', 1))->getMessage()],
|
153 |
+
['p, , div', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, ',', 3))->getMessage()],
|
154 |
+
['div > ', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_FILE_END, '', 6))->getMessage()],
|
155 |
+
[' > div', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '>', 2))->getMessage()],
|
156 |
+
['foo|#bar', SyntaxErrorException::unexpectedToken('identifier or "*"', new Token(Token::TYPE_HASH, 'bar', 4))->getMessage()],
|
157 |
+
['#.foo', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '#', 0))->getMessage()],
|
158 |
+
['.#foo', SyntaxErrorException::unexpectedToken('identifier', new Token(Token::TYPE_HASH, 'foo', 1))->getMessage()],
|
159 |
+
[':#foo', SyntaxErrorException::unexpectedToken('identifier', new Token(Token::TYPE_HASH, 'foo', 1))->getMessage()],
|
160 |
+
['[*]', SyntaxErrorException::unexpectedToken('"|"', new Token(Token::TYPE_DELIMITER, ']', 2))->getMessage()],
|
161 |
+
['[foo|]', SyntaxErrorException::unexpectedToken('identifier', new Token(Token::TYPE_DELIMITER, ']', 5))->getMessage()],
|
162 |
+
['[#]', SyntaxErrorException::unexpectedToken('identifier or "*"', new Token(Token::TYPE_DELIMITER, '#', 1))->getMessage()],
|
163 |
+
['[foo=#]', SyntaxErrorException::unexpectedToken('string or identifier', new Token(Token::TYPE_DELIMITER, '#', 5))->getMessage()],
|
164 |
+
[':nth-child()', SyntaxErrorException::unexpectedToken('at least one argument', new Token(Token::TYPE_DELIMITER, ')', 11))->getMessage()],
|
165 |
+
['[href]a', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_IDENTIFIER, 'a', 6))->getMessage()],
|
166 |
+
['[rel:stylesheet]', SyntaxErrorException::unexpectedToken('operator', new Token(Token::TYPE_DELIMITER, ':', 4))->getMessage()],
|
167 |
+
['[rel=stylesheet', SyntaxErrorException::unexpectedToken('"]"', new Token(Token::TYPE_FILE_END, '', 15))->getMessage()],
|
168 |
+
[':lang(fr', SyntaxErrorException::unexpectedToken('an argument', new Token(Token::TYPE_FILE_END, '', 8))->getMessage()],
|
169 |
+
[':contains("foo', SyntaxErrorException::unclosedString(10)->getMessage()],
|
170 |
+
['foo!', SyntaxErrorException::unexpectedToken('selector', new Token(Token::TYPE_DELIMITER, '!', 3))->getMessage()],
|
171 |
+
];
|
172 |
+
}
|
173 |
+
|
174 |
+
public function getPseudoElementsTestData()
|
175 |
+
{
|
176 |
+
return [
|
177 |
+
['foo', 'Element[foo]', ''],
|
178 |
+
['*', 'Element[*]', ''],
|
179 |
+
[':empty', 'Pseudo[Element[*]:empty]', ''],
|
180 |
+
[':BEfore', 'Element[*]', 'before'],
|
181 |
+
[':aftER', 'Element[*]', 'after'],
|
182 |
+
[':First-Line', 'Element[*]', 'first-line'],
|
183 |
+
[':First-Letter', 'Element[*]', 'first-letter'],
|
184 |
+
['::befoRE', 'Element[*]', 'before'],
|
185 |
+
['::AFter', 'Element[*]', 'after'],
|
186 |
+
['::firsT-linE', 'Element[*]', 'first-line'],
|
187 |
+
['::firsT-letteR', 'Element[*]', 'first-letter'],
|
188 |
+
['::Selection', 'Element[*]', 'selection'],
|
189 |
+
['foo:after', 'Element[foo]', 'after'],
|
190 |
+
['foo::selection', 'Element[foo]', 'selection'],
|
191 |
+
['lorem#ipsum ~ a#b.c[href]:empty::selection', 'CombinedSelector[Hash[Element[lorem]#ipsum] ~ Pseudo[Attribute[Class[Hash[Element[a]#b].c][href]]:empty]]', 'selection'],
|
192 |
+
['video::-webkit-media-controls', 'Element[video]', '-webkit-media-controls'],
|
193 |
+
];
|
194 |
+
}
|
195 |
+
|
196 |
+
public function getSpecificityTestData()
|
197 |
+
{
|
198 |
+
return [
|
199 |
+
['*', 0],
|
200 |
+
[' foo', 1],
|
201 |
+
[':empty ', 10],
|
202 |
+
[':before', 1],
|
203 |
+
['*:before', 1],
|
204 |
+
[':nth-child(2)', 10],
|
205 |
+
['.bar', 10],
|
206 |
+
['[baz]', 10],
|
207 |
+
['[baz="4"]', 10],
|
208 |
+
['[baz^="4"]', 10],
|
209 |
+
['#lipsum', 100],
|
210 |
+
[':not(*)', 0],
|
211 |
+
[':not(foo)', 1],
|
212 |
+
[':not(.foo)', 10],
|
213 |
+
[':not([foo])', 10],
|
214 |
+
[':not(:empty)', 10],
|
215 |
+
[':not(#foo)', 100],
|
216 |
+
['foo:empty', 11],
|
217 |
+
['foo:before', 2],
|
218 |
+
['foo::before', 2],
|
219 |
+
['foo:empty::before', 12],
|
220 |
+
['#lorem + foo#ipsum:first-child > bar:first-line', 213],
|
221 |
+
];
|
222 |
+
}
|
223 |
+
|
224 |
+
public function getParseSeriesTestData()
|
225 |
+
{
|
226 |
+
return [
|
227 |
+
['1n+3', 1, 3],
|
228 |
+
['1n +3', 1, 3],
|
229 |
+
['1n + 3', 1, 3],
|
230 |
+
['1n+ 3', 1, 3],
|
231 |
+
['1n-3', 1, -3],
|
232 |
+
['1n -3', 1, -3],
|
233 |
+
['1n - 3', 1, -3],
|
234 |
+
['1n- 3', 1, -3],
|
235 |
+
['n-5', 1, -5],
|
236 |
+
['odd', 2, 1],
|
237 |
+
['even', 2, 0],
|
238 |
+
['3n', 3, 0],
|
239 |
+
['n', 1, 0],
|
240 |
+
['+n', 1, 0],
|
241 |
+
['-n', -1, 0],
|
242 |
+
['5', 0, 5],
|
243 |
+
];
|
244 |
+
}
|
245 |
+
|
246 |
+
public function getParseSeriesExceptionTestData()
|
247 |
+
{
|
248 |
+
return [
|
249 |
+
['foo'],
|
250 |
+
['n+'],
|
251 |
+
];
|
252 |
+
}
|
253 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/ReaderTest.php
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Reader;
|
16 |
+
|
17 |
+
class ReaderTest extends TestCase
|
18 |
+
{
|
19 |
+
public function testIsEOF()
|
20 |
+
{
|
21 |
+
$reader = new Reader('');
|
22 |
+
$this->assertTrue($reader->isEOF());
|
23 |
+
|
24 |
+
$reader = new Reader('hello');
|
25 |
+
$this->assertFalse($reader->isEOF());
|
26 |
+
|
27 |
+
$this->assignPosition($reader, 2);
|
28 |
+
$this->assertFalse($reader->isEOF());
|
29 |
+
|
30 |
+
$this->assignPosition($reader, 5);
|
31 |
+
$this->assertTrue($reader->isEOF());
|
32 |
+
}
|
33 |
+
|
34 |
+
public function testGetRemainingLength()
|
35 |
+
{
|
36 |
+
$reader = new Reader('hello');
|
37 |
+
$this->assertEquals(5, $reader->getRemainingLength());
|
38 |
+
|
39 |
+
$this->assignPosition($reader, 2);
|
40 |
+
$this->assertEquals(3, $reader->getRemainingLength());
|
41 |
+
|
42 |
+
$this->assignPosition($reader, 5);
|
43 |
+
$this->assertEquals(0, $reader->getRemainingLength());
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testGetSubstring()
|
47 |
+
{
|
48 |
+
$reader = new Reader('hello');
|
49 |
+
$this->assertEquals('he', $reader->getSubstring(2));
|
50 |
+
$this->assertEquals('el', $reader->getSubstring(2, 1));
|
51 |
+
|
52 |
+
$this->assignPosition($reader, 2);
|
53 |
+
$this->assertEquals('ll', $reader->getSubstring(2));
|
54 |
+
$this->assertEquals('lo', $reader->getSubstring(2, 1));
|
55 |
+
}
|
56 |
+
|
57 |
+
public function testGetOffset()
|
58 |
+
{
|
59 |
+
$reader = new Reader('hello');
|
60 |
+
$this->assertEquals(2, $reader->getOffset('ll'));
|
61 |
+
$this->assertFalse($reader->getOffset('w'));
|
62 |
+
|
63 |
+
$this->assignPosition($reader, 2);
|
64 |
+
$this->assertEquals(0, $reader->getOffset('ll'));
|
65 |
+
$this->assertFalse($reader->getOffset('he'));
|
66 |
+
}
|
67 |
+
|
68 |
+
public function testFindPattern()
|
69 |
+
{
|
70 |
+
$reader = new Reader('hello');
|
71 |
+
|
72 |
+
$this->assertFalse($reader->findPattern('/world/'));
|
73 |
+
$this->assertEquals(['hello', 'h'], $reader->findPattern('/^([a-z]).*/'));
|
74 |
+
|
75 |
+
$this->assignPosition($reader, 2);
|
76 |
+
$this->assertFalse($reader->findPattern('/^h.*/'));
|
77 |
+
$this->assertEquals(['llo'], $reader->findPattern('/^llo$/'));
|
78 |
+
}
|
79 |
+
|
80 |
+
public function testMoveForward()
|
81 |
+
{
|
82 |
+
$reader = new Reader('hello');
|
83 |
+
$this->assertEquals(0, $reader->getPosition());
|
84 |
+
|
85 |
+
$reader->moveForward(2);
|
86 |
+
$this->assertEquals(2, $reader->getPosition());
|
87 |
+
}
|
88 |
+
|
89 |
+
public function testToEnd()
|
90 |
+
{
|
91 |
+
$reader = new Reader('hello');
|
92 |
+
$reader->moveToEnd();
|
93 |
+
$this->assertTrue($reader->isEOF());
|
94 |
+
}
|
95 |
+
|
96 |
+
private function assignPosition(Reader $reader, $value)
|
97 |
+
{
|
98 |
+
$position = new \ReflectionProperty($reader, 'position');
|
99 |
+
$position->setAccessible(true);
|
100 |
+
$position->setValue($reader, $value);
|
101 |
+
}
|
102 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Shortcut/ClassParserTest.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Shortcut;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Shortcut\ClassParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
20 |
+
*/
|
21 |
+
class ClassParserTest extends TestCase
|
22 |
+
{
|
23 |
+
/** @dataProvider getParseTestData */
|
24 |
+
public function testParse($source, $representation)
|
25 |
+
{
|
26 |
+
$parser = new ClassParser();
|
27 |
+
$selectors = $parser->parse($source);
|
28 |
+
$this->assertCount(1, $selectors);
|
29 |
+
|
30 |
+
/** @var SelectorNode $selector */
|
31 |
+
$selector = $selectors[0];
|
32 |
+
$this->assertEquals($representation, (string) $selector->getTree());
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getParseTestData()
|
36 |
+
{
|
37 |
+
return [
|
38 |
+
['.testclass', 'Class[Element[*].testclass]'],
|
39 |
+
['testel.testclass', 'Class[Element[testel].testclass]'],
|
40 |
+
['testns|.testclass', 'Class[Element[testns|*].testclass]'],
|
41 |
+
['testns|*.testclass', 'Class[Element[testns|*].testclass]'],
|
42 |
+
['testns|testel.testclass', 'Class[Element[testns|testel].testclass]'],
|
43 |
+
];
|
44 |
+
}
|
45 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Shortcut/ElementParserTest.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Shortcut;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Shortcut\ElementParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
20 |
+
*/
|
21 |
+
class ElementParserTest extends TestCase
|
22 |
+
{
|
23 |
+
/** @dataProvider getParseTestData */
|
24 |
+
public function testParse($source, $representation)
|
25 |
+
{
|
26 |
+
$parser = new ElementParser();
|
27 |
+
$selectors = $parser->parse($source);
|
28 |
+
$this->assertCount(1, $selectors);
|
29 |
+
|
30 |
+
/** @var SelectorNode $selector */
|
31 |
+
$selector = $selectors[0];
|
32 |
+
$this->assertEquals($representation, (string) $selector->getTree());
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getParseTestData()
|
36 |
+
{
|
37 |
+
return [
|
38 |
+
['*', 'Element[*]'],
|
39 |
+
['testel', 'Element[testel]'],
|
40 |
+
['testns|*', 'Element[testns|*]'],
|
41 |
+
['testns|testel', 'Element[testns|testel]'],
|
42 |
+
];
|
43 |
+
}
|
44 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Shortcut/EmptyStringParserTest.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Shortcut;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Shortcut\EmptyStringParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
20 |
+
*/
|
21 |
+
class EmptyStringParserTest extends TestCase
|
22 |
+
{
|
23 |
+
public function testParse()
|
24 |
+
{
|
25 |
+
$parser = new EmptyStringParser();
|
26 |
+
$selectors = $parser->parse('');
|
27 |
+
$this->assertCount(1, $selectors);
|
28 |
+
|
29 |
+
/** @var SelectorNode $selector */
|
30 |
+
$selector = $selectors[0];
|
31 |
+
$this->assertEquals('Element[*]', (string) $selector->getTree());
|
32 |
+
|
33 |
+
$selectors = $parser->parse('this will produce an empty array');
|
34 |
+
$this->assertCount(0, $selectors);
|
35 |
+
}
|
36 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/Shortcut/HashParserTest.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser\Shortcut;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\SelectorNode;
|
16 |
+
use Symfony\Component\CssSelector\Parser\Shortcut\HashParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
20 |
+
*/
|
21 |
+
class HashParserTest extends TestCase
|
22 |
+
{
|
23 |
+
/** @dataProvider getParseTestData */
|
24 |
+
public function testParse($source, $representation)
|
25 |
+
{
|
26 |
+
$parser = new HashParser();
|
27 |
+
$selectors = $parser->parse($source);
|
28 |
+
$this->assertCount(1, $selectors);
|
29 |
+
|
30 |
+
/** @var SelectorNode $selector */
|
31 |
+
$selector = $selectors[0];
|
32 |
+
$this->assertEquals($representation, (string) $selector->getTree());
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getParseTestData()
|
36 |
+
{
|
37 |
+
return [
|
38 |
+
['#testid', 'Hash[Element[*]#testid]'],
|
39 |
+
['testel#testid', 'Hash[Element[testel]#testid]'],
|
40 |
+
['testns|#testid', 'Hash[Element[testns|*]#testid]'],
|
41 |
+
['testns|*#testid', 'Hash[Element[testns|*]#testid]'],
|
42 |
+
['testns|testel#testid', 'Hash[Element[testns|testel]#testid]'],
|
43 |
+
];
|
44 |
+
}
|
45 |
+
}
|
vendor/symfony/css-selector/Tests/Parser/TokenStreamTest.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\Parser;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Parser\Token;
|
16 |
+
use Symfony\Component\CssSelector\Parser\TokenStream;
|
17 |
+
|
18 |
+
class TokenStreamTest extends TestCase
|
19 |
+
{
|
20 |
+
public function testGetNext()
|
21 |
+
{
|
22 |
+
$stream = new TokenStream();
|
23 |
+
$stream->push($t1 = new Token(Token::TYPE_IDENTIFIER, 'h1', 0));
|
24 |
+
$stream->push($t2 = new Token(Token::TYPE_DELIMITER, '.', 2));
|
25 |
+
$stream->push($t3 = new Token(Token::TYPE_IDENTIFIER, 'title', 3));
|
26 |
+
|
27 |
+
$this->assertSame($t1, $stream->getNext());
|
28 |
+
$this->assertSame($t2, $stream->getNext());
|
29 |
+
$this->assertSame($t3, $stream->getNext());
|
30 |
+
}
|
31 |
+
|
32 |
+
public function testGetPeek()
|
33 |
+
{
|
34 |
+
$stream = new TokenStream();
|
35 |
+
$stream->push($t1 = new Token(Token::TYPE_IDENTIFIER, 'h1', 0));
|
36 |
+
$stream->push($t2 = new Token(Token::TYPE_DELIMITER, '.', 2));
|
37 |
+
$stream->push($t3 = new Token(Token::TYPE_IDENTIFIER, 'title', 3));
|
38 |
+
|
39 |
+
$this->assertSame($t1, $stream->getPeek());
|
40 |
+
$this->assertSame($t1, $stream->getNext());
|
41 |
+
$this->assertSame($t2, $stream->getPeek());
|
42 |
+
$this->assertSame($t2, $stream->getPeek());
|
43 |
+
$this->assertSame($t2, $stream->getNext());
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testGetNextIdentifier()
|
47 |
+
{
|
48 |
+
$stream = new TokenStream();
|
49 |
+
$stream->push(new Token(Token::TYPE_IDENTIFIER, 'h1', 0));
|
50 |
+
|
51 |
+
$this->assertEquals('h1', $stream->getNextIdentifier());
|
52 |
+
}
|
53 |
+
|
54 |
+
public function testFailToGetNextIdentifier()
|
55 |
+
{
|
56 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\SyntaxErrorException');
|
57 |
+
|
58 |
+
$stream = new TokenStream();
|
59 |
+
$stream->push(new Token(Token::TYPE_DELIMITER, '.', 2));
|
60 |
+
$stream->getNextIdentifier();
|
61 |
+
}
|
62 |
+
|
63 |
+
public function testGetNextIdentifierOrStar()
|
64 |
+
{
|
65 |
+
$stream = new TokenStream();
|
66 |
+
|
67 |
+
$stream->push(new Token(Token::TYPE_IDENTIFIER, 'h1', 0));
|
68 |
+
$this->assertEquals('h1', $stream->getNextIdentifierOrStar());
|
69 |
+
|
70 |
+
$stream->push(new Token(Token::TYPE_DELIMITER, '*', 0));
|
71 |
+
$this->assertNull($stream->getNextIdentifierOrStar());
|
72 |
+
}
|
73 |
+
|
74 |
+
public function testFailToGetNextIdentifierOrStar()
|
75 |
+
{
|
76 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\SyntaxErrorException');
|
77 |
+
|
78 |
+
$stream = new TokenStream();
|
79 |
+
$stream->push(new Token(Token::TYPE_DELIMITER, '.', 2));
|
80 |
+
$stream->getNextIdentifierOrStar();
|
81 |
+
}
|
82 |
+
|
83 |
+
public function testSkipWhitespace()
|
84 |
+
{
|
85 |
+
$stream = new TokenStream();
|
86 |
+
$stream->push($t1 = new Token(Token::TYPE_IDENTIFIER, 'h1', 0));
|
87 |
+
$stream->push($t2 = new Token(Token::TYPE_WHITESPACE, ' ', 2));
|
88 |
+
$stream->push($t3 = new Token(Token::TYPE_IDENTIFIER, 'h1', 3));
|
89 |
+
|
90 |
+
$stream->skipWhitespace();
|
91 |
+
$this->assertSame($t1, $stream->getNext());
|
92 |
+
|
93 |
+
$stream->skipWhitespace();
|
94 |
+
$this->assertSame($t3, $stream->getNext());
|
95 |
+
}
|
96 |
+
}
|
vendor/symfony/css-selector/Tests/XPath/Fixtures/ids.html
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html id="html"><head>
|
2 |
+
<link id="link-href" href="foo" />
|
3 |
+
<link id="link-nohref" />
|
4 |
+
</head><body>
|
5 |
+
<div id="outer-div">
|
6 |
+
<a id="name-anchor" name="foo"></a>
|
7 |
+
<a id="tag-anchor" rel="tag" href="http://localhost/foo">link</a>
|
8 |
+
<a id="nofollow-anchor" rel="nofollow" href="https://example.org">
|
9 |
+
link</a>
|
10 |
+
<ol id="first-ol" class="a b c">
|
11 |
+
<li id="first-li">content</li>
|
12 |
+
<li id="second-li" lang="En-us">
|
13 |
+
<div id="li-div">
|
14 |
+
</div>
|
15 |
+
</li>
|
16 |
+
<li id="third-li" class="ab c"></li>
|
17 |
+
<li id="fourth-li" class="ab
|
18 |
+
c"></li>
|
19 |
+
<li id="fifth-li"></li>
|
20 |
+
<li id="sixth-li"></li>
|
21 |
+
<li id="seventh-li"> </li>
|
22 |
+
</ol>
|
23 |
+
<p id="paragraph">
|
24 |
+
<b id="p-b">hi</b> <em id="p-em">there</em>
|
25 |
+
<b id="p-b2">guy</b>
|
26 |
+
<input type="checkbox" id="checkbox-unchecked" />
|
27 |
+
<input type="checkbox" id="checkbox-disabled" disabled="" />
|
28 |
+
<input type="text" id="text-checked" checked="checked" />
|
29 |
+
<input type="hidden" />
|
30 |
+
<input type="hidden" disabled="disabled" />
|
31 |
+
<input type="checkbox" id="checkbox-checked" checked="checked" />
|
32 |
+
<input type="checkbox" id="checkbox-disabled-checked"
|
33 |
+
disabled="disabled" checked="checked" />
|
34 |
+
<fieldset id="fieldset" disabled="disabled">
|
35 |
+
<input type="checkbox" id="checkbox-fieldset-disabled" />
|
36 |
+
<input type="hidden" />
|
37 |
+
</fieldset>
|
38 |
+
</p>
|
39 |
+
<ol id="second-ol">
|
40 |
+
</ol>
|
41 |
+
<map name="dummymap">
|
42 |
+
<area shape="circle" coords="200,250,25" href="foo.html" id="area-href" />
|
43 |
+
<area shape="default" id="area-nohref" />
|
44 |
+
</map>
|
45 |
+
</div>
|
46 |
+
<div id="foobar-div" foobar="ab bc
|
47 |
+
cde"><span id="foobar-span"></span></div>
|
48 |
+
</body></html>
|
vendor/symfony/css-selector/Tests/XPath/Fixtures/lang.xml
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<test>
|
2 |
+
<a id="first" xml:lang="en">a</a>
|
3 |
+
<b id="second" xml:lang="en-US">b</b>
|
4 |
+
<c id="third" xml:lang="en-Nz">c</c>
|
5 |
+
<d id="fourth" xml:lang="En-us">d</d>
|
6 |
+
<e id="fifth" xml:lang="fr">e</e>
|
7 |
+
<f id="sixth" xml:lang="ru">f</f>
|
8 |
+
<g id="seventh" xml:lang="de">
|
9 |
+
<h id="eighth" xml:lang="zh"/>
|
10 |
+
</g>
|
11 |
+
</test>
|
vendor/symfony/css-selector/Tests/XPath/Fixtures/shakespear.html
ADDED
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2 |
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3 |
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" debug="true">
|
4 |
+
<head>
|
5 |
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
6 |
+
</head>
|
7 |
+
<body>
|
8 |
+
<div id="test">
|
9 |
+
<div class="dialog">
|
10 |
+
<h2>As You Like It</h2>
|
11 |
+
<div id="playwright">
|
12 |
+
by William Shakespeare
|
13 |
+
</div>
|
14 |
+
<div class="dialog scene thirdClass" id="scene1">
|
15 |
+
<h3>ACT I, SCENE III. A room in the palace.</h3>
|
16 |
+
<div class="dialog">
|
17 |
+
<div class="direction">Enter CELIA and ROSALIND</div>
|
18 |
+
</div>
|
19 |
+
<div id="speech1" class="character">CELIA</div>
|
20 |
+
<div class="dialog">
|
21 |
+
<div id="scene1.3.1">Why, cousin! why, Rosalind! Cupid have mercy! not a word?</div>
|
22 |
+
</div>
|
23 |
+
<div id="speech2" class="character">ROSALIND</div>
|
24 |
+
<div class="dialog">
|
25 |
+
<div id="scene1.3.2">Not one to throw at a dog.</div>
|
26 |
+
</div>
|
27 |
+
<div id="speech3" class="character">CELIA</div>
|
28 |
+
<div class="dialog">
|
29 |
+
<div id="scene1.3.3">No, thy words are too precious to be cast away upon</div>
|
30 |
+
<div id="scene1.3.4">curs; throw some of them at me; come, lame me with reasons.</div>
|
31 |
+
</div>
|
32 |
+
<div id="speech4" class="character">ROSALIND</div>
|
33 |
+
<div id="speech5" class="character">CELIA</div>
|
34 |
+
<div class="dialog">
|
35 |
+
<div id="scene1.3.8">But is all this for your father?</div>
|
36 |
+
</div>
|
37 |
+
<div class="dialog">
|
38 |
+
<div id="scene1.3.5">Then there were two cousins laid up; when the one</div>
|
39 |
+
<div id="scene1.3.6">should be lamed with reasons and the other mad</div>
|
40 |
+
<div id="scene1.3.7">without any.</div>
|
41 |
+
</div>
|
42 |
+
<div id="speech6" class="character">ROSALIND</div>
|
43 |
+
<div class="dialog">
|
44 |
+
<div id="scene1.3.9">No, some of it is for my child's father. O, how</div>
|
45 |
+
<div id="scene1.3.10">full of briers is this working-day world!</div>
|
46 |
+
</div>
|
47 |
+
<div id="speech7" class="character">CELIA</div>
|
48 |
+
<div class="dialog">
|
49 |
+
<div id="scene1.3.11">They are but burs, cousin, thrown upon thee in</div>
|
50 |
+
<div id="scene1.3.12">holiday foolery: if we walk not in the trodden</div>
|
51 |
+
<div id="scene1.3.13">paths our very petticoats will catch them.</div>
|
52 |
+
</div>
|
53 |
+
<div id="speech8" class="character">ROSALIND</div>
|
54 |
+
<div class="dialog">
|
55 |
+
<div id="scene1.3.14">I could shake them off my coat: these burs are in my heart.</div>
|
56 |
+
</div>
|
57 |
+
<div id="speech9" class="character">CELIA</div>
|
58 |
+
<div class="dialog">
|
59 |
+
<div id="scene1.3.15">Hem them away.</div>
|
60 |
+
</div>
|
61 |
+
<div id="speech10" class="character">ROSALIND</div>
|
62 |
+
<div class="dialog">
|
63 |
+
<div id="scene1.3.16">I would try, if I could cry 'hem' and have him.</div>
|
64 |
+
</div>
|
65 |
+
<div id="speech11" class="character">CELIA</div>
|
66 |
+
<div class="dialog">
|
67 |
+
<div id="scene1.3.17">Come, come, wrestle with thy affections.</div>
|
68 |
+
</div>
|
69 |
+
<div id="speech12" class="character">ROSALIND</div>
|
70 |
+
<div class="dialog">
|
71 |
+
<div id="scene1.3.18">O, they take the part of a better wrestler than myself!</div>
|
72 |
+
</div>
|
73 |
+
<div id="speech13" class="character">CELIA</div>
|
74 |
+
<div class="dialog">
|
75 |
+
<div id="scene1.3.19">O, a good wish upon you! you will try in time, in</div>
|
76 |
+
<div id="scene1.3.20">despite of a fall. But, turning these jests out of</div>
|
77 |
+
<div id="scene1.3.21">service, let us talk in good earnest: is it</div>
|
78 |
+
<div id="scene1.3.22">possible, on such a sudden, you should fall into so</div>
|
79 |
+
<div id="scene1.3.23">strong a liking with old Sir Rowland's youngest son?</div>
|
80 |
+
</div>
|
81 |
+
<div id="speech14" class="character">ROSALIND</div>
|
82 |
+
<div class="dialog">
|
83 |
+
<div id="scene1.3.24">The duke my father loved his father dearly.</div>
|
84 |
+
</div>
|
85 |
+
<div id="speech15" class="character">CELIA</div>
|
86 |
+
<div class="dialog">
|
87 |
+
<div id="scene1.3.25">Doth it therefore ensue that you should love his son</div>
|
88 |
+
<div id="scene1.3.26">dearly? By this kind of chase, I should hate him,</div>
|
89 |
+
<div id="scene1.3.27">for my father hated his father dearly; yet I hate</div>
|
90 |
+
<div id="scene1.3.28">not Orlando.</div>
|
91 |
+
</div>
|
92 |
+
<div id="speech16" class="character">ROSALIND</div>
|
93 |
+
<div title="wtf" class="dialog">
|
94 |
+
<div id="scene1.3.29">No, faith, hate him not, for my sake.</div>
|
95 |
+
</div>
|
96 |
+
<div id="speech17" class="character">CELIA</div>
|
97 |
+
<div class="dialog">
|
98 |
+
<div id="scene1.3.30">Why should I not? doth he not deserve well?</div>
|
99 |
+
</div>
|
100 |
+
<div id="speech18" class="character">ROSALIND</div>
|
101 |
+
<div class="dialog">
|
102 |
+
<div id="scene1.3.31">Let me love him for that, and do you love him</div>
|
103 |
+
<div id="scene1.3.32">because I do. Look, here comes the duke.</div>
|
104 |
+
</div>
|
105 |
+
<div id="speech19" class="character">CELIA</div>
|
106 |
+
<div class="dialog">
|
107 |
+
<div id="scene1.3.33">With his eyes full of anger.</div>
|
108 |
+
<div class="direction">Enter DUKE FREDERICK, with Lords</div>
|
109 |
+
</div>
|
110 |
+
<div id="speech20" class="character">DUKE FREDERICK</div>
|
111 |
+
<div class="dialog">
|
112 |
+
<div id="scene1.3.34">Mistress, dispatch you with your safest haste</div>
|
113 |
+
<div id="scene1.3.35">And get you from our court.</div>
|
114 |
+
</div>
|
115 |
+
<div id="speech21" class="character">ROSALIND</div>
|
116 |
+
<div class="dialog">
|
117 |
+
<div id="scene1.3.36">Me, uncle?</div>
|
118 |
+
</div>
|
119 |
+
<div id="speech22" class="character">DUKE FREDERICK</div>
|
120 |
+
<div class="dialog">
|
121 |
+
<div id="scene1.3.37">You, cousin</div>
|
122 |
+
<div id="scene1.3.38">Within these ten days if that thou be'st found</div>
|
123 |
+
<div id="scene1.3.39">So near our public court as twenty miles,</div>
|
124 |
+
<div id="scene1.3.40">Thou diest for it.</div>
|
125 |
+
</div>
|
126 |
+
<div id="speech23" class="character">ROSALIND</div>
|
127 |
+
<div class="dialog">
|
128 |
+
<div id="scene1.3.41"> I do beseech your grace,</div>
|
129 |
+
<div id="scene1.3.42">Let me the knowledge of my fault bear with me:</div>
|
130 |
+
<div id="scene1.3.43">If with myself I hold intelligence</div>
|
131 |
+
<div id="scene1.3.44">Or have acquaintance with mine own desires,</div>
|
132 |
+
<div id="scene1.3.45">If that I do not dream or be not frantic,--</div>
|
133 |
+
<div id="scene1.3.46">As I do trust I am not--then, dear uncle,</div>
|
134 |
+
<div id="scene1.3.47">Never so much as in a thought unborn</div>
|
135 |
+
<div id="scene1.3.48">Did I offend your highness.</div>
|
136 |
+
</div>
|
137 |
+
<div id="speech24" class="character">DUKE FREDERICK</div>
|
138 |
+
<div class="dialog">
|
139 |
+
<div id="scene1.3.49">Thus do all traitors:</div>
|
140 |
+
<div id="scene1.3.50">If their purgation did consist in words,</div>
|
141 |
+
<div id="scene1.3.51">They are as innocent as grace itself:</div>
|
142 |
+
<div id="scene1.3.52">Let it suffice thee that I trust thee not.</div>
|
143 |
+
</div>
|
144 |
+
<div id="speech25" class="character">ROSALIND</div>
|
145 |
+
<div class="dialog">
|
146 |
+
<div id="scene1.3.53">Yet your mistrust cannot make me a traitor:</div>
|
147 |
+
<div id="scene1.3.54">Tell me whereon the likelihood depends.</div>
|
148 |
+
</div>
|
149 |
+
<div id="speech26" class="character">DUKE FREDERICK</div>
|
150 |
+
<div class="dialog">
|
151 |
+
<div id="scene1.3.55">Thou art thy father's daughter; there's enough.</div>
|
152 |
+
</div>
|
153 |
+
<div id="speech27" class="character">ROSALIND</div>
|
154 |
+
<div class="dialog">
|
155 |
+
<div id="scene1.3.56">So was I when your highness took his dukedom;</div>
|
156 |
+
<div id="scene1.3.57">So was I when your highness banish'd him:</div>
|
157 |
+
<div id="scene1.3.58">Treason is not inherited, my lord;</div>
|
158 |
+
<div id="scene1.3.59">Or, if we did derive it from our friends,</div>
|
159 |
+
<div id="scene1.3.60">What's that to me? my father was no traitor:</div>
|
160 |
+
<div id="scene1.3.61">Then, good my liege, mistake me not so much</div>
|
161 |
+
<div id="scene1.3.62">To think my poverty is treacherous.</div>
|
162 |
+
</div>
|
163 |
+
<div id="speech28" class="character">CELIA</div>
|
164 |
+
<div class="dialog">
|
165 |
+
<div id="scene1.3.63">Dear sovereign, hear me speak.</div>
|
166 |
+
</div>
|
167 |
+
<div id="speech29" class="character">DUKE FREDERICK</div>
|
168 |
+
<div class="dialog">
|
169 |
+
<div id="scene1.3.64">Ay, Celia; we stay'd her for your sake,</div>
|
170 |
+
<div id="scene1.3.65">Else had she with her father ranged along.</div>
|
171 |
+
</div>
|
172 |
+
<div id="speech30" class="character">CELIA</div>
|
173 |
+
<div class="dialog">
|
174 |
+
<div id="scene1.3.66">I did not then entreat to have her stay;</div>
|
175 |
+
<div id="scene1.3.67">It was your pleasure and your own remorse:</div>
|
176 |
+
<div id="scene1.3.68">I was too young that time to value her;</div>
|
177 |
+
<div id="scene1.3.69">But now I know her: if she be a traitor,</div>
|
178 |
+
<div id="scene1.3.70">Why so am I; we still have slept together,</div>
|
179 |
+
<div id="scene1.3.71">Rose at an instant, learn'd, play'd, eat together,</div>
|
180 |
+
<div id="scene1.3.72">And wheresoever we went, like Juno's swans,</div>
|
181 |
+
<div id="scene1.3.73">Still we went coupled and inseparable.</div>
|
182 |
+
</div>
|
183 |
+
<div id="speech31" class="character">DUKE FREDERICK</div>
|
184 |
+
<div class="dialog">
|
185 |
+
<div id="scene1.3.74">She is too subtle for thee; and her smoothness,</div>
|
186 |
+
<div id="scene1.3.75">Her very silence and her patience</div>
|
187 |
+
<div id="scene1.3.76">Speak to the people, and they pity her.</div>
|
188 |
+
<div id="scene1.3.77">Thou art a fool: she robs thee of thy name;</div>
|
189 |
+
<div id="scene1.3.78">And thou wilt show more bright and seem more virtuous</div>
|
190 |
+
<div id="scene1.3.79">When she is gone. Then open not thy lips:</div>
|
191 |
+
<div id="scene1.3.80">Firm and irrevocable is my doom</div>
|
192 |
+
<div id="scene1.3.81">Which I have pass'd upon her; she is banish'd.</div>
|
193 |
+
</div>
|
194 |
+
<div id="speech32" class="character">CELIA</div>
|
195 |
+
<div class="dialog">
|
196 |
+
<div id="scene1.3.82">Pronounce that sentence then on me, my liege:</div>
|
197 |
+
<div id="scene1.3.83">I cannot live out of her company.</div>
|
198 |
+
</div>
|
199 |
+
<div id="speech33" class="character">DUKE FREDERICK</div>
|
200 |
+
<div class="dialog">
|
201 |
+
<div id="scene1.3.84">You are a fool. You, niece, provide yourself:</div>
|
202 |
+
<div id="scene1.3.85">If you outstay the time, upon mine honour,</div>
|
203 |
+
<div id="scene1.3.86">And in the greatness of my word, you die.</div>
|
204 |
+
<div class="direction">Exeunt DUKE FREDERICK and Lords</div>
|
205 |
+
</div>
|
206 |
+
<div id="speech34" class="character">CELIA</div>
|
207 |
+
<div class="dialog">
|
208 |
+
<div id="scene1.3.87">O my poor Rosalind, whither wilt thou go?</div>
|
209 |
+
<div id="scene1.3.88">Wilt thou change fathers? I will give thee mine.</div>
|
210 |
+
<div id="scene1.3.89">I charge thee, be not thou more grieved than I am.</div>
|
211 |
+
</div>
|
212 |
+
<div id="speech35" class="character">ROSALIND</div>
|
213 |
+
<div class="dialog">
|
214 |
+
<div id="scene1.3.90">I have more cause.</div>
|
215 |
+
</div>
|
216 |
+
<div id="speech36" class="character">CELIA</div>
|
217 |
+
<div class="dialog">
|
218 |
+
<div id="scene1.3.91"> Thou hast not, cousin;</div>
|
219 |
+
<div id="scene1.3.92">Prithee be cheerful: know'st thou not, the duke</div>
|
220 |
+
<div id="scene1.3.93">Hath banish'd me, his daughter?</div>
|
221 |
+
</div>
|
222 |
+
<div id="speech37" class="character">ROSALIND</div>
|
223 |
+
<div class="dialog">
|
224 |
+
<div id="scene1.3.94">That he hath not.</div>
|
225 |
+
</div>
|
226 |
+
<div id="speech38" class="character">CELIA</div>
|
227 |
+
<div class="dialog">
|
228 |
+
<div id="scene1.3.95">No, hath not? Rosalind lacks then the love</div>
|
229 |
+
<div id="scene1.3.96">Which teacheth thee that thou and I am one:</div>
|
230 |
+
<div id="scene1.3.97">Shall we be sunder'd? shall we part, sweet girl?</div>
|
231 |
+
<div id="scene1.3.98">No: let my father seek another heir.</div>
|
232 |
+
<div id="scene1.3.99">Therefore devise with me how we may fly,</div>
|
233 |
+
<div id="scene1.3.100">Whither to go and what to bear with us;</div>
|
234 |
+
<div id="scene1.3.101">And do not seek to take your change upon you,</div>
|
235 |
+
<div id="scene1.3.102">To bear your griefs yourself and leave me out;</div>
|
236 |
+
<div id="scene1.3.103">For, by this heaven, now at our sorrows pale,</div>
|
237 |
+
<div id="scene1.3.104">Say what thou canst, I'll go along with thee.</div>
|
238 |
+
</div>
|
239 |
+
<div id="speech39" class="character">ROSALIND</div>
|
240 |
+
<div class="dialog">
|
241 |
+
<div id="scene1.3.105">Why, whither shall we go?</div>
|
242 |
+
</div>
|
243 |
+
<div id="speech40" class="character">CELIA</div>
|
244 |
+
<div class="dialog">
|
245 |
+
<div id="scene1.3.106">To seek my uncle in the forest of Arden.</div>
|
246 |
+
</div>
|
247 |
+
<div id="speech41" class="character">ROSALIND</div>
|
248 |
+
<div class="dialog">
|
249 |
+
<div id="scene1.3.107">Alas, what danger will it be to us,</div>
|
250 |
+
<div id="scene1.3.108">Maids as we are, to travel forth so far!</div>
|
251 |
+
<div id="scene1.3.109">Beauty provoketh thieves sooner than gold.</div>
|
252 |
+
</div>
|
253 |
+
<div id="speech42" class="character">CELIA</div>
|
254 |
+
<div class="dialog">
|
255 |
+
<div id="scene1.3.110">I'll put myself in poor and mean attire</div>
|
256 |
+
<div id="scene1.3.111">And with a kind of umber smirch my face;</div>
|
257 |
+
<div id="scene1.3.112">The like do you: so shall we pass along</div>
|
258 |
+
<div id="scene1.3.113">And never stir assailants.</div>
|
259 |
+
</div>
|
260 |
+
<div id="speech43" class="character">ROSALIND</div>
|
261 |
+
<div class="dialog">
|
262 |
+
<div id="scene1.3.114">Were it not better,</div>
|
263 |
+
<div id="scene1.3.115">Because that I am more than common tall,</div>
|
264 |
+
<div id="scene1.3.116">That I did suit me all points like a man?</div>
|
265 |
+
<div id="scene1.3.117">A gallant curtle-axe upon my thigh,</div>
|
266 |
+
<div id="scene1.3.118">A boar-spear in my hand; and--in my heart</div>
|
267 |
+
<div id="scene1.3.119">Lie there what hidden woman's fear there will--</div>
|
268 |
+
<div id="scene1.3.120">We'll have a swashing and a martial outside,</div>
|
269 |
+
<div id="scene1.3.121">As many other mannish cowards have</div>
|
270 |
+
<div id="scene1.3.122">That do outface it with their semblances.</div>
|
271 |
+
</div>
|
272 |
+
<div id="speech44" class="character">CELIA</div>
|
273 |
+
<div class="dialog">
|
274 |
+
<div id="scene1.3.123">What shall I call thee when thou art a man?</div>
|
275 |
+
</div>
|
276 |
+
<div id="speech45" class="character">ROSALIND</div>
|
277 |
+
<div class="dialog">
|
278 |
+
<div id="scene1.3.124">I'll have no worse a name than Jove's own page;</div>
|
279 |
+
<div id="scene1.3.125">And therefore look you call me Ganymede.</div>
|
280 |
+
<div id="scene1.3.126">But what will you be call'd?</div>
|
281 |
+
</div>
|
282 |
+
<div id="speech46" class="character">CELIA</div>
|
283 |
+
<div class="dialog">
|
284 |
+
<div id="scene1.3.127">Something that hath a reference to my state</div>
|
285 |
+
<div id="scene1.3.128">No longer Celia, but Aliena.</div>
|
286 |
+
</div>
|
287 |
+
<div id="speech47" class="character">ROSALIND</div>
|
288 |
+
<div class="dialog">
|
289 |
+
<div id="scene1.3.129">But, cousin, what if we assay'd to steal</div>
|
290 |
+
<div id="scene1.3.130">The clownish fool out of your father's court?</div>
|
291 |
+
<div id="scene1.3.131">Would he not be a comfort to our travel?</div>
|
292 |
+
</div>
|
293 |
+
<div id="speech48" class="character">CELIA</div>
|
294 |
+
<div class="dialog">
|
295 |
+
<div id="scene1.3.132">He'll go along o'er the wide world with me;</div>
|
296 |
+
<div id="scene1.3.133">Leave me alone to woo him. Let's away,</div>
|
297 |
+
<div id="scene1.3.134">And get our jewels and our wealth together,</div>
|
298 |
+
<div id="scene1.3.135">Devise the fittest time and safest way</div>
|
299 |
+
<div id="scene1.3.136">To hide us from pursuit that will be made</div>
|
300 |
+
<div id="scene1.3.137">After my flight. Now go we in content</div>
|
301 |
+
<div id="scene1.3.138">To liberty and not to banishment.</div>
|
302 |
+
<div class="direction">Exeunt</div>
|
303 |
+
</div>
|
304 |
+
</div>
|
305 |
+
</div>
|
306 |
+
</div>
|
307 |
+
</body>
|
308 |
+
</html>
|
vendor/symfony/css-selector/Tests/XPath/TranslatorTest.php
ADDED
@@ -0,0 +1,413 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
namespace Symfony\Component\CssSelector\Tests\XPath;
|
13 |
+
|
14 |
+
use PHPUnit\Framework\TestCase;
|
15 |
+
use Symfony\Component\CssSelector\Node\ElementNode;
|
16 |
+
use Symfony\Component\CssSelector\Node\FunctionNode;
|
17 |
+
use Symfony\Component\CssSelector\Parser\Parser;
|
18 |
+
use Symfony\Component\CssSelector\XPath\Extension\HtmlExtension;
|
19 |
+
use Symfony\Component\CssSelector\XPath\Translator;
|
20 |
+
use Symfony\Component\CssSelector\XPath\XPathExpr;
|
21 |
+
|
22 |
+
class TranslatorTest extends TestCase
|
23 |
+
{
|
24 |
+
/** @dataProvider getXpathLiteralTestData */
|
25 |
+
public function testXpathLiteral($value, $literal)
|
26 |
+
{
|
27 |
+
$this->assertEquals($literal, Translator::getXpathLiteral($value));
|
28 |
+
}
|
29 |
+
|
30 |
+
/** @dataProvider getCssToXPathTestData */
|
31 |
+
public function testCssToXPath($css, $xpath)
|
32 |
+
{
|
33 |
+
$translator = new Translator();
|
34 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
35 |
+
$this->assertEquals($xpath, $translator->cssToXPath($css, ''));
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testCssToXPathPseudoElement()
|
39 |
+
{
|
40 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
41 |
+
$translator = new Translator();
|
42 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
43 |
+
$translator->cssToXPath('e::first-line');
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testGetExtensionNotExistsExtension()
|
47 |
+
{
|
48 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
49 |
+
$translator = new Translator();
|
50 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
51 |
+
$translator->getExtension('fake');
|
52 |
+
}
|
53 |
+
|
54 |
+
public function testAddCombinationNotExistsExtension()
|
55 |
+
{
|
56 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
57 |
+
$translator = new Translator();
|
58 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
59 |
+
$parser = new Parser();
|
60 |
+
$xpath = $parser->parse('*')[0];
|
61 |
+
$combinedXpath = $parser->parse('*')[0];
|
62 |
+
$translator->addCombination('fake', $xpath, $combinedXpath);
|
63 |
+
}
|
64 |
+
|
65 |
+
public function testAddFunctionNotExistsFunction()
|
66 |
+
{
|
67 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
68 |
+
$translator = new Translator();
|
69 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
70 |
+
$xpath = new XPathExpr();
|
71 |
+
$function = new FunctionNode(new ElementNode(), 'fake');
|
72 |
+
$translator->addFunction($xpath, $function);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testAddPseudoClassNotExistsClass()
|
76 |
+
{
|
77 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
78 |
+
$translator = new Translator();
|
79 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
80 |
+
$xpath = new XPathExpr();
|
81 |
+
$translator->addPseudoClass($xpath, 'fake');
|
82 |
+
}
|
83 |
+
|
84 |
+
public function testAddAttributeMatchingClassNotExistsClass()
|
85 |
+
{
|
86 |
+
$this->expectException('Symfony\Component\CssSelector\Exception\ExpressionErrorException');
|
87 |
+
$translator = new Translator();
|
88 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
89 |
+
$xpath = new XPathExpr();
|
90 |
+
$translator->addAttributeMatching($xpath, '', '', '');
|
91 |
+
}
|
92 |
+
|
93 |
+
/** @dataProvider getXmlLangTestData */
|
94 |
+
public function testXmlLang($css, array $elementsId)
|
95 |
+
{
|
96 |
+
$translator = new Translator();
|
97 |
+
$document = new \SimpleXMLElement(file_get_contents(__DIR__.'/Fixtures/lang.xml'));
|
98 |
+
$elements = $document->xpath($translator->cssToXPath($css));
|
99 |
+
$this->assertCount(\count($elementsId), $elements);
|
100 |
+
foreach ($elements as $element) {
|
101 |
+
$this->assertContains((string) $element->attributes()->id, $elementsId);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
/** @dataProvider getHtmlIdsTestData */
|
106 |
+
public function testHtmlIds($css, array $elementsId)
|
107 |
+
{
|
108 |
+
$translator = new Translator();
|
109 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
110 |
+
$document = new \DOMDocument();
|
111 |
+
$document->strictErrorChecking = false;
|
112 |
+
$internalErrors = libxml_use_internal_errors(true);
|
113 |
+
$document->loadHTMLFile(__DIR__.'/Fixtures/ids.html');
|
114 |
+
$document = simplexml_import_dom($document);
|
115 |
+
$elements = $document->xpath($translator->cssToXPath($css));
|
116 |
+
$this->assertCount(\count($elementsId), $elementsId);
|
117 |
+
foreach ($elements as $element) {
|
118 |
+
if (null !== $element->attributes()->id) {
|
119 |
+
$this->assertContains((string) $element->attributes()->id, $elementsId);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
libxml_clear_errors();
|
123 |
+
libxml_use_internal_errors($internalErrors);
|
124 |
+
}
|
125 |
+
|
126 |
+
/** @dataProvider getHtmlShakespearTestData */
|
127 |
+
public function testHtmlShakespear($css, $count)
|
128 |
+
{
|
129 |
+
$translator = new Translator();
|
130 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
131 |
+
$document = new \DOMDocument();
|
132 |
+
$document->strictErrorChecking = false;
|
133 |
+
$document->loadHTMLFile(__DIR__.'/Fixtures/shakespear.html');
|
134 |
+
$document = simplexml_import_dom($document);
|
135 |
+
$bodies = $document->xpath('//body');
|
136 |
+
$elements = $bodies[0]->xpath($translator->cssToXPath($css));
|
137 |
+
$this->assertCount($count, $elements);
|
138 |
+
}
|
139 |
+
|
140 |
+
public function testOnlyOfTypeFindsSingleChildrenOfGivenType()
|
141 |
+
{
|
142 |
+
$translator = new Translator();
|
143 |
+
$translator->registerExtension(new HtmlExtension($translator));
|
144 |
+
$document = new \DOMDocument();
|
145 |
+
$document->loadHTML(<<<'HTML'
|
146 |
+
<html>
|
147 |
+
<body>
|
148 |
+
<p>
|
149 |
+
<span>A</span>
|
150 |
+
</p>
|
151 |
+
<p>
|
152 |
+
<span>B</span>
|
153 |
+
<span>C</span>
|
154 |
+
</p>
|
155 |
+
</body>
|
156 |
+
</html>
|
157 |
+
HTML
|
158 |
+
);
|
159 |
+
|
160 |
+
$xpath = new \DOMXPath($document);
|
161 |
+
$nodeList = $xpath->query($translator->cssToXPath('span:only-of-type'));
|
162 |
+
|
163 |
+
$this->assertSame(1, $nodeList->length);
|
164 |
+
$this->assertSame('A', $nodeList->item(0)->textContent);
|
165 |
+
}
|
166 |
+
|
167 |
+
public function getXpathLiteralTestData()
|
168 |
+
{
|
169 |
+
return [
|
170 |
+
['foo', "'foo'"],
|
171 |
+
["foo's bar", '"foo\'s bar"'],
|
172 |
+
["foo's \"middle\" bar", 'concat(\'foo\', "\'", \'s "middle" bar\')'],
|
173 |
+
["foo's 'middle' \"bar\"", 'concat(\'foo\', "\'", \'s \', "\'", \'middle\', "\'", \' "bar"\')'],
|
174 |
+
];
|
175 |
+
}
|
176 |
+
|
177 |
+
public function getCssToXPathTestData()
|
178 |
+
{
|
179 |
+
return [
|
180 |
+
['*', '*'],
|
181 |
+
['e', 'e'],
|
182 |
+
['*|e', 'e'],
|
183 |
+
['e|f', 'e:f'],
|
184 |
+
['e[foo]', 'e[@foo]'],
|
185 |
+
['e[foo|bar]', 'e[@foo:bar]'],
|
186 |
+
['e[foo="bar"]', "e[@foo = 'bar']"],
|
187 |
+
['e[foo~="bar"]', "e[@foo and contains(concat(' ', normalize-space(@foo), ' '), ' bar ')]"],
|
188 |
+
['e[foo^="bar"]', "e[@foo and starts-with(@foo, 'bar')]"],
|
189 |
+
['e[foo$="bar"]', "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']"],
|
190 |
+
['e[foo*="bar"]', "e[@foo and contains(@foo, 'bar')]"],
|
191 |
+
['e[foo!="bar"]', "e[not(@foo) or @foo != 'bar']"],
|
192 |
+
['e[foo!="bar"][foo!="baz"]', "e[(not(@foo) or @foo != 'bar') and (not(@foo) or @foo != 'baz')]"],
|
193 |
+
['e[hreflang|="en"]', "e[@hreflang and (@hreflang = 'en' or starts-with(@hreflang, 'en-'))]"],
|
194 |
+
['e:nth-child(1)', "*/*[(name() = 'e') and (position() = 1)]"],
|
195 |
+
['e:nth-last-child(1)', "*/*[(name() = 'e') and (position() = last() - 0)]"],
|
196 |
+
['e:nth-last-child(2n+2)', "*/*[(name() = 'e') and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"],
|
197 |
+
['e:nth-of-type(1)', '*/e[position() = 1]'],
|
198 |
+
['e:nth-last-of-type(1)', '*/e[position() = last() - 0]'],
|
199 |
+
['div e:nth-last-of-type(1) .aclass', "div/descendant-or-self::*/e[position() = last() - 0]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' aclass ')]"],
|
200 |
+
['e:first-child', "*/*[(name() = 'e') and (position() = 1)]"],
|
201 |
+
['e:last-child', "*/*[(name() = 'e') and (position() = last())]"],
|
202 |
+
['e:first-of-type', '*/e[position() = 1]'],
|
203 |
+
['e:last-of-type', '*/e[position() = last()]'],
|
204 |
+
['e:only-child', "*/*[(name() = 'e') and (last() = 1)]"],
|
205 |
+
['e:only-of-type', 'e[count(preceding-sibling::e)=0 and count(following-sibling::e)=0]'],
|
206 |
+
['e:empty', 'e[not(*) and not(string-length())]'],
|
207 |
+
['e:EmPTY', 'e[not(*) and not(string-length())]'],
|
208 |
+
['e:root', 'e[not(parent::*)]'],
|
209 |
+
['e:hover', 'e[0]'],
|
210 |
+
['e:contains("foo")', "e[contains(string(.), 'foo')]"],
|
211 |
+
['e:ConTains(foo)', "e[contains(string(.), 'foo')]"],
|
212 |
+
['e.warning', "e[@class and contains(concat(' ', normalize-space(@class), ' '), ' warning ')]"],
|
213 |
+
['e#myid', "e[@id = 'myid']"],
|
214 |
+
['e:not(:nth-child(odd))', 'e[not(position() - 1 >= 0 and (position() - 1) mod 2 = 0)]'],
|
215 |
+
['e:nOT(*)', 'e[0]'],
|
216 |
+
['e f', 'e/descendant-or-self::*/f'],
|
217 |
+
['e > f', 'e/f'],
|
218 |
+
['e + f', "e/following-sibling::*[(name() = 'f') and (position() = 1)]"],
|
219 |
+
['e ~ f', 'e/following-sibling::f'],
|
220 |
+
['div#container p', "div[@id = 'container']/descendant-or-self::*/p"],
|
221 |
+
];
|
222 |
+
}
|
223 |
+
|
224 |
+
public function getXmlLangTestData()
|
225 |
+
{
|
226 |
+
return [
|
227 |
+
[':lang("EN")', ['first', 'second', 'third', 'fourth']],
|
228 |
+
[':lang("en-us")', ['second', 'fourth']],
|
229 |
+
[':lang(en-nz)', ['third']],
|
230 |
+
[':lang(fr)', ['fifth']],
|
231 |
+
[':lang(ru)', ['sixth']],
|
232 |
+
[":lang('ZH')", ['eighth']],
|
233 |
+
[':lang(de) :lang(zh)', ['eighth']],
|
234 |
+
[':lang(en), :lang(zh)', ['first', 'second', 'third', 'fourth', 'eighth']],
|
235 |
+
[':lang(es)', []],
|
236 |
+
];
|
237 |
+
}
|
238 |
+
|
239 |
+
public function getHtmlIdsTestData()
|
240 |
+
{
|
241 |
+
return [
|
242 |
+
['div', ['outer-div', 'li-div', 'foobar-div']],
|
243 |
+
['DIV', ['outer-div', 'li-div', 'foobar-div']], // case-insensitive in HTML
|
244 |
+
['div div', ['li-div']],
|
245 |
+
['div, div div', ['outer-div', 'li-div', 'foobar-div']],
|
246 |
+
['a[name]', ['name-anchor']],
|
247 |
+
['a[NAme]', ['name-anchor']], // case-insensitive in HTML:
|
248 |
+
['a[rel]', ['tag-anchor', 'nofollow-anchor']],
|
249 |
+
['a[rel="tag"]', ['tag-anchor']],
|
250 |
+
['a[href*="localhost"]', ['tag-anchor']],
|
251 |
+
['a[href*=""]', []],
|
252 |
+
['a[href^="http"]', ['tag-anchor', 'nofollow-anchor']],
|
253 |
+
['a[href^="http:"]', ['tag-anchor']],
|
254 |
+
['a[href^=""]', []],
|
255 |
+
['a[href$="org"]', ['nofollow-anchor']],
|
256 |
+
['a[href$=""]', []],
|
257 |
+
['div[foobar~="bc"]', ['foobar-div']],
|
258 |
+
['div[foobar~="cde"]', ['foobar-div']],
|
259 |
+
['[foobar~="ab bc"]', ['foobar-div']],
|
260 |
+
['[foobar~=""]', []],
|
261 |
+
['[foobar~=" \t"]', []],
|
262 |
+
['div[foobar~="cd"]', []],
|
263 |
+
['*[lang|="En"]', ['second-li']],
|
264 |
+
['[lang|="En-us"]', ['second-li']],
|
265 |
+
// Attribute values are case sensitive
|
266 |
+
['*[lang|="en"]', []],
|
267 |
+
['[lang|="en-US"]', []],
|
268 |
+
['*[lang|="e"]', []],
|
269 |
+
// ... :lang() is not.
|
270 |
+
[':lang("EN")', ['second-li', 'li-div']],
|
271 |
+
['*:lang(en-US)', ['second-li', 'li-div']],
|
272 |
+
[':lang("e")', []],
|
273 |
+
['li:nth-child(3)', ['third-li']],
|
274 |
+
['li:nth-child(10)', []],
|
275 |
+
['li:nth-child(2n)', ['second-li', 'fourth-li', 'sixth-li']],
|
276 |
+
['li:nth-child(even)', ['second-li', 'fourth-li', 'sixth-li']],
|
277 |
+
['li:nth-child(2n+0)', ['second-li', 'fourth-li', 'sixth-li']],
|
278 |
+
['li:nth-child(+2n+1)', ['first-li', 'third-li', 'fifth-li', 'seventh-li']],
|
279 |
+
['li:nth-child(odd)', ['first-li', 'third-li', 'fifth-li', 'seventh-li']],
|
280 |
+
['li:nth-child(2n+4)', ['fourth-li', 'sixth-li']],
|
281 |
+
['li:nth-child(3n+1)', ['first-li', 'fourth-li', 'seventh-li']],
|
282 |
+
['li:nth-child(n)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
283 |
+
['li:nth-child(n-1)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
284 |
+
['li:nth-child(n+1)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
285 |
+
['li:nth-child(n+3)', ['third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
286 |
+
['li:nth-child(-n)', []],
|
287 |
+
['li:nth-child(-n-1)', []],
|
288 |
+
['li:nth-child(-n+1)', ['first-li']],
|
289 |
+
['li:nth-child(-n+3)', ['first-li', 'second-li', 'third-li']],
|
290 |
+
['li:nth-last-child(0)', []],
|
291 |
+
['li:nth-last-child(2n)', ['second-li', 'fourth-li', 'sixth-li']],
|
292 |
+
['li:nth-last-child(even)', ['second-li', 'fourth-li', 'sixth-li']],
|
293 |
+
['li:nth-last-child(2n+2)', ['second-li', 'fourth-li', 'sixth-li']],
|
294 |
+
['li:nth-last-child(n)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
295 |
+
['li:nth-last-child(n-1)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
296 |
+
['li:nth-last-child(n-3)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
297 |
+
['li:nth-last-child(n+1)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li', 'sixth-li', 'seventh-li']],
|
298 |
+
['li:nth-last-child(n+3)', ['first-li', 'second-li', 'third-li', 'fourth-li', 'fifth-li']],
|
299 |
+
['li:nth-last-child(-n)', []],
|
300 |
+
['li:nth-last-child(-n-1)', []],
|
301 |
+
['li:nth-last-child(-n+1)', ['seventh-li']],
|
302 |
+
['li:nth-last-child(-n+3)', ['fifth-li', 'sixth-li', 'seventh-li']],
|
303 |
+
['ol:first-of-type', ['first-ol']],
|
304 |
+
['ol:nth-child(1)', ['first-ol']],
|
305 |
+
['ol:nth-of-type(2)', ['second-ol']],
|
306 |
+
['ol:nth-last-of-type(1)', ['second-ol']],
|
307 |
+
['span:only-child', ['foobar-span']],
|
308 |
+
['li div:only-child', ['li-div']],
|
309 |
+
['div *:only-child', ['li-div', 'foobar-span']],
|
310 |
+
['p:only-of-type', ['paragraph']],
|
311 |
+
['a:empty', ['name-anchor']],
|
312 |
+
['a:EMpty', ['name-anchor']],
|
313 |
+
['li:empty', ['third-li', 'fourth-li', 'fifth-li', 'sixth-li']],
|
314 |
+
[':root', ['html']],
|
315 |
+
['html:root', ['html']],
|
316 |
+
['li:root', []],
|
317 |
+
['* :root', []],
|
318 |
+
['*:contains("link")', ['html', 'outer-div', 'tag-anchor', 'nofollow-anchor']],
|
319 |
+
[':CONtains("link")', ['html', 'outer-div', 'tag-anchor', 'nofollow-anchor']],
|
320 |
+
['*:contains("LInk")', []], // case sensitive
|
321 |
+
['*:contains("e")', ['html', 'nil', 'outer-div', 'first-ol', 'first-li', 'paragraph', 'p-em']],
|
322 |
+
['*:contains("E")', []], // case-sensitive
|
323 |
+
['.a', ['first-ol']],
|
324 |
+
['.b', ['first-ol']],
|
325 |
+
['*.a', ['first-ol']],
|
326 |
+
['ol.a', ['first-ol']],
|
327 |
+
['.c', ['first-ol', 'third-li', 'fourth-li']],
|
328 |
+
['*.c', ['first-ol', 'third-li', 'fourth-li']],
|
329 |
+
['ol *.c', ['third-li', 'fourth-li']],
|
330 |
+
['ol li.c', ['third-li', 'fourth-li']],
|
331 |
+
['li ~ li.c', ['third-li', 'fourth-li']],
|
332 |
+
['ol > li.c', ['third-li', 'fourth-li']],
|
333 |
+
['#first-li', ['first-li']],
|
334 |
+
['li#first-li', ['first-li']],
|
335 |
+
['*#first-li', ['first-li']],
|
336 |
+
['li div', ['li-div']],
|
337 |
+
['li > div', ['li-div']],
|
338 |
+
['div div', ['li-div']],
|
339 |
+
['div > div', []],
|
340 |
+
['div>.c', ['first-ol']],
|
341 |
+
['div > .c', ['first-ol']],
|
342 |
+
['div + div', ['foobar-div']],
|
343 |
+
['a ~ a', ['tag-anchor', 'nofollow-anchor']],
|
344 |
+
['a[rel="tag"] ~ a', ['nofollow-anchor']],
|
345 |
+
['ol#first-ol li:last-child', ['seventh-li']],
|
346 |
+
['ol#first-ol *:last-child', ['li-div', 'seventh-li']],
|
347 |
+
['#outer-div:first-child', ['outer-div']],
|
348 |
+
['#outer-div :first-child', ['name-anchor', 'first-li', 'li-div', 'p-b', 'checkbox-fieldset-disabled', 'area-href']],
|
349 |
+
['a[href]', ['tag-anchor', 'nofollow-anchor']],
|
350 |
+
[':not(*)', []],
|
351 |
+
['a:not([href])', ['name-anchor']],
|
352 |
+
['ol :Not(li[class])', ['first-li', 'second-li', 'li-div', 'fifth-li', 'sixth-li', 'seventh-li']],
|
353 |
+
// HTML-specific
|
354 |
+
[':link', ['link-href', 'tag-anchor', 'nofollow-anchor', 'area-href']],
|
355 |
+
[':visited', []],
|
356 |
+
[':enabled', ['link-href', 'tag-anchor', 'nofollow-anchor', 'checkbox-unchecked', 'text-checked', 'checkbox-checked', 'area-href']],
|
357 |
+
[':disabled', ['checkbox-disabled', 'checkbox-disabled-checked', 'fieldset', 'checkbox-fieldset-disabled']],
|
358 |
+
[':checked', ['checkbox-checked', 'checkbox-disabled-checked']],
|
359 |
+
];
|
360 |
+
}
|
361 |
+
|
362 |
+
public function getHtmlShakespearTestData()
|
363 |
+
{
|
364 |
+
return [
|
365 |
+
['*', 246],
|
366 |
+
['div:contains(CELIA)', 26],
|
367 |
+
['div:only-child', 22], // ?
|
368 |
+
['div:nth-child(even)', 106],
|
369 |
+
['div:nth-child(2n)', 106],
|
370 |
+
['div:nth-child(odd)', 137],
|
371 |
+
['div:nth-child(2n+1)', 137],
|
372 |
+
['div:nth-child(n)', 243],
|
373 |
+
['div:last-child', 53],
|
374 |
+
['div:first-child', 51],
|
375 |
+
['div > div', 242],
|
376 |
+
['div + div', 190],
|
377 |
+
['div ~ div', 190],
|
378 |
+
['body', 1],
|
379 |
+
['body div', 243],
|
380 |
+
['div', 243],
|
381 |
+
['div div', 242],
|
382 |
+
['div div div', 241],
|
383 |
+
['div, div, div', 243],
|
384 |
+
['div, a, span', 243],
|
385 |
+
['.dialog', 51],
|
386 |
+
['div.dialog', 51],
|
387 |
+
['div .dialog', 51],
|
388 |
+
['div.character, div.dialog', 99],
|
389 |
+
['div.direction.dialog', 0],
|
390 |
+
['div.dialog.direction', 0],
|
391 |
+
['div.dialog.scene', 1],
|
392 |
+
['div.scene.scene', 1],
|
393 |
+
['div.scene .scene', 0],
|
394 |
+
['div.direction .dialog ', 0],
|
395 |
+
['div .dialog .direction', 4],
|
396 |
+
['div.dialog .dialog .direction', 4],
|
397 |
+
['#speech5', 1],
|
398 |
+
['div#speech5', 1],
|
399 |
+
['div #speech5', 1],
|
400 |
+
['div.scene div.dialog', 49],
|
401 |
+
['div#scene1 div.dialog div', 142],
|
402 |
+
['#scene1 #speech1', 1],
|
403 |
+
['div[class]', 103],
|
404 |
+
['div[class=dialog]', 50],
|
405 |
+
['div[class^=dia]', 51],
|
406 |
+
['div[class$=log]', 50],
|
407 |
+
['div[class*=sce]', 1],
|
408 |
+
['div[class|=dialog]', 50], // ? Seems right
|
409 |
+
['div[class!=madeup]', 243], // ? Seems right
|
410 |
+
['div[class~=dialog]', 51], // ? Seems right
|
411 |
+
];
|
412 |
+
}
|
413 |
+
}
|
vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php
CHANGED
@@ -26,7 +26,7 @@ abstract class AbstractExtension implements ExtensionInterface
|
|
26 |
/**
|
27 |
* {@inheritdoc}
|
28 |
*/
|
29 |
-
public function getNodeTranslators()
|
30 |
{
|
31 |
return [];
|
32 |
}
|
@@ -34,7 +34,7 @@ abstract class AbstractExtension implements ExtensionInterface
|
|
34 |
/**
|
35 |
* {@inheritdoc}
|
36 |
*/
|
37 |
-
public function getCombinationTranslators()
|
38 |
{
|
39 |
return [];
|
40 |
}
|
@@ -42,7 +42,7 @@ abstract class AbstractExtension implements ExtensionInterface
|
|
42 |
/**
|
43 |
* {@inheritdoc}
|
44 |
*/
|
45 |
-
public function getFunctionTranslators()
|
46 |
{
|
47 |
return [];
|
48 |
}
|
@@ -50,7 +50,7 @@ abstract class AbstractExtension implements ExtensionInterface
|
|
50 |
/**
|
51 |
* {@inheritdoc}
|
52 |
*/
|
53 |
-
public function getPseudoClassTranslators()
|
54 |
{
|
55 |
return [];
|
56 |
}
|
@@ -58,7 +58,7 @@ abstract class AbstractExtension implements ExtensionInterface
|
|
58 |
/**
|
59 |
* {@inheritdoc}
|
60 |
*/
|
61 |
-
public function getAttributeMatchingTranslators()
|
62 |
{
|
63 |
return [];
|
64 |
}
|
26 |
/**
|
27 |
* {@inheritdoc}
|
28 |
*/
|
29 |
+
public function getNodeTranslators()
|
30 |
{
|
31 |
return [];
|
32 |
}
|
34 |
/**
|
35 |
* {@inheritdoc}
|
36 |
*/
|
37 |
+
public function getCombinationTranslators()
|
38 |
{
|
39 |
return [];
|
40 |
}
|
42 |
/**
|
43 |
* {@inheritdoc}
|
44 |
*/
|
45 |
+
public function getFunctionTranslators()
|
46 |
{
|
47 |
return [];
|
48 |
}
|
50 |
/**
|
51 |
* {@inheritdoc}
|
52 |
*/
|
53 |
+
public function getPseudoClassTranslators()
|
54 |
{
|
55 |
return [];
|
56 |
}
|
58 |
/**
|
59 |
* {@inheritdoc}
|
60 |
*/
|
61 |
+
public function getAttributeMatchingTranslators()
|
62 |
{
|
63 |
return [];
|
64 |
}
|
vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php
CHANGED
@@ -29,7 +29,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
-
public function getAttributeMatchingTranslators()
|
33 |
{
|
34 |
return [
|
35 |
'exists' => [$this, 'translateExists'],
|
@@ -43,17 +43,35 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
43 |
];
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
{
|
48 |
return $xpath->addCondition($attribute);
|
49 |
}
|
50 |
|
51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
{
|
53 |
return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value)));
|
54 |
}
|
55 |
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
{
|
58 |
return $xpath->addCondition($value ? sprintf(
|
59 |
'%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)',
|
@@ -62,7 +80,13 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
62 |
) : '0');
|
63 |
}
|
64 |
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
{
|
67 |
return $xpath->addCondition(sprintf(
|
68 |
'%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))',
|
@@ -72,7 +96,13 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
72 |
));
|
73 |
}
|
74 |
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
{
|
77 |
return $xpath->addCondition($value ? sprintf(
|
78 |
'%1$s and starts-with(%1$s, %2$s)',
|
@@ -81,7 +111,13 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
81 |
) : '0');
|
82 |
}
|
83 |
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
{
|
86 |
return $xpath->addCondition($value ? sprintf(
|
87 |
'%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s',
|
@@ -91,7 +127,13 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
91 |
) : '0');
|
92 |
}
|
93 |
|
94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
{
|
96 |
return $xpath->addCondition($value ? sprintf(
|
97 |
'%1$s and contains(%1$s, %2$s)',
|
@@ -100,7 +142,13 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
100 |
) : '0');
|
101 |
}
|
102 |
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
{
|
105 |
return $xpath->addCondition(sprintf(
|
106 |
$value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s',
|
@@ -112,7 +160,7 @@ class AttributeMatchingExtension extends AbstractExtension
|
|
112 |
/**
|
113 |
* {@inheritdoc}
|
114 |
*/
|
115 |
-
public function getName()
|
116 |
{
|
117 |
return 'attribute-matching';
|
118 |
}
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
+
public function getAttributeMatchingTranslators()
|
33 |
{
|
34 |
return [
|
35 |
'exists' => [$this, 'translateExists'],
|
43 |
];
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @param string $attribute
|
48 |
+
* @param string $value
|
49 |
+
*
|
50 |
+
* @return XPathExpr
|
51 |
+
*/
|
52 |
+
public function translateExists(XPathExpr $xpath, $attribute, $value)
|
53 |
{
|
54 |
return $xpath->addCondition($attribute);
|
55 |
}
|
56 |
|
57 |
+
/**
|
58 |
+
* @param string $attribute
|
59 |
+
* @param string $value
|
60 |
+
*
|
61 |
+
* @return XPathExpr
|
62 |
+
*/
|
63 |
+
public function translateEquals(XPathExpr $xpath, $attribute, $value)
|
64 |
{
|
65 |
return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value)));
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* @param string $attribute
|
70 |
+
* @param string $value
|
71 |
+
*
|
72 |
+
* @return XPathExpr
|
73 |
+
*/
|
74 |
+
public function translateIncludes(XPathExpr $xpath, $attribute, $value)
|
75 |
{
|
76 |
return $xpath->addCondition($value ? sprintf(
|
77 |
'%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)',
|
80 |
) : '0');
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* @param string $attribute
|
85 |
+
* @param string $value
|
86 |
+
*
|
87 |
+
* @return XPathExpr
|
88 |
+
*/
|
89 |
+
public function translateDashMatch(XPathExpr $xpath, $attribute, $value)
|
90 |
{
|
91 |
return $xpath->addCondition(sprintf(
|
92 |
'%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))',
|
96 |
));
|
97 |
}
|
98 |
|
99 |
+
/**
|
100 |
+
* @param string $attribute
|
101 |
+
* @param string $value
|
102 |
+
*
|
103 |
+
* @return XPathExpr
|
104 |
+
*/
|
105 |
+
public function translatePrefixMatch(XPathExpr $xpath, $attribute, $value)
|
106 |
{
|
107 |
return $xpath->addCondition($value ? sprintf(
|
108 |
'%1$s and starts-with(%1$s, %2$s)',
|
111 |
) : '0');
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* @param string $attribute
|
116 |
+
* @param string $value
|
117 |
+
*
|
118 |
+
* @return XPathExpr
|
119 |
+
*/
|
120 |
+
public function translateSuffixMatch(XPathExpr $xpath, $attribute, $value)
|
121 |
{
|
122 |
return $xpath->addCondition($value ? sprintf(
|
123 |
'%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s',
|
127 |
) : '0');
|
128 |
}
|
129 |
|
130 |
+
/**
|
131 |
+
* @param string $attribute
|
132 |
+
* @param string $value
|
133 |
+
*
|
134 |
+
* @return XPathExpr
|
135 |
+
*/
|
136 |
+
public function translateSubstringMatch(XPathExpr $xpath, $attribute, $value)
|
137 |
{
|
138 |
return $xpath->addCondition($value ? sprintf(
|
139 |
'%1$s and contains(%1$s, %2$s)',
|
142 |
) : '0');
|
143 |
}
|
144 |
|
145 |
+
/**
|
146 |
+
* @param string $attribute
|
147 |
+
* @param string $value
|
148 |
+
*
|
149 |
+
* @return XPathExpr
|
150 |
+
*/
|
151 |
+
public function translateDifferent(XPathExpr $xpath, $attribute, $value)
|
152 |
{
|
153 |
return $xpath->addCondition(sprintf(
|
154 |
$value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s',
|
160 |
/**
|
161 |
* {@inheritdoc}
|
162 |
*/
|
163 |
+
public function getName()
|
164 |
{
|
165 |
return 'attribute-matching';
|
166 |
}
|
vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php
CHANGED
@@ -28,7 +28,7 @@ class CombinationExtension extends AbstractExtension
|
|
28 |
/**
|
29 |
* {@inheritdoc}
|
30 |
*/
|
31 |
-
public function getCombinationTranslators()
|
32 |
{
|
33 |
return [
|
34 |
' ' => [$this, 'translateDescendant'],
|
@@ -38,17 +38,26 @@ class CombinationExtension extends AbstractExtension
|
|
38 |
];
|
39 |
}
|
40 |
|
41 |
-
|
|
|
|
|
|
|
42 |
{
|
43 |
return $xpath->join('/descendant-or-self::*/', $combinedXpath);
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
{
|
48 |
return $xpath->join('/', $combinedXpath);
|
49 |
}
|
50 |
|
51 |
-
|
|
|
|
|
|
|
52 |
{
|
53 |
return $xpath
|
54 |
->join('/following-sibling::', $combinedXpath)
|
@@ -56,7 +65,10 @@ class CombinationExtension extends AbstractExtension
|
|
56 |
->addCondition('position() = 1');
|
57 |
}
|
58 |
|
59 |
-
|
|
|
|
|
|
|
60 |
{
|
61 |
return $xpath->join('/following-sibling::', $combinedXpath);
|
62 |
}
|
@@ -64,7 +76,7 @@ class CombinationExtension extends AbstractExtension
|
|
64 |
/**
|
65 |
* {@inheritdoc}
|
66 |
*/
|
67 |
-
public function getName()
|
68 |
{
|
69 |
return 'combination';
|
70 |
}
|
28 |
/**
|
29 |
* {@inheritdoc}
|
30 |
*/
|
31 |
+
public function getCombinationTranslators()
|
32 |
{
|
33 |
return [
|
34 |
' ' => [$this, 'translateDescendant'],
|
38 |
];
|
39 |
}
|
40 |
|
41 |
+
/**
|
42 |
+
* @return XPathExpr
|
43 |
+
*/
|
44 |
+
public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath)
|
45 |
{
|
46 |
return $xpath->join('/descendant-or-self::*/', $combinedXpath);
|
47 |
}
|
48 |
|
49 |
+
/**
|
50 |
+
* @return XPathExpr
|
51 |
+
*/
|
52 |
+
public function translateChild(XPathExpr $xpath, XPathExpr $combinedXpath)
|
53 |
{
|
54 |
return $xpath->join('/', $combinedXpath);
|
55 |
}
|
56 |
|
57 |
+
/**
|
58 |
+
* @return XPathExpr
|
59 |
+
*/
|
60 |
+
public function translateDirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath)
|
61 |
{
|
62 |
return $xpath
|
63 |
->join('/following-sibling::', $combinedXpath)
|
65 |
->addCondition('position() = 1');
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* @return XPathExpr
|
70 |
+
*/
|
71 |
+
public function translateIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedXpath)
|
72 |
{
|
73 |
return $xpath->join('/following-sibling::', $combinedXpath);
|
74 |
}
|
76 |
/**
|
77 |
* {@inheritdoc}
|
78 |
*/
|
79 |
+
public function getName()
|
80 |
{
|
81 |
return 'combination';
|
82 |
}
|
vendor/symfony/css-selector/XPath/Extension/ExtensionInterface.php
CHANGED
@@ -30,38 +30,40 @@ interface ExtensionInterface
|
|
30 |
*
|
31 |
* @return callable[]
|
32 |
*/
|
33 |
-
public function getNodeTranslators()
|
34 |
|
35 |
/**
|
36 |
* Returns combination translators.
|
37 |
*
|
38 |
* @return callable[]
|
39 |
*/
|
40 |
-
public function getCombinationTranslators()
|
41 |
|
42 |
/**
|
43 |
* Returns function translators.
|
44 |
*
|
45 |
* @return callable[]
|
46 |
*/
|
47 |
-
public function getFunctionTranslators()
|
48 |
|
49 |
/**
|
50 |
* Returns pseudo-class translators.
|
51 |
*
|
52 |
* @return callable[]
|
53 |
*/
|
54 |
-
public function getPseudoClassTranslators()
|
55 |
|
56 |
/**
|
57 |
* Returns attribute operation translators.
|
58 |
*
|
59 |
* @return callable[]
|
60 |
*/
|
61 |
-
public function getAttributeMatchingTranslators()
|
62 |
|
63 |
/**
|
64 |
* Returns extension name.
|
|
|
|
|
65 |
*/
|
66 |
-
public function getName()
|
67 |
}
|
30 |
*
|
31 |
* @return callable[]
|
32 |
*/
|
33 |
+
public function getNodeTranslators();
|
34 |
|
35 |
/**
|
36 |
* Returns combination translators.
|
37 |
*
|
38 |
* @return callable[]
|
39 |
*/
|
40 |
+
public function getCombinationTranslators();
|
41 |
|
42 |
/**
|
43 |
* Returns function translators.
|
44 |
*
|
45 |
* @return callable[]
|
46 |
*/
|
47 |
+
public function getFunctionTranslators();
|
48 |
|
49 |
/**
|
50 |
* Returns pseudo-class translators.
|
51 |
*
|
52 |
* @return callable[]
|
53 |
*/
|
54 |
+
public function getPseudoClassTranslators();
|
55 |
|
56 |
/**
|
57 |
* Returns attribute operation translators.
|
58 |
*
|
59 |
* @return callable[]
|
60 |
*/
|
61 |
+
public function getAttributeMatchingTranslators();
|
62 |
|
63 |
/**
|
64 |
* Returns extension name.
|
65 |
+
*
|
66 |
+
* @return string
|
67 |
*/
|
68 |
+
public function getName();
|
69 |
}
|
vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php
CHANGED
@@ -33,7 +33,7 @@ class FunctionExtension extends AbstractExtension
|
|
33 |
/**
|
34 |
* {@inheritdoc}
|
35 |
*/
|
36 |
-
public function getFunctionTranslators()
|
37 |
{
|
38 |
return [
|
39 |
'nth-child' => [$this, 'translateNthChild'],
|
@@ -46,12 +46,17 @@ class FunctionExtension extends AbstractExtension
|
|
46 |
}
|
47 |
|
48 |
/**
|
|
|
|
|
|
|
|
|
|
|
49 |
* @throws ExpressionErrorException
|
50 |
*/
|
51 |
-
public function translateNthChild(XPathExpr $xpath, FunctionNode $function,
|
52 |
{
|
53 |
try {
|
54 |
-
|
55 |
} catch (SyntaxErrorException $e) {
|
56 |
throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
|
57 |
}
|
@@ -103,20 +108,28 @@ class FunctionExtension extends AbstractExtension
|
|
103 |
// -1n+6 means elements 6 and previous
|
104 |
}
|
105 |
|
106 |
-
|
|
|
|
|
|
|
107 |
{
|
108 |
return $this->translateNthChild($xpath, $function, true);
|
109 |
}
|
110 |
|
111 |
-
|
|
|
|
|
|
|
112 |
{
|
113 |
return $this->translateNthChild($xpath, $function, false, false);
|
114 |
}
|
115 |
|
116 |
/**
|
|
|
|
|
117 |
* @throws ExpressionErrorException
|
118 |
*/
|
119 |
-
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function)
|
120 |
{
|
121 |
if ('*' === $xpath->getElement()) {
|
122 |
throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.');
|
@@ -126,9 +139,11 @@ class FunctionExtension extends AbstractExtension
|
|
126 |
}
|
127 |
|
128 |
/**
|
|
|
|
|
129 |
* @throws ExpressionErrorException
|
130 |
*/
|
131 |
-
public function translateContains(XPathExpr $xpath, FunctionNode $function)
|
132 |
{
|
133 |
$arguments = $function->getArguments();
|
134 |
foreach ($arguments as $token) {
|
@@ -144,9 +159,11 @@ class FunctionExtension extends AbstractExtension
|
|
144 |
}
|
145 |
|
146 |
/**
|
|
|
|
|
147 |
* @throws ExpressionErrorException
|
148 |
*/
|
149 |
-
public function translateLang(XPathExpr $xpath, FunctionNode $function)
|
150 |
{
|
151 |
$arguments = $function->getArguments();
|
152 |
foreach ($arguments as $token) {
|
@@ -164,7 +181,7 @@ class FunctionExtension extends AbstractExtension
|
|
164 |
/**
|
165 |
* {@inheritdoc}
|
166 |
*/
|
167 |
-
public function getName()
|
168 |
{
|
169 |
return 'function';
|
170 |
}
|
33 |
/**
|
34 |
* {@inheritdoc}
|
35 |
*/
|
36 |
+
public function getFunctionTranslators()
|
37 |
{
|
38 |
return [
|
39 |
'nth-child' => [$this, 'translateNthChild'],
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
+
* @param bool $last
|
50 |
+
* @param bool $addNameTest
|
51 |
+
*
|
52 |
+
* @return XPathExpr
|
53 |
+
*
|
54 |
* @throws ExpressionErrorException
|
55 |
*/
|
56 |
+
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true)
|
57 |
{
|
58 |
try {
|
59 |
+
list($a, $b) = Parser::parseSeries($function->getArguments());
|
60 |
} catch (SyntaxErrorException $e) {
|
61 |
throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
|
62 |
}
|
108 |
// -1n+6 means elements 6 and previous
|
109 |
}
|
110 |
|
111 |
+
/**
|
112 |
+
* @return XPathExpr
|
113 |
+
*/
|
114 |
+
public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function)
|
115 |
{
|
116 |
return $this->translateNthChild($xpath, $function, true);
|
117 |
}
|
118 |
|
119 |
+
/**
|
120 |
+
* @return XPathExpr
|
121 |
+
*/
|
122 |
+
public function translateNthOfType(XPathExpr $xpath, FunctionNode $function)
|
123 |
{
|
124 |
return $this->translateNthChild($xpath, $function, false, false);
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
+
* @return XPathExpr
|
129 |
+
*
|
130 |
* @throws ExpressionErrorException
|
131 |
*/
|
132 |
+
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function)
|
133 |
{
|
134 |
if ('*' === $xpath->getElement()) {
|
135 |
throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.');
|
139 |
}
|
140 |
|
141 |
/**
|
142 |
+
* @return XPathExpr
|
143 |
+
*
|
144 |
* @throws ExpressionErrorException
|
145 |
*/
|
146 |
+
public function translateContains(XPathExpr $xpath, FunctionNode $function)
|
147 |
{
|
148 |
$arguments = $function->getArguments();
|
149 |
foreach ($arguments as $token) {
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
+
* @return XPathExpr
|
163 |
+
*
|
164 |
* @throws ExpressionErrorException
|
165 |
*/
|
166 |
+
public function translateLang(XPathExpr $xpath, FunctionNode $function)
|
167 |
{
|
168 |
$arguments = $function->getArguments();
|
169 |
foreach ($arguments as $token) {
|
181 |
/**
|
182 |
* {@inheritdoc}
|
183 |
*/
|
184 |
+
public function getName()
|
185 |
{
|
186 |
return 'function';
|
187 |
}
|
vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php
CHANGED
@@ -39,7 +39,7 @@ class HtmlExtension extends AbstractExtension
|
|
39 |
/**
|
40 |
* {@inheritdoc}
|
41 |
*/
|
42 |
-
public function getPseudoClassTranslators()
|
43 |
{
|
44 |
return [
|
45 |
'checked' => [$this, 'translateChecked'],
|
@@ -56,14 +56,17 @@ class HtmlExtension extends AbstractExtension
|
|
56 |
/**
|
57 |
* {@inheritdoc}
|
58 |
*/
|
59 |
-
public function getFunctionTranslators()
|
60 |
{
|
61 |
return [
|
62 |
'lang' => [$this, 'translateLang'],
|
63 |
];
|
64 |
}
|
65 |
|
66 |
-
|
|
|
|
|
|
|
67 |
{
|
68 |
return $xpath->addCondition(
|
69 |
'(@checked '
|
@@ -72,12 +75,18 @@ class HtmlExtension extends AbstractExtension
|
|
72 |
);
|
73 |
}
|
74 |
|
75 |
-
|
|
|
|
|
|
|
76 |
{
|
77 |
return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')");
|
78 |
}
|
79 |
|
80 |
-
|
|
|
|
|
|
|
81 |
{
|
82 |
return $xpath->addCondition(
|
83 |
'('
|
@@ -103,7 +112,10 @@ class HtmlExtension extends AbstractExtension
|
|
103 |
// todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any."
|
104 |
}
|
105 |
|
106 |
-
|
|
|
|
|
|
|
107 |
{
|
108 |
return $xpath->addCondition(
|
109 |
'('
|
@@ -137,9 +149,11 @@ class HtmlExtension extends AbstractExtension
|
|
137 |
}
|
138 |
|
139 |
/**
|
|
|
|
|
140 |
* @throws ExpressionErrorException
|
141 |
*/
|
142 |
-
public function translateLang(XPathExpr $xpath, FunctionNode $function)
|
143 |
{
|
144 |
$arguments = $function->getArguments();
|
145 |
foreach ($arguments as $token) {
|
@@ -157,22 +171,34 @@ class HtmlExtension extends AbstractExtension
|
|
157 |
));
|
158 |
}
|
159 |
|
160 |
-
|
|
|
|
|
|
|
161 |
{
|
162 |
return $xpath->addCondition("(@selected and name(.) = 'option')");
|
163 |
}
|
164 |
|
165 |
-
|
|
|
|
|
|
|
166 |
{
|
167 |
return $xpath->addCondition('0');
|
168 |
}
|
169 |
|
170 |
-
|
|
|
|
|
|
|
171 |
{
|
172 |
return $xpath->addCondition('0');
|
173 |
}
|
174 |
|
175 |
-
|
|
|
|
|
|
|
176 |
{
|
177 |
return $xpath->addCondition('0');
|
178 |
}
|
@@ -180,7 +206,7 @@ class HtmlExtension extends AbstractExtension
|
|
180 |
/**
|
181 |
* {@inheritdoc}
|
182 |
*/
|
183 |
-
public function getName()
|
184 |
{
|
185 |
return 'html';
|
186 |
}
|
39 |
/**
|
40 |
* {@inheritdoc}
|
41 |
*/
|
42 |
+
public function getPseudoClassTranslators()
|
43 |
{
|
44 |
return [
|
45 |
'checked' => [$this, 'translateChecked'],
|
56 |
/**
|
57 |
* {@inheritdoc}
|
58 |
*/
|
59 |
+
public function getFunctionTranslators()
|
60 |
{
|
61 |
return [
|
62 |
'lang' => [$this, 'translateLang'],
|
63 |
];
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
* @return XPathExpr
|
68 |
+
*/
|
69 |
+
public function translateChecked(XPathExpr $xpath)
|
70 |
{
|
71 |
return $xpath->addCondition(
|
72 |
'(@checked '
|
75 |
);
|
76 |
}
|
77 |
|
78 |
+
/**
|
79 |
+
* @return XPathExpr
|
80 |
+
*/
|
81 |
+
public function translateLink(XPathExpr $xpath)
|
82 |
{
|
83 |
return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')");
|
84 |
}
|
85 |
|
86 |
+
/**
|
87 |
+
* @return XPathExpr
|
88 |
+
*/
|
89 |
+
public function translateDisabled(XPathExpr $xpath)
|
90 |
{
|
91 |
return $xpath->addCondition(
|
92 |
'('
|
112 |
// todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any."
|
113 |
}
|
114 |
|
115 |
+
/**
|
116 |
+
* @return XPathExpr
|
117 |
+
*/
|
118 |
+
public function translateEnabled(XPathExpr $xpath)
|
119 |
{
|
120 |
return $xpath->addCondition(
|
121 |
'('
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
+
* @return XPathExpr
|
153 |
+
*
|
154 |
* @throws ExpressionErrorException
|
155 |
*/
|
156 |
+
public function translateLang(XPathExpr $xpath, FunctionNode $function)
|
157 |
{
|
158 |
$arguments = $function->getArguments();
|
159 |
foreach ($arguments as $token) {
|
171 |
));
|
172 |
}
|
173 |
|
174 |
+
/**
|
175 |
+
* @return XPathExpr
|
176 |
+
*/
|
177 |
+
public function translateSelected(XPathExpr $xpath)
|
178 |
{
|
179 |
return $xpath->addCondition("(@selected and name(.) = 'option')");
|
180 |
}
|
181 |
|
182 |
+
/**
|
183 |
+
* @return XPathExpr
|
184 |
+
*/
|
185 |
+
public function translateInvalid(XPathExpr $xpath)
|
186 |
{
|
187 |
return $xpath->addCondition('0');
|
188 |
}
|
189 |
|
190 |
+
/**
|
191 |
+
* @return XPathExpr
|
192 |
+
*/
|
193 |
+
public function translateHover(XPathExpr $xpath)
|
194 |
{
|
195 |
return $xpath->addCondition('0');
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* @return XPathExpr
|
200 |
+
*/
|
201 |
+
public function translateVisited(XPathExpr $xpath)
|
202 |
{
|
203 |
return $xpath->addCondition('0');
|
204 |
}
|
206 |
/**
|
207 |
* {@inheritdoc}
|
208 |
*/
|
209 |
+
public function getName()
|
210 |
{
|
211 |
return 'html';
|
212 |
}
|
vendor/symfony/css-selector/XPath/Extension/NodeExtension.php
CHANGED
@@ -27,21 +27,27 @@ use Symfony\Component\CssSelector\XPath\XPathExpr;
|
|
27 |
*/
|
28 |
class NodeExtension extends AbstractExtension
|
29 |
{
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
|
34 |
private $flags;
|
35 |
|
36 |
-
|
|
|
|
|
|
|
37 |
{
|
38 |
$this->flags = $flags;
|
39 |
}
|
40 |
|
41 |
/**
|
|
|
|
|
|
|
42 |
* @return $this
|
43 |
*/
|
44 |
-
public function setFlag(
|
45 |
{
|
46 |
if ($on && !$this->hasFlag($flag)) {
|
47 |
$this->flags += $flag;
|
@@ -54,7 +60,12 @@ class NodeExtension extends AbstractExtension
|
|
54 |
return $this;
|
55 |
}
|
56 |
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
58 |
{
|
59 |
return (bool) ($this->flags & $flag);
|
60 |
}
|
@@ -62,7 +73,7 @@ class NodeExtension extends AbstractExtension
|
|
62 |
/**
|
63 |
* {@inheritdoc}
|
64 |
*/
|
65 |
-
public function getNodeTranslators()
|
66 |
{
|
67 |
return [
|
68 |
'Selector' => [$this, 'translateSelector'],
|
@@ -77,17 +88,26 @@ class NodeExtension extends AbstractExtension
|
|
77 |
];
|
78 |
}
|
79 |
|
80 |
-
|
|
|
|
|
|
|
81 |
{
|
82 |
return $translator->nodeToXPath($node->getTree());
|
83 |
}
|
84 |
|
85 |
-
|
|
|
|
|
|
|
86 |
{
|
87 |
return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector());
|
88 |
}
|
89 |
|
90 |
-
|
|
|
|
|
|
|
91 |
{
|
92 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
93 |
$subXpath = $translator->nodeToXPath($node->getSubSelector());
|
@@ -100,21 +120,30 @@ class NodeExtension extends AbstractExtension
|
|
100 |
return $xpath->addCondition('0');
|
101 |
}
|
102 |
|
103 |
-
|
|
|
|
|
|
|
104 |
{
|
105 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
106 |
|
107 |
return $translator->addFunction($xpath, $node);
|
108 |
}
|
109 |
|
110 |
-
|
|
|
|
|
|
|
111 |
{
|
112 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
113 |
|
114 |
return $translator->addPseudoClass($xpath, $node->getIdentifier());
|
115 |
}
|
116 |
|
117 |
-
|
|
|
|
|
|
|
118 |
{
|
119 |
$name = $node->getAttribute();
|
120 |
$safe = $this->isSafeName($name);
|
@@ -139,25 +168,34 @@ class NodeExtension extends AbstractExtension
|
|
139 |
return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value);
|
140 |
}
|
141 |
|
142 |
-
|
|
|
|
|
|
|
143 |
{
|
144 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
145 |
|
146 |
return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName());
|
147 |
}
|
148 |
|
149 |
-
|
|
|
|
|
|
|
150 |
{
|
151 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
152 |
|
153 |
return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId());
|
154 |
}
|
155 |
|
156 |
-
|
|
|
|
|
|
|
157 |
{
|
158 |
$element = $node->getElement();
|
159 |
|
160 |
-
if ($
|
161 |
$element = strtolower($element);
|
162 |
}
|
163 |
|
@@ -185,12 +223,19 @@ class NodeExtension extends AbstractExtension
|
|
185 |
/**
|
186 |
* {@inheritdoc}
|
187 |
*/
|
188 |
-
public function getName()
|
189 |
{
|
190 |
return 'node';
|
191 |
}
|
192 |
|
193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
{
|
195 |
return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name);
|
196 |
}
|
27 |
*/
|
28 |
class NodeExtension extends AbstractExtension
|
29 |
{
|
30 |
+
const ELEMENT_NAME_IN_LOWER_CASE = 1;
|
31 |
+
const ATTRIBUTE_NAME_IN_LOWER_CASE = 2;
|
32 |
+
const ATTRIBUTE_VALUE_IN_LOWER_CASE = 4;
|
33 |
|
34 |
private $flags;
|
35 |
|
36 |
+
/**
|
37 |
+
* @param int $flags
|
38 |
+
*/
|
39 |
+
public function __construct($flags = 0)
|
40 |
{
|
41 |
$this->flags = $flags;
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
+
* @param int $flag
|
46 |
+
* @param bool $on
|
47 |
+
*
|
48 |
* @return $this
|
49 |
*/
|
50 |
+
public function setFlag($flag, $on)
|
51 |
{
|
52 |
if ($on && !$this->hasFlag($flag)) {
|
53 |
$this->flags += $flag;
|
60 |
return $this;
|
61 |
}
|
62 |
|
63 |
+
/**
|
64 |
+
* @param int $flag
|
65 |
+
*
|
66 |
+
* @return bool
|
67 |
+
*/
|
68 |
+
public function hasFlag($flag)
|
69 |
{
|
70 |
return (bool) ($this->flags & $flag);
|
71 |
}
|
73 |
/**
|
74 |
* {@inheritdoc}
|
75 |
*/
|
76 |
+
public function getNodeTranslators()
|
77 |
{
|
78 |
return [
|
79 |
'Selector' => [$this, 'translateSelector'],
|
88 |
];
|
89 |
}
|
90 |
|
91 |
+
/**
|
92 |
+
* @return XPathExpr
|
93 |
+
*/
|
94 |
+
public function translateSelector(Node\SelectorNode $node, Translator $translator)
|
95 |
{
|
96 |
return $translator->nodeToXPath($node->getTree());
|
97 |
}
|
98 |
|
99 |
+
/**
|
100 |
+
* @return XPathExpr
|
101 |
+
*/
|
102 |
+
public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator)
|
103 |
{
|
104 |
return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector());
|
105 |
}
|
106 |
|
107 |
+
/**
|
108 |
+
* @return XPathExpr
|
109 |
+
*/
|
110 |
+
public function translateNegation(Node\NegationNode $node, Translator $translator)
|
111 |
{
|
112 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
113 |
$subXpath = $translator->nodeToXPath($node->getSubSelector());
|
120 |
return $xpath->addCondition('0');
|
121 |
}
|
122 |
|
123 |
+
/**
|
124 |
+
* @return XPathExpr
|
125 |
+
*/
|
126 |
+
public function translateFunction(Node\FunctionNode $node, Translator $translator)
|
127 |
{
|
128 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
129 |
|
130 |
return $translator->addFunction($xpath, $node);
|
131 |
}
|
132 |
|
133 |
+
/**
|
134 |
+
* @return XPathExpr
|
135 |
+
*/
|
136 |
+
public function translatePseudo(Node\PseudoNode $node, Translator $translator)
|
137 |
{
|
138 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
139 |
|
140 |
return $translator->addPseudoClass($xpath, $node->getIdentifier());
|
141 |
}
|
142 |
|
143 |
+
/**
|
144 |
+
* @return XPathExpr
|
145 |
+
*/
|
146 |
+
public function translateAttribute(Node\AttributeNode $node, Translator $translator)
|
147 |
{
|
148 |
$name = $node->getAttribute();
|
149 |
$safe = $this->isSafeName($name);
|
168 |
return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value);
|
169 |
}
|
170 |
|
171 |
+
/**
|
172 |
+
* @return XPathExpr
|
173 |
+
*/
|
174 |
+
public function translateClass(Node\ClassNode $node, Translator $translator)
|
175 |
{
|
176 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
177 |
|
178 |
return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName());
|
179 |
}
|
180 |
|
181 |
+
/**
|
182 |
+
* @return XPathExpr
|
183 |
+
*/
|
184 |
+
public function translateHash(Node\HashNode $node, Translator $translator)
|
185 |
{
|
186 |
$xpath = $translator->nodeToXPath($node->getSelector());
|
187 |
|
188 |
return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId());
|
189 |
}
|
190 |
|
191 |
+
/**
|
192 |
+
* @return XPathExpr
|
193 |
+
*/
|
194 |
+
public function translateElement(Node\ElementNode $node)
|
195 |
{
|
196 |
$element = $node->getElement();
|
197 |
|
198 |
+
if ($this->hasFlag(self::ELEMENT_NAME_IN_LOWER_CASE)) {
|
199 |
$element = strtolower($element);
|
200 |
}
|
201 |
|
223 |
/**
|
224 |
* {@inheritdoc}
|
225 |
*/
|
226 |
+
public function getName()
|
227 |
{
|
228 |
return 'node';
|
229 |
}
|
230 |
|
231 |
+
/**
|
232 |
+
* Tests if given name is safe.
|
233 |
+
*
|
234 |
+
* @param string $name
|
235 |
+
*
|
236 |
+
* @return bool
|
237 |
+
*/
|
238 |
+
private function isSafeName($name)
|
239 |
{
|
240 |
return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name);
|
241 |
}
|
vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php
CHANGED
@@ -29,7 +29,7 @@ class PseudoClassExtension extends AbstractExtension
|
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
-
public function getPseudoClassTranslators()
|
33 |
{
|
34 |
return [
|
35 |
'root' => [$this, 'translateRoot'],
|
@@ -43,12 +43,18 @@ class PseudoClassExtension extends AbstractExtension
|
|
43 |
];
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
{
|
48 |
return $xpath->addCondition('not(parent::*)');
|
49 |
}
|
50 |
|
51 |
-
|
|
|
|
|
|
|
52 |
{
|
53 |
return $xpath
|
54 |
->addStarPrefix()
|
@@ -56,7 +62,10 @@ class PseudoClassExtension extends AbstractExtension
|
|
56 |
->addCondition('position() = 1');
|
57 |
}
|
58 |
|
59 |
-
|
|
|
|
|
|
|
60 |
{
|
61 |
return $xpath
|
62 |
->addStarPrefix()
|
@@ -65,9 +74,11 @@ class PseudoClassExtension extends AbstractExtension
|
|
65 |
}
|
66 |
|
67 |
/**
|
|
|
|
|
68 |
* @throws ExpressionErrorException
|
69 |
*/
|
70 |
-
public function translateFirstOfType(XPathExpr $xpath)
|
71 |
{
|
72 |
if ('*' === $xpath->getElement()) {
|
73 |
throw new ExpressionErrorException('"*:first-of-type" is not implemented.');
|
@@ -79,9 +90,11 @@ class PseudoClassExtension extends AbstractExtension
|
|
79 |
}
|
80 |
|
81 |
/**
|
|
|
|
|
82 |
* @throws ExpressionErrorException
|
83 |
*/
|
84 |
-
public function translateLastOfType(XPathExpr $xpath)
|
85 |
{
|
86 |
if ('*' === $xpath->getElement()) {
|
87 |
throw new ExpressionErrorException('"*:last-of-type" is not implemented.');
|
@@ -92,7 +105,10 @@ class PseudoClassExtension extends AbstractExtension
|
|
92 |
->addCondition('position() = last()');
|
93 |
}
|
94 |
|
95 |
-
|
|
|
|
|
|
|
96 |
{
|
97 |
return $xpath
|
98 |
->addStarPrefix()
|
@@ -100,14 +116,26 @@ class PseudoClassExtension extends AbstractExtension
|
|
100 |
->addCondition('last() = 1');
|
101 |
}
|
102 |
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
104 |
{
|
105 |
$element = $xpath->getElement();
|
106 |
|
|
|
|
|
|
|
|
|
107 |
return $xpath->addCondition(sprintf('count(preceding-sibling::%s)=0 and count(following-sibling::%s)=0', $element, $element));
|
108 |
}
|
109 |
|
110 |
-
|
|
|
|
|
|
|
111 |
{
|
112 |
return $xpath->addCondition('not(*) and not(string-length())');
|
113 |
}
|
@@ -115,7 +143,7 @@ class PseudoClassExtension extends AbstractExtension
|
|
115 |
/**
|
116 |
* {@inheritdoc}
|
117 |
*/
|
118 |
-
public function getName()
|
119 |
{
|
120 |
return 'pseudo-class';
|
121 |
}
|
29 |
/**
|
30 |
* {@inheritdoc}
|
31 |
*/
|
32 |
+
public function getPseudoClassTranslators()
|
33 |
{
|
34 |
return [
|
35 |
'root' => [$this, 'translateRoot'],
|
43 |
];
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* @return XPathExpr
|
48 |
+
*/
|
49 |
+
public function translateRoot(XPathExpr $xpath)
|
50 |
{
|
51 |
return $xpath->addCondition('not(parent::*)');
|
52 |
}
|
53 |
|
54 |
+
/**
|
55 |
+
* @return XPathExpr
|
56 |
+
*/
|
57 |
+
public function translateFirstChild(XPathExpr $xpath)
|
58 |
{
|
59 |
return $xpath
|
60 |
->addStarPrefix()
|
62 |
->addCondition('position() = 1');
|
63 |
}
|
64 |
|
65 |
+
/**
|
66 |
+
* @return XPathExpr
|
67 |
+
*/
|
68 |
+
public function translateLastChild(XPathExpr $xpath)
|
69 |
{
|
70 |
return $xpath
|
71 |
->addStarPrefix()
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
+
* @return XPathExpr
|
78 |
+
*
|
79 |
* @throws ExpressionErrorException
|
80 |
*/
|
81 |
+
public function translateFirstOfType(XPathExpr $xpath)
|
82 |
{
|
83 |
if ('*' === $xpath->getElement()) {
|
84 |
throw new ExpressionErrorException('"*:first-of-type" is not implemented.');
|
90 |
}
|
91 |
|
92 |
/**
|
93 |
+
* @return XPathExpr
|
94 |
+
*
|
95 |
* @throws ExpressionErrorException
|
96 |
*/
|
97 |
+
public function translateLastOfType(XPathExpr $xpath)
|
98 |
{
|
99 |
if ('*' === $xpath->getElement()) {
|
100 |
throw new ExpressionErrorException('"*:last-of-type" is not implemented.');
|
105 |
->addCondition('position() = last()');
|
106 |
}
|
107 |
|
108 |
+
/**
|
109 |
+
* @return XPathExpr
|
110 |
+
*/
|
111 |
+
public function translateOnlyChild(XPathExpr $xpath)
|
112 |
{
|
113 |
return $xpath
|
114 |
->addStarPrefix()
|
116 |
->addCondition('last() = 1');
|
117 |
}
|
118 |
|
119 |
+
/**
|
120 |
+
* @return XPathExpr
|
121 |
+
*
|
122 |
+
* @throws ExpressionErrorException
|
123 |
+
*/
|
124 |
+
public function translateOnlyOfType(XPathExpr $xpath)
|
125 |
{
|
126 |
$element = $xpath->getElement();
|
127 |
|
128 |
+
if ('*' === $element) {
|
129 |
+
throw new ExpressionErrorException('"*:only-of-type" is not implemented.');
|
130 |
+
}
|
131 |
+
|
132 |
return $xpath->addCondition(sprintf('count(preceding-sibling::%s)=0 and count(following-sibling::%s)=0', $element, $element));
|
133 |
}
|
134 |
|
135 |
+
/**
|
136 |
+
* @return XPathExpr
|
137 |
+
*/
|
138 |
+
public function translateEmpty(XPathExpr $xpath)
|
139 |
{
|
140 |
return $xpath->addCondition('not(*) and not(string-length())');
|
141 |
}
|
143 |
/**
|
144 |
* {@inheritdoc}
|
145 |
*/
|
146 |
+
public function getName()
|
147 |
{
|
148 |
return 'pseudo-class';
|
149 |
}
|
vendor/symfony/css-selector/XPath/Translator.php
CHANGED
@@ -50,7 +50,7 @@ class Translator implements TranslatorInterface
|
|
50 |
|
51 |
public function __construct(ParserInterface $parser = null)
|
52 |
{
|
53 |
-
$this->mainParser = $parser
|
54 |
|
55 |
$this
|
56 |
->registerExtension(new Extension\NodeExtension())
|
@@ -61,7 +61,12 @@ class Translator implements TranslatorInterface
|
|
61 |
;
|
62 |
}
|
63 |
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
65 |
{
|
66 |
if (false === strpos($element, "'")) {
|
67 |
return "'".$element."'";
|
@@ -90,7 +95,7 @@ class Translator implements TranslatorInterface
|
|
90 |
/**
|
91 |
* {@inheritdoc}
|
92 |
*/
|
93 |
-
public function cssToXPath(
|
94 |
{
|
95 |
$selectors = $this->parseSelectors($cssExpr);
|
96 |
|
@@ -109,15 +114,17 @@ class Translator implements TranslatorInterface
|
|
109 |
/**
|
110 |
* {@inheritdoc}
|
111 |
*/
|
112 |
-
public function selectorToXPath(SelectorNode $selector,
|
113 |
{
|
114 |
return ($prefix ?: '').$this->nodeToXPath($selector);
|
115 |
}
|
116 |
|
117 |
/**
|
|
|
|
|
118 |
* @return $this
|
119 |
*/
|
120 |
-
public function registerExtension(Extension\ExtensionInterface $extension)
|
121 |
{
|
122 |
$this->extensions[$extension->getName()] = $extension;
|
123 |
|
@@ -131,9 +138,13 @@ class Translator implements TranslatorInterface
|
|
131 |
}
|
132 |
|
133 |
/**
|
|
|
|
|
|
|
|
|
134 |
* @throws ExpressionErrorException
|
135 |
*/
|
136 |
-
public function getExtension(
|
137 |
{
|
138 |
if (!isset($this->extensions[$name])) {
|
139 |
throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name));
|
@@ -143,9 +154,11 @@ class Translator implements TranslatorInterface
|
|
143 |
}
|
144 |
|
145 |
/**
|
|
|
|
|
146 |
* @return $this
|
147 |
*/
|
148 |
-
public function registerParserShortcut(ParserInterface $shortcut)
|
149 |
{
|
150 |
$this->shortcutParsers[] = $shortcut;
|
151 |
|
@@ -153,69 +166,89 @@ class Translator implements TranslatorInterface
|
|
153 |
}
|
154 |
|
155 |
/**
|
|
|
|
|
156 |
* @throws ExpressionErrorException
|
157 |
*/
|
158 |
-
public function nodeToXPath(NodeInterface $node)
|
159 |
{
|
160 |
if (!isset($this->nodeTranslators[$node->getNodeName()])) {
|
161 |
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
|
162 |
}
|
163 |
|
164 |
-
return $this->nodeTranslators[$node->getNodeName()]
|
165 |
}
|
166 |
|
167 |
/**
|
|
|
|
|
|
|
|
|
168 |
* @throws ExpressionErrorException
|
169 |
*/
|
170 |
-
public function addCombination(
|
171 |
{
|
172 |
if (!isset($this->combinationTranslators[$combiner])) {
|
173 |
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
|
174 |
}
|
175 |
|
176 |
-
return $this->combinationTranslators[$combiner]
|
177 |
}
|
178 |
|
179 |
/**
|
|
|
|
|
180 |
* @throws ExpressionErrorException
|
181 |
*/
|
182 |
-
public function addFunction(XPathExpr $xpath, FunctionNode $function)
|
183 |
{
|
184 |
if (!isset($this->functionTranslators[$function->getName()])) {
|
185 |
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
|
186 |
}
|
187 |
|
188 |
-
return $this->functionTranslators[$function->getName()]
|
189 |
}
|
190 |
|
191 |
/**
|
|
|
|
|
|
|
|
|
192 |
* @throws ExpressionErrorException
|
193 |
*/
|
194 |
-
public function addPseudoClass(XPathExpr $xpath,
|
195 |
{
|
196 |
if (!isset($this->pseudoClassTranslators[$pseudoClass])) {
|
197 |
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
|
198 |
}
|
199 |
|
200 |
-
return $this->pseudoClassTranslators[$pseudoClass]
|
201 |
}
|
202 |
|
203 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
* @throws ExpressionErrorException
|
205 |
*/
|
206 |
-
public function addAttributeMatching(XPathExpr $xpath,
|
207 |
{
|
208 |
if (!isset($this->attributeMatchingTranslators[$operator])) {
|
209 |
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
|
210 |
}
|
211 |
|
212 |
-
return $this->attributeMatchingTranslators[$operator]
|
213 |
}
|
214 |
|
215 |
/**
|
|
|
|
|
216 |
* @return SelectorNode[]
|
217 |
*/
|
218 |
-
private function parseSelectors(
|
219 |
{
|
220 |
foreach ($this->shortcutParsers as $shortcut) {
|
221 |
$tokens = $shortcut->parse($css);
|
50 |
|
51 |
public function __construct(ParserInterface $parser = null)
|
52 |
{
|
53 |
+
$this->mainParser = $parser ?: new Parser();
|
54 |
|
55 |
$this
|
56 |
->registerExtension(new Extension\NodeExtension())
|
61 |
;
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* @param string $element
|
66 |
+
*
|
67 |
+
* @return string
|
68 |
+
*/
|
69 |
+
public static function getXpathLiteral($element)
|
70 |
{
|
71 |
if (false === strpos($element, "'")) {
|
72 |
return "'".$element."'";
|
95 |
/**
|
96 |
* {@inheritdoc}
|
97 |
*/
|
98 |
+
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::')
|
99 |
{
|
100 |
$selectors = $this->parseSelectors($cssExpr);
|
101 |
|
114 |
/**
|
115 |
* {@inheritdoc}
|
116 |
*/
|
117 |
+
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::')
|
118 |
{
|
119 |
return ($prefix ?: '').$this->nodeToXPath($selector);
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Registers an extension.
|
124 |
+
*
|
125 |
* @return $this
|
126 |
*/
|
127 |
+
public function registerExtension(Extension\ExtensionInterface $extension)
|
128 |
{
|
129 |
$this->extensions[$extension->getName()] = $extension;
|
130 |
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* @param string $name
|
142 |
+
*
|
143 |
+
* @return Extension\ExtensionInterface
|
144 |
+
*
|
145 |
* @throws ExpressionErrorException
|
146 |
*/
|
147 |
+
public function getExtension($name)
|
148 |
{
|
149 |
if (!isset($this->extensions[$name])) {
|
150 |
throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name));
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
+
* Registers a shortcut parser.
|
158 |
+
*
|
159 |
* @return $this
|
160 |
*/
|
161 |
+
public function registerParserShortcut(ParserInterface $shortcut)
|
162 |
{
|
163 |
$this->shortcutParsers[] = $shortcut;
|
164 |
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
+
* @return XPathExpr
|
170 |
+
*
|
171 |
* @throws ExpressionErrorException
|
172 |
*/
|
173 |
+
public function nodeToXPath(NodeInterface $node)
|
174 |
{
|
175 |
if (!isset($this->nodeTranslators[$node->getNodeName()])) {
|
176 |
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
|
177 |
}
|
178 |
|
179 |
+
return \call_user_func($this->nodeTranslators[$node->getNodeName()], $node, $this);
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
+
* @param string $combiner
|
184 |
+
*
|
185 |
+
* @return XPathExpr
|
186 |
+
*
|
187 |
* @throws ExpressionErrorException
|
188 |
*/
|
189 |
+
public function addCombination($combiner, NodeInterface $xpath, NodeInterface $combinedXpath)
|
190 |
{
|
191 |
if (!isset($this->combinationTranslators[$combiner])) {
|
192 |
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
|
193 |
}
|
194 |
|
195 |
+
return \call_user_func($this->combinationTranslators[$combiner], $this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath));
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* @return XPathExpr
|
200 |
+
*
|
201 |
* @throws ExpressionErrorException
|
202 |
*/
|
203 |
+
public function addFunction(XPathExpr $xpath, FunctionNode $function)
|
204 |
{
|
205 |
if (!isset($this->functionTranslators[$function->getName()])) {
|
206 |
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
|
207 |
}
|
208 |
|
209 |
+
return \call_user_func($this->functionTranslators[$function->getName()], $xpath, $function);
|
210 |
}
|
211 |
|
212 |
/**
|
213 |
+
* @param string $pseudoClass
|
214 |
+
*
|
215 |
+
* @return XPathExpr
|
216 |
+
*
|
217 |
* @throws ExpressionErrorException
|
218 |
*/
|
219 |
+
public function addPseudoClass(XPathExpr $xpath, $pseudoClass)
|
220 |
{
|
221 |
if (!isset($this->pseudoClassTranslators[$pseudoClass])) {
|
222 |
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
|
223 |
}
|
224 |
|
225 |
+
return \call_user_func($this->pseudoClassTranslators[$pseudoClass], $xpath);
|
226 |
}
|
227 |
|
228 |
/**
|
229 |
+
* @param string $operator
|
230 |
+
* @param string $attribute
|
231 |
+
* @param string $value
|
232 |
+
*
|
233 |
+
* @return XPathExpr
|
234 |
+
*
|
235 |
* @throws ExpressionErrorException
|
236 |
*/
|
237 |
+
public function addAttributeMatching(XPathExpr $xpath, $operator, $attribute, $value)
|
238 |
{
|
239 |
if (!isset($this->attributeMatchingTranslators[$operator])) {
|
240 |
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
|
241 |
}
|
242 |
|
243 |
+
return \call_user_func($this->attributeMatchingTranslators[$operator], $xpath, $attribute, $value);
|
244 |
}
|
245 |
|
246 |
/**
|
247 |
+
* @param string $css
|
248 |
+
*
|
249 |
* @return SelectorNode[]
|
250 |
*/
|
251 |
+
private function parseSelectors($css)
|
252 |
{
|
253 |
foreach ($this->shortcutParsers as $shortcut) {
|
254 |
$tokens = $shortcut->parse($css);
|
vendor/symfony/css-selector/XPath/TranslatorInterface.php
CHANGED
@@ -27,11 +27,20 @@ interface TranslatorInterface
|
|
27 |
{
|
28 |
/**
|
29 |
* Translates a CSS selector to an XPath expression.
|
|
|
|
|
|
|
|
|
|
|
30 |
*/
|
31 |
-
public function cssToXPath(
|
32 |
|
33 |
/**
|
34 |
* Translates a parsed selector node to an XPath expression.
|
|
|
|
|
|
|
|
|
35 |
*/
|
36 |
-
public function selectorToXPath(SelectorNode $selector,
|
37 |
}
|
27 |
{
|
28 |
/**
|
29 |
* Translates a CSS selector to an XPath expression.
|
30 |
+
*
|
31 |
+
* @param string $cssExpr
|
32 |
+
* @param string $prefix
|
33 |
+
*
|
34 |
+
* @return string
|
35 |
*/
|
36 |
+
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::');
|
37 |
|
38 |
/**
|
39 |
* Translates a parsed selector node to an XPath expression.
|
40 |
+
*
|
41 |
+
* @param string $prefix
|
42 |
+
*
|
43 |
+
* @return string
|
44 |
*/
|
45 |
+
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::');
|
46 |
}
|
vendor/symfony/css-selector/XPath/XPathExpr.php
CHANGED
@@ -27,7 +27,13 @@ class XPathExpr
|
|
27 |
private $element;
|
28 |
private $condition;
|
29 |
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
{
|
32 |
$this->path = $path;
|
33 |
$this->element = $element;
|
@@ -38,24 +44,36 @@ class XPathExpr
|
|
38 |
}
|
39 |
}
|
40 |
|
41 |
-
|
|
|
|
|
|
|
42 |
{
|
43 |
return $this->element;
|
44 |
}
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
{
|
48 |
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
|
49 |
|
50 |
return $this;
|
51 |
}
|
52 |
|
53 |
-
|
|
|
|
|
|
|
54 |
{
|
55 |
return $this->condition;
|
56 |
}
|
57 |
|
58 |
-
|
|
|
|
|
|
|
59 |
{
|
60 |
if ('*' !== $this->element) {
|
61 |
$this->addCondition('name() = '.Translator::getXpathLiteral($this->element));
|
@@ -65,7 +83,10 @@ class XPathExpr
|
|
65 |
return $this;
|
66 |
}
|
67 |
|
68 |
-
|
|
|
|
|
|
|
69 |
{
|
70 |
$this->path .= '*/';
|
71 |
|
@@ -75,9 +96,12 @@ class XPathExpr
|
|
75 |
/**
|
76 |
* Joins another XPathExpr with a combiner.
|
77 |
*
|
|
|
|
|
|
|
78 |
* @return $this
|
79 |
*/
|
80 |
-
public function join(
|
81 |
{
|
82 |
$path = $this->__toString().$combiner;
|
83 |
|
@@ -92,7 +116,10 @@ class XPathExpr
|
|
92 |
return $this;
|
93 |
}
|
94 |
|
95 |
-
|
|
|
|
|
|
|
96 |
{
|
97 |
$path = $this->path.$this->element;
|
98 |
$condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']';
|
27 |
private $element;
|
28 |
private $condition;
|
29 |
|
30 |
+
/**
|
31 |
+
* @param string $path
|
32 |
+
* @param string $element
|
33 |
+
* @param string $condition
|
34 |
+
* @param bool $starPrefix
|
35 |
+
*/
|
36 |
+
public function __construct($path = '', $element = '*', $condition = '', $starPrefix = false)
|
37 |
{
|
38 |
$this->path = $path;
|
39 |
$this->element = $element;
|
44 |
}
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* @return string
|
49 |
+
*/
|
50 |
+
public function getElement()
|
51 |
{
|
52 |
return $this->element;
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @return $this
|
57 |
+
*/
|
58 |
+
public function addCondition($condition)
|
59 |
{
|
60 |
$this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition;
|
61 |
|
62 |
return $this;
|
63 |
}
|
64 |
|
65 |
+
/**
|
66 |
+
* @return string
|
67 |
+
*/
|
68 |
+
public function getCondition()
|
69 |
{
|
70 |
return $this->condition;
|
71 |
}
|
72 |
|
73 |
+
/**
|
74 |
+
* @return $this
|
75 |
+
*/
|
76 |
+
public function addNameTest()
|
77 |
{
|
78 |
if ('*' !== $this->element) {
|
79 |
$this->addCondition('name() = '.Translator::getXpathLiteral($this->element));
|
83 |
return $this;
|
84 |
}
|
85 |
|
86 |
+
/**
|
87 |
+
* @return $this
|
88 |
+
*/
|
89 |
+
public function addStarPrefix()
|
90 |
{
|
91 |
$this->path .= '*/';
|
92 |
|
96 |
/**
|
97 |
* Joins another XPathExpr with a combiner.
|
98 |
*
|
99 |
+
* @param string $combiner
|
100 |
+
* @param XPathExpr $expr
|
101 |
+
*
|
102 |
* @return $this
|
103 |
*/
|
104 |
+
public function join($combiner, self $expr)
|
105 |
{
|
106 |
$path = $this->__toString().$combiner;
|
107 |
|
116 |
return $this;
|
117 |
}
|
118 |
|
119 |
+
/**
|
120 |
+
* @return string
|
121 |
+
*/
|
122 |
+
public function __toString()
|
123 |
{
|
124 |
$path = $this->path.$this->element;
|
125 |
$condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']';
|
vendor/symfony/css-selector/composer.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
{
|
2 |
"name": "symfony/css-selector",
|
3 |
"type": "library",
|
4 |
-
"description": "
|
5 |
"keywords": [],
|
6 |
"homepage": "https://symfony.com",
|
7 |
"license": "MIT",
|
@@ -20,7 +20,7 @@
|
|
20 |
}
|
21 |
],
|
22 |
"require": {
|
23 |
-
"php": "
|
24 |
},
|
25 |
"autoload": {
|
26 |
"psr-4": { "Symfony\\Component\\CssSelector\\": "" },
|
1 |
{
|
2 |
"name": "symfony/css-selector",
|
3 |
"type": "library",
|
4 |
+
"description": "Symfony CssSelector Component",
|
5 |
"keywords": [],
|
6 |
"homepage": "https://symfony.com",
|
7 |
"license": "MIT",
|
20 |
}
|
21 |
],
|
22 |
"require": {
|
23 |
+
"php": "^5.5.9|>=7.0.8"
|
24 |
},
|
25 |
"autoload": {
|
26 |
"psr-4": { "Symfony\\Component\\CssSelector\\": "" },
|
vendor/symfony/css-selector/phpunit.xml.dist
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
|
3 |
+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
4 |
+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
|
5 |
+
backupGlobals="false"
|
6 |
+
colors="true"
|
7 |
+
bootstrap="vendor/autoload.php"
|
8 |
+
failOnRisky="true"
|
9 |
+
failOnWarning="true"
|
10 |
+
>
|
11 |
+
<php>
|
12 |
+
<ini name="error_reporting" value="-1" />
|
13 |
+
</php>
|
14 |
+
|
15 |
+
<testsuites>
|
16 |
+
<testsuite name="Symfony CssSelector Component Test Suite">
|
17 |
+
<directory>./Tests/</directory>
|
18 |
+
</testsuite>
|
19 |
+
</testsuites>
|
20 |
+
|
21 |
+
<filter>
|
22 |
+
<whitelist>
|
23 |
+
<directory>./</directory>
|
24 |
+
<exclude>
|
25 |
+
<directory>./Resources</directory>
|
26 |
+
<directory>./Tests</directory>
|
27 |
+
<directory>./vendor</directory>
|
28 |
+
</exclude>
|
29 |
+
</whitelist>
|
30 |
+
</filter>
|
31 |
+
</phpunit>
|
wp-user-avatar.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: ProfilePress
|
4 |
* Plugin URI: https://profilepress.net
|
5 |
* Description: The modern WordPress membership and user profile plugin.
|
6 |
-
* Version: 3.1.
|
7 |
* Author: ProfilePress Team
|
8 |
* Author URI: https://profilepress.net
|
9 |
* Text Domain: wp-user-avatar
|
@@ -14,7 +14,7 @@
|
|
14 |
defined('ABSPATH') or die("No script kiddies please!");
|
15 |
|
16 |
define('PROFILEPRESS_SYSTEM_FILE_PATH', __FILE__);
|
17 |
-
define('PPRESS_VERSION_NUMBER', '3.1.
|
18 |
|
19 |
require __DIR__ . '/vendor/autoload.php';
|
20 |
|
3 |
* Plugin Name: ProfilePress
|
4 |
* Plugin URI: https://profilepress.net
|
5 |
* Description: The modern WordPress membership and user profile plugin.
|
6 |
+
* Version: 3.1.14
|
7 |
* Author: ProfilePress Team
|
8 |
* Author URI: https://profilepress.net
|
9 |
* Text Domain: wp-user-avatar
|
14 |
defined('ABSPATH') or die("No script kiddies please!");
|
15 |
|
16 |
define('PROFILEPRESS_SYSTEM_FILE_PATH', __FILE__);
|
17 |
+
define('PPRESS_VERSION_NUMBER', '3.1.14');
|
18 |
|
19 |
require __DIR__ . '/vendor/autoload.php';
|
20 |
|