Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
46
web/vendor/behat/mink/src/Selector/CssSelector.php
vendored
Normal file
46
web/vendor/behat/mink/src/Selector/CssSelector.php
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
use Symfony\Component\CssSelector\CssSelector as CSS;
|
||||
use Symfony\Component\CssSelector\CssSelectorConverter;
|
||||
|
||||
/**
|
||||
* CSS selector engine. Transforms CSS to XPath.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class CssSelector implements SelectorInterface
|
||||
{
|
||||
/**
|
||||
* Translates CSS into XPath.
|
||||
*
|
||||
* @param string|array $locator current selector locator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function translateToXPath($locator)
|
||||
{
|
||||
if (!is_string($locator)) {
|
||||
throw new \InvalidArgumentException('The CssSelector expects to get a string as locator');
|
||||
}
|
||||
|
||||
// Symfony 2.8+ API
|
||||
if (class_exists('Symfony\Component\CssSelector\CssSelectorConverter')) {
|
||||
$converter = new CssSelectorConverter();
|
||||
|
||||
return $converter->toXPath($locator);
|
||||
}
|
||||
|
||||
// old static API for Symfony 2.7 and older
|
||||
return CSS::toXPath($locator);
|
||||
}
|
||||
}
|
||||
29
web/vendor/behat/mink/src/Selector/ExactNamedSelector.php
vendored
Normal file
29
web/vendor/behat/mink/src/Selector/ExactNamedSelector.php
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
/**
|
||||
* Exact match selector engine. Like the Named selector engine but ignores partial matches.
|
||||
*/
|
||||
class ExactNamedSelector extends NamedSelector
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerReplacement('%tagTextMatch%', 'normalize-space(string(.)) = %locator%');
|
||||
$this->registerReplacement('%valueMatch%', './@value = %locator%');
|
||||
$this->registerReplacement('%titleMatch%', './@title = %locator%');
|
||||
$this->registerReplacement('%altMatch%', './@alt = %locator%');
|
||||
$this->registerReplacement('%relMatch%', './@rel = %locator%');
|
||||
$this->registerReplacement('%labelAttributeMatch%', './@label = %locator%');
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
263
web/vendor/behat/mink/src/Selector/NamedSelector.php
vendored
Normal file
263
web/vendor/behat/mink/src/Selector/NamedSelector.php
vendored
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
use Behat\Mink\Selector\Xpath\Escaper;
|
||||
|
||||
/**
|
||||
* Named selectors engine. Uses registered XPath selectors to create new expressions.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class NamedSelector implements SelectorInterface
|
||||
{
|
||||
private $replacements = array(
|
||||
// simple replacements
|
||||
'%lowercaseType%' => "translate(./@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')",
|
||||
'%lowercaseRole%' => "translate(./@role, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')",
|
||||
'%tagTextMatch%' => 'contains(normalize-space(string(.)), %locator%)',
|
||||
'%labelTextMatch%' => './@id = //label[%tagTextMatch%]/@for',
|
||||
'%idMatch%' => './@id = %locator%',
|
||||
'%valueMatch%' => 'contains(./@value, %locator%)',
|
||||
'%idOrValueMatch%' => '(%idMatch% or %valueMatch%)',
|
||||
'%idOrNameMatch%' => '(%idMatch% or ./@name = %locator%)',
|
||||
'%placeholderMatch%' => './@placeholder = %locator%',
|
||||
'%titleMatch%' => 'contains(./@title, %locator%)',
|
||||
'%altMatch%' => 'contains(./@alt, %locator%)',
|
||||
'%relMatch%' => 'contains(./@rel, %locator%)',
|
||||
'%labelAttributeMatch%' => 'contains(./@label, %locator%)',
|
||||
|
||||
// complex replacements
|
||||
'%inputTypeWithoutPlaceholderFilter%' => "%lowercaseType% = 'radio' or %lowercaseType% = 'checkbox' or %lowercaseType% = 'file'",
|
||||
'%fieldFilterWithPlaceholder%' => 'self::input[not(%inputTypeWithoutPlaceholderFilter%)] | self::textarea',
|
||||
'%fieldMatchWithPlaceholder%' => '(%idOrNameMatch% or %labelTextMatch% or %placeholderMatch%)',
|
||||
'%fieldMatchWithoutPlaceholder%' => '(%idOrNameMatch% or %labelTextMatch%)',
|
||||
'%fieldFilterWithoutPlaceholder%' => 'self::input[%inputTypeWithoutPlaceholderFilter%] | self::select',
|
||||
'%buttonTypeFilter%' => "%lowercaseType% = 'submit' or %lowercaseType% = 'image' or %lowercaseType% = 'button' or %lowercaseType% = 'reset'",
|
||||
'%notFieldTypeFilter%' => "not(%buttonTypeFilter% or %lowercaseType% = 'hidden')",
|
||||
'%buttonMatch%' => '%idOrNameMatch% or %valueMatch% or %titleMatch%',
|
||||
'%linkMatch%' => '(%idMatch% or %tagTextMatch% or %titleMatch% or %relMatch%)',
|
||||
'%imgAltMatch%' => './/img[%altMatch%]',
|
||||
);
|
||||
|
||||
private $selectors = array(
|
||||
'fieldset' => <<<XPATH
|
||||
.//fieldset
|
||||
[(%idMatch% or .//legend[%tagTextMatch%])]
|
||||
XPATH
|
||||
|
||||
,'field' => <<<XPATH
|
||||
.//*
|
||||
[%fieldFilterWithPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//*[%fieldFilterWithPlaceholder%][%notFieldTypeFilter%]
|
||||
|
|
||||
.//*
|
||||
[%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%][%fieldMatchWithoutPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//*[%fieldFilterWithoutPlaceholder%][%notFieldTypeFilter%]
|
||||
XPATH
|
||||
|
||||
,'link' => <<<XPATH
|
||||
.//a
|
||||
[./@href][(%linkMatch% or %imgAltMatch%)]
|
||||
|
|
||||
.//*
|
||||
[%lowercaseRole% = 'link'][(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
|
||||
XPATH
|
||||
|
||||
,'button' => <<<XPATH
|
||||
.//input
|
||||
[%buttonTypeFilter%][(%buttonMatch%)]
|
||||
|
|
||||
.//input
|
||||
[%lowercaseType% = 'image'][%altMatch%]
|
||||
|
|
||||
.//button
|
||||
[(%buttonMatch% or %tagTextMatch%)]
|
||||
|
|
||||
.//*
|
||||
[%lowercaseRole% = 'button'][(%buttonMatch% or %tagTextMatch%)]
|
||||
XPATH
|
||||
|
||||
,'link_or_button' => <<<XPATH
|
||||
.//a
|
||||
[./@href][(%linkMatch% or %imgAltMatch%)]
|
||||
|
|
||||
.//input
|
||||
[%buttonTypeFilter%][(%idOrValueMatch% or %titleMatch%)]
|
||||
|
|
||||
.//input
|
||||
[%lowercaseType% = 'image'][%altMatch%]
|
||||
|
|
||||
.//button
|
||||
[(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
|
||||
|
|
||||
.//*
|
||||
[(%lowercaseRole% = 'button' or %lowercaseRole% = 'link')][(%idOrValueMatch% or %titleMatch% or %tagTextMatch%)]
|
||||
XPATH
|
||||
|
||||
,'content' => <<<XPATH
|
||||
./descendant-or-self::*
|
||||
[%tagTextMatch%]
|
||||
XPATH
|
||||
|
||||
,'select' => <<<XPATH
|
||||
.//select
|
||||
[%fieldMatchWithoutPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//select
|
||||
XPATH
|
||||
|
||||
,'checkbox' => <<<XPATH
|
||||
.//input
|
||||
[%lowercaseType% = 'checkbox'][%fieldMatchWithoutPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'checkbox']
|
||||
XPATH
|
||||
|
||||
,'radio' => <<<XPATH
|
||||
.//input
|
||||
[%lowercaseType% = 'radio'][%fieldMatchWithoutPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'radio']
|
||||
XPATH
|
||||
|
||||
,'file' => <<<XPATH
|
||||
.//input
|
||||
[%lowercaseType% = 'file'][%fieldMatchWithoutPlaceholder%]
|
||||
|
|
||||
.//label[%tagTextMatch%]//.//input[%lowercaseType% = 'file']
|
||||
XPATH
|
||||
|
||||
,'optgroup' => <<<XPATH
|
||||
.//optgroup
|
||||
[%labelAttributeMatch%]
|
||||
XPATH
|
||||
|
||||
,'option' => <<<XPATH
|
||||
.//option
|
||||
[(./@value = %locator% or %tagTextMatch%)]
|
||||
XPATH
|
||||
|
||||
,'table' => <<<XPATH
|
||||
.//table
|
||||
[(%idMatch% or .//caption[%tagTextMatch%])]
|
||||
XPATH
|
||||
,'id' => <<<XPATH
|
||||
.//*[%idMatch%]
|
||||
XPATH
|
||||
,'id_or_name' => <<<XPATH
|
||||
.//*[%idOrNameMatch%]
|
||||
XPATH
|
||||
);
|
||||
private $xpathEscaper;
|
||||
|
||||
/**
|
||||
* Creates selector instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->xpathEscaper = new Escaper();
|
||||
|
||||
foreach ($this->replacements as $from => $to) {
|
||||
$this->replacements[$from] = strtr($to, $this->replacements);
|
||||
}
|
||||
|
||||
foreach ($this->selectors as $alias => $selector) {
|
||||
$this->selectors[$alias] = strtr($selector, $this->replacements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new XPath selector with specified name.
|
||||
*
|
||||
* @param string $name name for selector
|
||||
* @param string $xpath xpath expression
|
||||
*/
|
||||
public function registerNamedXpath($name, $xpath)
|
||||
{
|
||||
$this->selectors[$name] = $xpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates provided locator into XPath.
|
||||
*
|
||||
* @param string|array $locator selector name or array of (selector_name, locator)
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function translateToXPath($locator)
|
||||
{
|
||||
if (2 < count($locator)) {
|
||||
throw new \InvalidArgumentException('NamedSelector expects array(name, locator) as argument');
|
||||
}
|
||||
|
||||
if (2 == count($locator)) {
|
||||
$selector = $locator[0];
|
||||
$locator = $locator[1];
|
||||
} else {
|
||||
$selector = (string) $locator;
|
||||
$locator = null;
|
||||
}
|
||||
|
||||
if (!isset($this->selectors[$selector])) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Unknown named selector provided: "%s". Expected one of (%s)',
|
||||
$selector,
|
||||
implode(', ', array_keys($this->selectors))
|
||||
));
|
||||
}
|
||||
|
||||
$xpath = $this->selectors[$selector];
|
||||
|
||||
if (null !== $locator) {
|
||||
$xpath = strtr($xpath, array('%locator%' => $this->escapeLocator($locator)));
|
||||
}
|
||||
|
||||
return $xpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a replacement in the list of replacements.
|
||||
*
|
||||
* This method must be called in the constructor before calling the parent constructor.
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*/
|
||||
protected function registerReplacement($from, $to)
|
||||
{
|
||||
$this->replacements[$from] = $to;
|
||||
}
|
||||
|
||||
private function escapeLocator($locator)
|
||||
{
|
||||
// If the locator looks like an escaped one, don't escape it again for BC reasons.
|
||||
if (
|
||||
preg_match('/^\'[^\']*+\'$/', $locator)
|
||||
|| (false !== strpos($locator, '\'') && preg_match('/^"[^"]*+"$/', $locator))
|
||||
|| ((8 < $length = strlen($locator)) && 'concat(' === substr($locator, 0, 7) && ')' === $locator[$length - 1])
|
||||
) {
|
||||
@trigger_error(
|
||||
'Passing an escaped locator to the named selector is deprecated as of 1.7 and will be removed in 2.0.'
|
||||
.' Pass the raw value instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
return $locator;
|
||||
}
|
||||
|
||||
return $this->xpathEscaper->escapeLiteral($locator);
|
||||
}
|
||||
}
|
||||
31
web/vendor/behat/mink/src/Selector/PartialNamedSelector.php
vendored
Normal file
31
web/vendor/behat/mink/src/Selector/PartialNamedSelector.php
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
/**
|
||||
* Named selectors engine. Uses registered XPath selectors to create new expressions.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class PartialNamedSelector extends NamedSelector
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerReplacement('%tagTextMatch%', 'contains(normalize-space(string(.)), %locator%)');
|
||||
$this->registerReplacement('%valueMatch%', 'contains(./@value, %locator%)');
|
||||
$this->registerReplacement('%titleMatch%', 'contains(./@title, %locator%)');
|
||||
$this->registerReplacement('%altMatch%', 'contains(./@alt, %locator%)');
|
||||
$this->registerReplacement('%relMatch%', 'contains(./@rel, %locator%)');
|
||||
$this->registerReplacement('%labelAttributeMatch%', 'contains(./@label, %locator%)');
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
}
|
||||
28
web/vendor/behat/mink/src/Selector/SelectorInterface.php
vendored
Normal file
28
web/vendor/behat/mink/src/Selector/SelectorInterface.php
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
/**
|
||||
* Mink selector engine interface.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
interface SelectorInterface
|
||||
{
|
||||
/**
|
||||
* Translates provided locator into XPath.
|
||||
*
|
||||
* @param string|array $locator current selector locator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function translateToXPath($locator);
|
||||
}
|
||||
135
web/vendor/behat/mink/src/Selector/SelectorsHandler.php
vendored
Normal file
135
web/vendor/behat/mink/src/Selector/SelectorsHandler.php
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector;
|
||||
|
||||
use Behat\Mink\Selector\Xpath\Escaper;
|
||||
|
||||
/**
|
||||
* Selectors handler.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class SelectorsHandler
|
||||
{
|
||||
private $selectors;
|
||||
private $escaper;
|
||||
|
||||
/**
|
||||
* Initializes selectors handler.
|
||||
*
|
||||
* @param SelectorInterface[] $selectors default selectors to register
|
||||
*/
|
||||
public function __construct(array $selectors = array())
|
||||
{
|
||||
$this->escaper = new Escaper();
|
||||
|
||||
$this->registerSelector('named_partial', new PartialNamedSelector());
|
||||
$this->registerSelector('named_exact', new ExactNamedSelector());
|
||||
$this->registerSelector('css', new CssSelector());
|
||||
|
||||
foreach ($selectors as $name => $selector) {
|
||||
$this->registerSelector($name, $selector);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new selector engine with specified name.
|
||||
*
|
||||
* @param string $name selector engine name
|
||||
* @param SelectorInterface $selector selector engine instance
|
||||
*/
|
||||
public function registerSelector($name, SelectorInterface $selector)
|
||||
{
|
||||
$this->selectors[$name] = $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether selector with specified name is registered on handler.
|
||||
*
|
||||
* @param string $name selector engine name
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isSelectorRegistered($name)
|
||||
{
|
||||
return isset($this->selectors[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns selector engine with specified name.
|
||||
*
|
||||
* @param string $name selector engine name
|
||||
*
|
||||
* @return SelectorInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getSelector($name)
|
||||
{
|
||||
if ('named' === $name) {
|
||||
@trigger_error(
|
||||
'Using the "named" selector directly from the handler is deprecated as of 1.6 and will be removed in 2.0.'
|
||||
.' Use the "named_partial" or use the "named" selector through the Element API instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
$name = 'named_partial';
|
||||
}
|
||||
|
||||
if (!$this->isSelectorRegistered($name)) {
|
||||
throw new \InvalidArgumentException("Selector \"$name\" is not registered.");
|
||||
}
|
||||
|
||||
return $this->selectors[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates selector with specified name to XPath.
|
||||
*
|
||||
* @param string $selector selector engine name (registered)
|
||||
* @param string|array $locator selector locator (an array or a string depending of the selector being used)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function selectorToXpath($selector, $locator)
|
||||
{
|
||||
if ('xpath' === $selector) {
|
||||
if (!is_string($locator)) {
|
||||
throw new \InvalidArgumentException('The xpath selector expects to get a string as locator');
|
||||
}
|
||||
|
||||
return $locator;
|
||||
}
|
||||
|
||||
return $this->getSelector($selector)->translateToXPath($locator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates string to XPath literal.
|
||||
*
|
||||
* @deprecated since Mink 1.7. Use \Behat\Mink\Selector\Xpath\Escaper::escapeLiteral when building Xpath
|
||||
* or pass the unescaped value when using the named selector.
|
||||
*
|
||||
* @param string $s
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function xpathLiteral($s)
|
||||
{
|
||||
@trigger_error(
|
||||
'The '.__METHOD__.' method is deprecated as of 1.7 and will be removed in 2.0.'
|
||||
.' Use \Behat\Mink\Selector\Xpath\Escaper::escapeLiteral instead when building Xpath'
|
||||
.' or pass the unescaped value when using the named selector.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
return $this->escaper->escapeLiteral($s);
|
||||
}
|
||||
}
|
||||
52
web/vendor/behat/mink/src/Selector/Xpath/Escaper.php
vendored
Normal file
52
web/vendor/behat/mink/src/Selector/Xpath/Escaper.php
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector\Xpath;
|
||||
|
||||
/**
|
||||
* XPath escaper.
|
||||
*
|
||||
* @author Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*/
|
||||
class Escaper
|
||||
{
|
||||
/**
|
||||
* Escapes the string as a XPath literal.
|
||||
*
|
||||
* @param string $s
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function escapeLiteral($s)
|
||||
{
|
||||
if (false === strpos($s, "'")) {
|
||||
return sprintf("'%s'", $s);
|
||||
}
|
||||
|
||||
if (false === strpos($s, '"')) {
|
||||
return sprintf('"%s"', $s);
|
||||
}
|
||||
|
||||
$string = $s;
|
||||
$parts = array();
|
||||
while (true) {
|
||||
if (false !== $pos = strpos($string, "'")) {
|
||||
$parts[] = sprintf("'%s'", substr($string, 0, $pos));
|
||||
$parts[] = "\"'\"";
|
||||
$string = substr($string, $pos + 1);
|
||||
} else {
|
||||
$parts[] = "'$string'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf('concat(%s)', implode($parts, ','));
|
||||
}
|
||||
}
|
||||
69
web/vendor/behat/mink/src/Selector/Xpath/Manipulator.php
vendored
Normal file
69
web/vendor/behat/mink/src/Selector/Xpath/Manipulator.php
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Mink package.
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Behat\Mink\Selector\Xpath;
|
||||
|
||||
/**
|
||||
* XPath manipulation utility.
|
||||
*
|
||||
* @author Graham Bates
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class Manipulator
|
||||
{
|
||||
/**
|
||||
* Regex to find union operators not inside brackets.
|
||||
*/
|
||||
const UNION_PATTERN = '/\|(?![^\[]*\])/';
|
||||
|
||||
/**
|
||||
* Prepends the XPath prefix to the given XPath.
|
||||
*
|
||||
* The returned XPath will match elements matching the XPath inside an element
|
||||
* matching the prefix.
|
||||
*
|
||||
* @param string $xpath
|
||||
* @param string $prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function prepend($xpath, $prefix)
|
||||
{
|
||||
$expressions = array();
|
||||
|
||||
// If the xpath prefix contains a union we need to wrap it in parentheses.
|
||||
if (preg_match(self::UNION_PATTERN, $prefix)) {
|
||||
$prefix = '('.$prefix.')';
|
||||
}
|
||||
|
||||
// Split any unions into individual expressions.
|
||||
foreach (preg_split(self::UNION_PATTERN, $xpath) as $expression) {
|
||||
$expression = trim($expression);
|
||||
$parenthesis = '';
|
||||
|
||||
// If the union is inside some braces, we need to preserve the opening braces and apply
|
||||
// the prefix only inside it.
|
||||
if (preg_match('/^[\(\s*]+/', $expression, $matches)) {
|
||||
$parenthesis = $matches[0];
|
||||
$expression = substr($expression, strlen($parenthesis));
|
||||
}
|
||||
|
||||
// add prefix before element selector
|
||||
if (0 === strpos($expression, '/')) {
|
||||
$expression = $prefix.$expression;
|
||||
} else {
|
||||
$expression = $prefix.'/'.$expression;
|
||||
}
|
||||
$expressions[] = $parenthesis.$expression;
|
||||
}
|
||||
|
||||
return implode(' | ', $expressions);
|
||||
}
|
||||
}
|
||||
Reference in a new issue