From 705c93e8f797a7aa4e4f37fdfd0e49660d43b161 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 16 Nov 2012 18:56:42 +0000 Subject: [PATCH 01/59] Fix crash when loading a DOMDocument node ($loaded not initialised). --- phpQuery/phpQuery/DOMDocumentWrapper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpQuery/phpQuery/DOMDocumentWrapper.php b/phpQuery/phpQuery/DOMDocumentWrapper.php index 47ce35c..a58b1f3 100644 --- a/phpQuery/phpQuery/DOMDocumentWrapper.php +++ b/phpQuery/phpQuery/DOMDocumentWrapper.php @@ -59,6 +59,7 @@ public function load($markup, $contentType = null, $newDocumentID = null) { $this->root = $this->document; $this->charset = $this->document->encoding; // TODO isDocumentFragment + $loaded = true; } else { $loaded = $this->loadMarkup($markup); } @@ -677,4 +678,4 @@ public static function expandEmptyTag($tag, $xml){ } return $xml; } -} \ No newline at end of file +} From 1d1cb898b26693378f07e2a71f92e0ecc4508967 Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Fri, 14 Dec 2012 09:08:40 +0100 Subject: [PATCH 02/59] Removed Zend --- phpQuery/phpQuery/Zend/Exception.php | 30 - phpQuery/phpQuery/Zend/Http/Client.php | 1186 ----------------- .../Zend/Http/Client/Adapter/Exception.php | 33 - .../Zend/Http/Client/Adapter/Interface.php | 78 -- .../Zend/Http/Client/Adapter/Proxy.php | 268 ---- .../Zend/Http/Client/Adapter/Socket.php | 332 ----- .../Zend/Http/Client/Adapter/Test.php | 193 --- .../phpQuery/Zend/Http/Client/Exception.php | 33 - phpQuery/phpQuery/Zend/Http/Cookie.php | 327 ----- phpQuery/phpQuery/Zend/Http/CookieJar.php | 350 ----- phpQuery/phpQuery/Zend/Http/Exception.php | 33 - phpQuery/phpQuery/Zend/Http/Response.php | 625 --------- phpQuery/phpQuery/Zend/Json/Decoder.php | 457 ------- phpQuery/phpQuery/Zend/Json/Encoder.php | 431 ------ phpQuery/phpQuery/Zend/Json/Exception.php | 36 - phpQuery/phpQuery/Zend/Loader.php | 258 ---- phpQuery/phpQuery/Zend/Registry.php | 195 --- phpQuery/phpQuery/Zend/Uri.php | 164 --- phpQuery/phpQuery/Zend/Uri/Exception.php | 37 - phpQuery/phpQuery/Zend/Uri/Http.php | 702 ---------- phpQuery/phpQuery/Zend/Validate/Abstract.php | 348 ----- phpQuery/phpQuery/Zend/Validate/Alnum.php | 120 -- phpQuery/phpQuery/Zend/Validate/Alpha.php | 120 -- phpQuery/phpQuery/Zend/Validate/Barcode.php | 99 -- .../phpQuery/Zend/Validate/Barcode/Ean13.php | 100 -- .../phpQuery/Zend/Validate/Barcode/UpcA.php | 100 -- phpQuery/phpQuery/Zend/Validate/Between.php | 200 --- phpQuery/phpQuery/Zend/Validate/Ccnum.php | 111 -- phpQuery/phpQuery/Zend/Validate/Date.php | 250 ---- phpQuery/phpQuery/Zend/Validate/Digits.php | 100 -- .../phpQuery/Zend/Validate/EmailAddress.php | 245 ---- phpQuery/phpQuery/Zend/Validate/Exception.php | 37 - .../phpQuery/Zend/Validate/File/Count.php | 229 ---- .../phpQuery/Zend/Validate/File/Exists.php | 192 --- .../phpQuery/Zend/Validate/File/Extension.php | 204 --- .../phpQuery/Zend/Validate/File/FilesSize.php | 156 --- .../phpQuery/Zend/Validate/File/ImageSize.php | 335 ----- .../phpQuery/Zend/Validate/File/MimeType.php | 200 --- .../phpQuery/Zend/Validate/File/NotExists.php | 86 -- phpQuery/phpQuery/Zend/Validate/File/Size.php | 308 ----- .../phpQuery/Zend/Validate/File/Upload.php | 216 --- phpQuery/phpQuery/Zend/Validate/Float.php | 75 -- .../phpQuery/Zend/Validate/GreaterThan.php | 114 -- phpQuery/phpQuery/Zend/Validate/Hex.php | 74 - phpQuery/phpQuery/Zend/Validate/Hostname.php | 444 ------ .../phpQuery/Zend/Validate/Hostname/At.php | 50 - .../phpQuery/Zend/Validate/Hostname/Ch.php | 50 - .../phpQuery/Zend/Validate/Hostname/De.php | 58 - .../phpQuery/Zend/Validate/Hostname/Fi.php | 50 - .../phpQuery/Zend/Validate/Hostname/Hu.php | 50 - .../Zend/Validate/Hostname/Interface.php | 52 - .../phpQuery/Zend/Validate/Hostname/Li.php | 50 - .../phpQuery/Zend/Validate/Hostname/No.php | 52 - .../phpQuery/Zend/Validate/Hostname/Se.php | 50 - phpQuery/phpQuery/Zend/Validate/Identical.php | 117 -- phpQuery/phpQuery/Zend/Validate/InArray.php | 138 -- phpQuery/phpQuery/Zend/Validate/Int.php | 75 -- phpQuery/phpQuery/Zend/Validate/Interface.php | 71 - phpQuery/phpQuery/Zend/Validate/Ip.php | 70 - phpQuery/phpQuery/Zend/Validate/LessThan.php | 113 -- phpQuery/phpQuery/Zend/Validate/NotEmpty.php | 74 - phpQuery/phpQuery/Zend/Validate/Regex.php | 125 -- .../phpQuery/Zend/Validate/StringLength.php | 180 --- 63 files changed, 11656 deletions(-) delete mode 100644 phpQuery/phpQuery/Zend/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Adapter/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Adapter/Interface.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Adapter/Proxy.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Adapter/Socket.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Adapter/Test.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Client/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Cookie.php delete mode 100644 phpQuery/phpQuery/Zend/Http/CookieJar.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Http/Response.php delete mode 100644 phpQuery/phpQuery/Zend/Json/Decoder.php delete mode 100644 phpQuery/phpQuery/Zend/Json/Encoder.php delete mode 100644 phpQuery/phpQuery/Zend/Json/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Loader.php delete mode 100644 phpQuery/phpQuery/Zend/Registry.php delete mode 100644 phpQuery/phpQuery/Zend/Uri.php delete mode 100644 phpQuery/phpQuery/Zend/Uri/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Uri/Http.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Abstract.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Alnum.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Alpha.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Barcode.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Barcode/Ean13.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Barcode/UpcA.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Between.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Ccnum.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Date.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Digits.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/EmailAddress.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Exception.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/Count.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/Exists.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/Extension.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/FilesSize.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/ImageSize.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/MimeType.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/NotExists.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/Size.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/File/Upload.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Float.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/GreaterThan.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hex.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/At.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Ch.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/De.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Fi.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Hu.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Interface.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Li.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/No.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Hostname/Se.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Identical.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/InArray.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Int.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Interface.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Ip.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/LessThan.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/NotEmpty.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/Regex.php delete mode 100644 phpQuery/phpQuery/Zend/Validate/StringLength.php diff --git a/phpQuery/phpQuery/Zend/Exception.php b/phpQuery/phpQuery/Zend/Exception.php deleted file mode 100644 index 599d8a0..0000000 --- a/phpQuery/phpQuery/Zend/Exception.php +++ /dev/null @@ -1,30 +0,0 @@ - 5, - 'strictredirects' => false, - 'useragent' => 'Zend_Http_Client', - 'timeout' => 10, - 'adapter' => 'Zend_Http_Client_Adapter_Socket', - 'httpversion' => self::HTTP_1, - 'keepalive' => false, - 'storeresponse' => true, - 'strict' => true - ); - - /** - * The adapter used to preform the actual connection to the server - * - * @var Zend_Http_Client_Adapter_Interface - */ - protected $adapter = null; - - /** - * Request URI - * - * @var Zend_Uri_Http - */ - protected $uri; - - /** - * Associative array of request headers - * - * @var array - */ - protected $headers = array(); - - /** - * HTTP request method - * - * @var string - */ - protected $method = self::GET; - - /** - * Associative array of GET parameters - * - * @var array - */ - protected $paramsGet = array(); - - /** - * Assiciative array of POST parameters - * - * @var array - */ - protected $paramsPost = array(); - - /** - * Request body content type (for POST requests) - * - * @var string - */ - protected $enctype = null; - - /** - * The raw post data to send. Could be set by setRawData($data, $enctype). - * - * @var string - */ - protected $raw_post_data = null; - - /** - * HTTP Authentication settings - * - * Expected to be an associative array with this structure: - * $this->auth = array('user' => 'username', 'password' => 'password', 'type' => 'basic') - * Where 'type' should be one of the supported authentication types (see the AUTH_* - * constants), for example 'basic' or 'digest'. - * - * If null, no authentication will be used. - * - * @var array|null - */ - protected $auth; - - /** - * File upload arrays (used in POST requests) - * - * An associative array, where each element is of the format: - * 'name' => array('filename.txt', 'text/plain', 'This is the actual file contents') - * - * @var array - */ - protected $files = array(); - - /** - * The client's cookie jar - * - * @var Zend_Http_CookieJar - */ - protected $cookiejar = null; - - /** - * The last HTTP request sent by the client, as string - * - * @var string - */ - protected $last_request = null; - - /** - * The last HTTP response received by the client - * - * @var Zend_Http_Response - */ - protected $last_response = null; - - /** - * Redirection counter - * - * @var int - */ - protected $redirectCounter = 0; - - /** - * Fileinfo magic database resource - * - * This varaiable is populated the first time _detectFileMimeType is called - * and is then reused on every call to this method - * - * @var resource - */ - static protected $_fileInfoDb = null; - - /** - * Contructor method. Will create a new HTTP client. Accepts the target - * URL and optionally configuration array. - * - * @param Zend_Uri_Http|string $uri - * @param array $config Configuration key-value pairs. - */ - public function __construct($uri = null, $config = null) - { - if ($uri !== null) $this->setUri($uri); - if ($config !== null) $this->setConfig($config); - } - - /** - * Set the URI for the next request - * - * @param Zend_Uri_Http|string $uri - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setUri($uri) - { - if (is_string($uri)) { - $uri = Zend_Uri::factory($uri); - } - - if (!$uri instanceof Zend_Uri_Http) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('Passed parameter is not a valid HTTP URI.'); - } - - // We have no ports, set the defaults - if (! $uri->getPort()) { - $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80)); - } - - $this->uri = $uri; - - return $this; - } - - /** - * Get the URI for the next request - * - * @param boolean $as_string If true, will return the URI as a string - * @return Zend_Uri_Http|string - */ - public function getUri($as_string = false) - { - if ($as_string && $this->uri instanceof Zend_Uri_Http) { - return $this->uri->__toString(); - } else { - return $this->uri; - } - } - - /** - * Set configuration parameters for this HTTP client - * - * @param array $config - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setConfig($config = array()) - { - if (! is_array($config)) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('Expected array parameter, given ' . gettype($config)); - } - - foreach ($config as $k => $v) - $this->config[strtolower($k)] = $v; - - return $this; - } - - /** - * Set the next request's method - * - * Validated the passed method and sets it. If we have files set for - * POST requests, and the new method is not POST, the files are silently - * dropped. - * - * @param string $method - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setMethod($method = self::GET) - { - $regex = '/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/'; - if (! preg_match($regex, $method)) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("'{$method}' is not a valid HTTP request method."); - } - - if ($method == self::POST && $this->enctype === null) - $this->setEncType(self::ENC_URLENCODED); - - $this->method = $method; - - return $this; - } - - /** - * Set one or more request headers - * - * This function can be used in several ways to set the client's request - * headers: - * 1. By providing two parameters: $name as the header to set (eg. 'Host') - * and $value as it's value (eg. 'www.example.com'). - * 2. By providing a single header string as the only parameter - * eg. 'Host: www.example.com' - * 3. By providing an array of headers as the first parameter - * eg. array('host' => 'www.example.com', 'x-foo: bar'). In This case - * the function will call itself recursively for each array item. - * - * @param string|array $name Header name, full header string ('Header: value') - * or an array of headers - * @param mixed $value Header value or null - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setHeaders($name, $value = null) - { - // If we got an array, go recusive! - if (is_array($name)) { - foreach ($name as $k => $v) { - if (is_string($k)) { - $this->setHeaders($k, $v); - } else { - $this->setHeaders($v, null); - } - } - } else { - // Check if $name needs to be split - if ($value === null && (strpos($name, ':') > 0)) - list($name, $value) = explode(':', $name, 2); - - // Make sure the name is valid if we are in strict mode - if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("{$name} is not a valid HTTP header name"); - } - - $normalized_name = strtolower($name); - - // If $value is null or false, unset the header - if ($value === null || $value === false) { - unset($this->headers[$normalized_name]); - - // Else, set the header - } else { - // Header names are storred lowercase internally. - if (is_string($value)) $value = trim($value); - $this->headers[$normalized_name] = array($name, $value); - } - } - - return $this; - } - - /** - * Get the value of a specific header - * - * Note that if the header has more than one value, an array - * will be returned. - * - * @param string $key - * @return string|array|null The header value or null if it is not set - */ - public function getHeader($key) - { - $key = strtolower($key); - if (isset($this->headers[$key])) { - return $this->headers[$key][1]; - } else { - return null; - } - } - - /** - * Set a GET parameter for the request. Wrapper around _setParameter - * - * @param string|array $name - * @param string $value - * @return Zend_Http_Client - */ - public function setParameterGet($name, $value = null) - { - if (is_array($name)) { - foreach ($name as $k => $v) - $this->_setParameter('GET', $k, $v); - } else { - $this->_setParameter('GET', $name, $value); - } - - return $this; - } - - /** - * Set a POST parameter for the request. Wrapper around _setParameter - * - * @param string|array $name - * @param string $value - * @return Zend_Http_Client - */ - public function setParameterPost($name, $value = null) - { - if (is_array($name)) { - foreach ($name as $k => $v) - $this->_setParameter('POST', $k, $v); - } else { - $this->_setParameter('POST', $name, $value); - } - - return $this; - } - - /** - * Set a GET or POST parameter - used by SetParameterGet and SetParameterPost - * - * @param string $type GET or POST - * @param string $name - * @param string $value - * @return null - */ - protected function _setParameter($type, $name, $value) - { - $parray = array(); - $type = strtolower($type); - switch ($type) { - case 'get': - $parray = &$this->paramsGet; - break; - case 'post': - $parray = &$this->paramsPost; - break; - } - - if ($value === null) { - if (isset($parray[$name])) unset($parray[$name]); - } else { - $parray[$name] = $value; - } - } - - /** - * Get the number of redirections done on the last request - * - * @return int - */ - public function getRedirectionsCount() - { - return $this->redirectCounter; - } - - /** - * Set HTTP authentication parameters - * - * $type should be one of the supported types - see the self::AUTH_* - * constants. - * - * To enable authentication: - * - * $this->setAuth('shahar', 'secret', Zend_Http_Client::AUTH_BASIC); - * - * - * To disable authentication: - * - * $this->setAuth(false); - * - * - * @see http://www.faqs.org/rfcs/rfc2617.html - * @param string|false $user User name or false disable authentication - * @param string $password Password - * @param string $type Authentication type - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setAuth($user, $password = '', $type = self::AUTH_BASIC) - { - // If we got false or null, disable authentication - if ($user === false || $user === null) { - $this->auth = null; - - // Else, set up authentication - } else { - // Check we got a proper authentication type - if (! defined('self::AUTH_' . strtoupper($type))) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Invalid or not supported authentication type: '$type'"); - } - - $this->auth = array( - 'user' => (string) $user, - 'password' => (string) $password, - 'type' => $type - ); - } - - return $this; - } - - /** - * Set the HTTP client's cookie jar. - * - * A cookie jar is an object that holds and maintains cookies across HTTP requests - * and responses. - * - * @param Zend_Http_CookieJar|boolean $cookiejar Existing cookiejar object, true to create a new one, false to disable - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setCookieJar($cookiejar = true) - { - if (! class_exists('Zend_Http_CookieJar')) - require_once 'Zend/Http/CookieJar.php'; - - if ($cookiejar instanceof Zend_Http_CookieJar) { - $this->cookiejar = $cookiejar; - } elseif ($cookiejar === true) { - $this->cookiejar = new Zend_Http_CookieJar(); - } elseif (! $cookiejar) { - $this->cookiejar = null; - } else { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('Invalid parameter type passed as CookieJar'); - } - - return $this; - } - - /** - * Return the current cookie jar or null if none. - * - * @return Zend_Http_CookieJar|null - */ - public function getCookieJar() - { - return $this->cookiejar; - } - - /** - * Add a cookie to the request. If the client has no Cookie Jar, the cookies - * will be added directly to the headers array as "Cookie" headers. - * - * @param Zend_Http_Cookie|string $cookie - * @param string|null $value If "cookie" is a string, this is the cookie value. - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setCookie($cookie, $value = null) - { - if (! class_exists('Zend_Http_Cookie')) - require_once 'Zend/Http/Cookie.php'; - - if (is_array($cookie)) { - foreach ($cookie as $c => $v) { - if (is_string($c)) { - $this->setCookie($c, $v); - } else { - $this->setCookie($v); - } - } - - return $this; - } - - if ($value !== null) $value = urlencode($value); - - if (isset($this->cookiejar)) { - if ($cookie instanceof Zend_Http_Cookie) { - $this->cookiejar->addCookie($cookie); - } elseif (is_string($cookie) && $value !== null) { - $cookie = Zend_Http_Cookie::fromString("{$cookie}={$value}", $this->uri); - $this->cookiejar->addCookie($cookie); - } - } else { - if ($cookie instanceof Zend_Http_Cookie) { - $name = $cookie->getName(); - $value = $cookie->getValue(); - $cookie = $name; - } - - if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})"); - } - - $value = addslashes($value); - - if (! isset($this->headers['cookie'])) $this->headers['cookie'] = array('Cookie', ''); - $this->headers['cookie'][1] .= $cookie . '=' . $value . '; '; - } - - return $this; - } - - /** - * Set a file to upload (using a POST request) - * - * Can be used in two ways: - * - * 1. $data is null (default): $filename is treated as the name if a local file which - * will be read and sent. Will try to guess the content type using mime_content_type(). - * 2. $data is set - $filename is sent as the file name, but $data is sent as the file - * contents and no file is read from the file system. In this case, you need to - * manually set the content-type ($ctype) or it will default to - * application/octet-stream. - * - * @param string $filename Name of file to upload, or name to save as - * @param string $formname Name of form element to send as - * @param string $data Data to send (if null, $filename is read and sent) - * @param string $ctype Content type to use (if $data is set and $ctype is - * null, will be application/octet-stream) - * @return Zend_Http_Client - * @throws Zend_Http_Client_Exception - */ - public function setFileUpload($filename, $formname, $data = null, $ctype = null) - { - if ($data === null) { - if (($data = @file_get_contents($filename)) === false) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Unable to read file '{$filename}' for upload"); - } - - if (! $ctype) $ctype = $this->_detectFileMimeType($filename); - } - - // Force enctype to multipart/form-data - $this->setEncType(self::ENC_FORMDATA); - - $this->files[$formname] = array(basename($filename), $ctype, $data); - - return $this; - } - - /** - * Set the encoding type for POST data - * - * @param string $enctype - * @return Zend_Http_Client - */ - public function setEncType($enctype = self::ENC_URLENCODED) - { - $this->enctype = $enctype; - - return $this; - } - - /** - * Set the raw (already encoded) POST data. - * - * This function is here for two reasons: - * 1. For advanced user who would like to set their own data, already encoded - * 2. For backwards compatibilty: If someone uses the old post($data) method. - * this method will be used to set the encoded data. - * - * @param string $data - * @param string $enctype - * @return Zend_Http_Client - */ - public function setRawData($data, $enctype = null) - { - $this->raw_post_data = $data; - $this->setEncType($enctype); - - return $this; - } - - /** - * Clear all GET and POST parameters - * - * Should be used to reset the request parameters if the client is - * used for several concurrent requests. - * - * @return Zend_Http_Client - */ - public function resetParameters() - { - // Reset parameter data - $this->paramsGet = array(); - $this->paramsPost = array(); - $this->files = array(); - $this->raw_post_data = null; - - // Clear outdated headers - if (isset($this->headers['content-type'])) unset($this->headers['content-type']); - if (isset($this->headers['content-length'])) unset($this->headers['content-length']); - - return $this; - } - - /** - * Get the last HTTP request as string - * - * @return string - */ - public function getLastRequest() - { - return $this->last_request; - } - - /** - * Get the last HTTP response received by this client - * - * If $config['storeresponse'] is set to false, or no response was - * stored yet, will return null - * - * @return Zend_Http_Response or null if none - */ - public function getLastResponse() - { - return $this->last_response; - } - - /** - * Load the connection adapter - * - * While this method is not called more than one for a client, it is - * seperated from ->request() to preserve logic and readability - * - * @param Zend_Http_Client_Adapter_Interface|string $adapter - * @return null - * @throws Zend_Http_Client_Exception - */ - public function setAdapter($adapter) - { - if (is_string($adapter)) { - try { - Zend_Loader::loadClass($adapter); - } catch (Zend_Exception $e) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Unable to load adapter '$adapter': {$e->getMessage()}"); - } - - $adapter = new $adapter; - } - - if (! $adapter instanceof Zend_Http_Client_Adapter_Interface) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('Passed adapter is not a HTTP connection adapter'); - } - - $this->adapter = $adapter; - $config = $this->config; - unset($config['adapter']); - $this->adapter->setConfig($config); - } - - /** - * Send the HTTP request and return an HTTP response object - * - * @param string $method - * @return Zend_Http_Response - * @throws Zend_Http_Client_Exception - */ - public function request($method = null) - { - if (! $this->uri instanceof Zend_Uri_Http) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('No valid URI has been passed to the client'); - } - - if ($method) $this->setMethod($method); - $this->redirectCounter = 0; - $response = null; - - // Make sure the adapter is loaded - if ($this->adapter == null) $this->setAdapter($this->config['adapter']); - - // Send the first request. If redirected, continue. - do { - // Clone the URI and add the additional GET parameters to it - $uri = clone $this->uri; - if (! empty($this->paramsGet)) { - $query = $uri->getQuery(); - if (! empty($query)) $query .= '&'; - $query .= http_build_query($this->paramsGet, null, '&'); - - $uri->setQuery($query); - } - - $body = $this->_prepareBody(); - $headers = $this->_prepareHeaders(); - - // Open the connection, send the request and read the response - $this->adapter->connect($uri->getHost(), $uri->getPort(), - ($uri->getScheme() == 'https' ? true : false)); - - $this->last_request = $this->adapter->write($this->method, - $uri, $this->config['httpversion'], $headers, $body); - - $response = $this->adapter->read(); - if (! $response) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception('Unable to read response, or response is empty'); - } - - $response = Zend_Http_Response::fromString($response); - if ($this->config['storeresponse']) $this->last_response = $response; - - // Load cookies into cookie jar - if (isset($this->cookiejar)) $this->cookiejar->addCookiesFromResponse($response, $uri); - - // If we got redirected, look for the Location header - if ($response->isRedirect() && ($location = $response->getHeader('location'))) { - - // Check whether we send the exact same request again, or drop the parameters - // and send a GET request - if ($response->getStatus() == 303 || - ((! $this->config['strictredirects']) && ($response->getStatus() == 302 || - $response->getStatus() == 301))) { - - $this->resetParameters(); - $this->setMethod(self::GET); - } - - // If we got a well formed absolute URI - if (Zend_Uri_Http::check($location)) { - $this->setHeaders('host', null); - $this->setUri($location); - - } else { - - // Split into path and query and set the query - if (strpos($location, '?') !== false) { - list($location, $query) = explode('?', $location, 2); - } else { - $query = ''; - } - $this->uri->setQuery($query); - - // Else, if we got just an absolute path, set it - if(strpos($location, '/') === 0) { - $this->uri->setPath($location); - - // Else, assume we have a relative path - } else { - // Get the current path directory, removing any trailing slashes - $path = $this->uri->getPath(); - $path = rtrim(substr($path, 0, strrpos($path, '/')), "/"); - $this->uri->setPath($path . '/' . $location); - } - } - ++$this->redirectCounter; - - } else { - // If we didn't get any location, stop redirecting - break; - } - - } while ($this->redirectCounter < $this->config['maxredirects']); - - return $response; - } - - /** - * Prepare the request headers - * - * @return array - */ - protected function _prepareHeaders() - { - $headers = array(); - - // Set the host header - if (! isset($this->headers['host'])) { - $host = $this->uri->getHost(); - - // If the port is not default, add it - if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) || - ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) { - $host .= ':' . $this->uri->getPort(); - } - - $headers[] = "Host: {$host}"; - } - - // Set the connection header - if (! isset($this->headers['connection'])) { - if (! $this->config['keepalive']) $headers[] = "Connection: close"; - } - - // Set the Accept-encoding header if not set - depending on whether - // zlib is available or not. - if (! isset($this->headers['accept-encoding'])) { - if (function_exists('gzinflate')) { - $headers[] = 'Accept-encoding: gzip, deflate'; - } else { - $headers[] = 'Accept-encoding: identity'; - } - } - - // Set the content-type header - if ($this->method == self::POST && - (! isset($this->headers['content-type']) && isset($this->enctype))) { - - $headers[] = "Content-type: {$this->enctype}"; - } - - // Set the user agent header - if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) { - $headers[] = "User-agent: {$this->config['useragent']}"; - } - - // Set HTTP authentication if needed - if (is_array($this->auth)) { - $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']); - $headers[] = "Authorization: {$auth}"; - } - - // Load cookies from cookie jar - if (isset($this->cookiejar)) { - $cookstr = $this->cookiejar->getMatchingCookies($this->uri, - true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT); - - if ($cookstr) $headers[] = "Cookie: {$cookstr}"; - } - - // Add all other user defined headers - foreach ($this->headers as $header) { - list($name, $value) = $header; - if (is_array($value)) - $value = implode(', ', $value); - - $headers[] = "$name: $value"; - } - - return $headers; - } - - /** - * Prepare the request body (for POST and PUT requests) - * - * @return string - * @throws Zend_Http_Client_Exception - */ - protected function _prepareBody() - { - // According to RFC2616, a TRACE request should not have a body. - if ($this->method == self::TRACE) { - return ''; - } - - // If we have raw_post_data set, just use it as the body. - if (isset($this->raw_post_data)) { - $this->setHeaders('Content-length', strlen($this->raw_post_data)); - return $this->raw_post_data; - } - - $body = ''; - - // If we have files to upload, force enctype to multipart/form-data - if (count ($this->files) > 0) $this->setEncType(self::ENC_FORMDATA); - - // If we have POST parameters or files, encode and add them to the body - if (count($this->paramsPost) > 0 || count($this->files) > 0) { - switch($this->enctype) { - case self::ENC_FORMDATA: - // Encode body as multipart/form-data - $boundary = '---ZENDHTTPCLIENT-' . md5(microtime()); - $this->setHeaders('Content-type', self::ENC_FORMDATA . "; boundary={$boundary}"); - - // Get POST parameters and encode them - $params = $this->_getParametersRecursive($this->paramsPost); - foreach ($params as $pp) { - $body .= self::encodeFormData($boundary, $pp[0], $pp[1]); - } - - // Encode files - foreach ($this->files as $name => $file) { - $fhead = array('Content-type' => $file[1]); - $body .= self::encodeFormData($boundary, $name, $file[2], $file[0], $fhead); - } - - $body .= "--{$boundary}--\r\n"; - break; - - case self::ENC_URLENCODED: - // Encode body as application/x-www-form-urlencoded - $this->setHeaders('Content-type', self::ENC_URLENCODED); - $body = http_build_query($this->paramsPost, '', '&'); - break; - - default: - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." . - " Please use Zend_Http_Client::setRawData to send this kind of content."); - break; - } - } - - // Set the content-length if we have a body or if request is POST/PUT - if ($body || $this->method == self::POST || $this->method == self::PUT) { - $this->setHeaders('Content-length', strlen($body)); - } - - return $body; - } - - /** - * Helper method that gets a possibly multi-level parameters array (get or - * post) and flattens it. - * - * The method returns an array of (key, value) pairs (because keys are not - * necessarily unique. If one of the parameters in as array, it will also - * add a [] suffix to the key. - * - * @param array $parray The parameters array - * @param bool $urlencode Whether to urlencode the name and value - * @return array - */ - protected function _getParametersRecursive($parray, $urlencode = false) - { - if (! is_array($parray)) return $parray; - $parameters = array(); - - foreach ($parray as $name => $value) { - if ($urlencode) $name = urlencode($name); - - // If $value is an array, iterate over it - if (is_array($value)) { - $name .= ($urlencode ? '%5B%5D' : '[]'); - foreach ($value as $subval) { - if ($urlencode) $subval = urlencode($subval); - $parameters[] = array($name, $subval); - } - } else { - if ($urlencode) $value = urlencode($value); - $parameters[] = array($name, $value); - } - } - - return $parameters; - } - - /** - * Attempt to detect the MIME type of a file using available extensions - * - * This method will try to detect the MIME type of a file. If the fileinfo - * extension is available, it will be used. If not, the mime_magic - * extension which is deprected but is still available in many PHP setups - * will be tried. - * - * If neither extension is available, the default application/octet-stream - * MIME type will be returned - * - * @param string $file File path - * @return string MIME type - */ - protected function _detectFileMimeType($file) - { - $type = null; - - // First try with fileinfo functions - if (function_exists('finfo_open')) { - if (self::$_fileInfoDb === null) { - self::$_fileInfoDb = @finfo_open(FILEINFO_MIME); - } - - if (self::$_fileInfoDb) { - $type = finfo_file(self::$_fileInfoDb, $file); - } - - } elseif (function_exists('mime_content_type')) { - $type = mime_content_type($file); - } - - // Fallback to the default application/octet-stream - if (! $type) { - $type = 'application/octet-stream'; - } - - return $type; - } - - /** - * Encode data to a multipart/form-data part suitable for a POST request. - * - * @param string $boundary - * @param string $name - * @param mixed $value - * @param string $filename - * @param array $headers Associative array of optional headers @example ("Content-transfer-encoding" => "binary") - * @return string - */ - public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) { - $ret = "--{$boundary}\r\n" . - 'Content-disposition: form-data; name="' . $name .'"'; - - if ($filename) $ret .= '; filename="' . $filename . '"'; - $ret .= "\r\n"; - - foreach ($headers as $hname => $hvalue) { - $ret .= "{$hname}: {$hvalue}\r\n"; - } - $ret .= "\r\n"; - - $ret .= "{$value}\r\n"; - - return $ret; - } - - /** - * Create a HTTP authentication "Authorization:" header according to the - * specified user, password and authentication method. - * - * @see http://www.faqs.org/rfcs/rfc2617.html - * @param string $user - * @param string $password - * @param string $type - * @return string - * @throws Zend_Http_Client_Exception - */ - public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC) - { - $authHeader = null; - - switch ($type) { - case self::AUTH_BASIC: - // In basic authentication, the user name cannot contain ":" - if (strpos($user, ':') !== false) { - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication"); - } - - $authHeader = 'Basic ' . base64_encode($user . ':' . $password); - break; - - //case self::AUTH_DIGEST: - /** - * @todo Implement digest authentication - */ - // break; - - default: - /** @see Zend_Http_Client_Exception */ - require_once 'Zend/Http/Client/Exception.php'; - throw new Zend_Http_Client_Exception("Not a supported HTTP authentication type: '$type'"); - } - - return $authHeader; - } -} diff --git a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Exception.php b/phpQuery/phpQuery/Zend/Http/Client/Adapter/Exception.php deleted file mode 100644 index dfbe904..0000000 --- a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ - 'ssl', - 'proxy_host' => '', - 'proxy_port' => 8080, - 'proxy_user' => '', - 'proxy_pass' => '', - 'proxy_auth' => Zend_Http_Client::AUTH_BASIC, - 'persistent' => false - ); - - /** - * Whether HTTPS CONNECT was already negotiated with the proxy or not - * - * @var boolean - */ - protected $negotiated = false; - - /** - * Connect to the remote server - * - * Will try to connect to the proxy server. If no proxy was set, will - * fall back to the target server (behave like regular Socket adapter) - * - * @param string $host - * @param int $port - * @param boolean $secure - * @param int $timeout - */ - public function connect($host, $port = 80, $secure = false) - { - // If no proxy is set, fall back to Socket adapter - if (! $this->config['proxy_host']) return parent::connect($host, $port, $secure); - - // Go through a proxy - the connection is actually to the proxy server - $host = $this->config['proxy_host']; - $port = $this->config['proxy_port']; - - // If we are connected to the wrong proxy, disconnect first - if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) { - if (is_resource($this->socket)) $this->close(); - } - - // Now, if we are not connected, connect - if (! is_resource($this->socket) || ! $this->config['keepalive']) { - $this->socket = @fsockopen($host, $port, $errno, $errstr, (int) $this->config['timeout']); - if (! $this->socket) { - $this->close(); - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception( - 'Unable to Connect to proxy server ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr); - } - - // Set the stream timeout - if (!stream_set_timeout($this->socket, (int) $this->config['timeout'])) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout'); - } - - // Update connected_to - $this->connected_to = array($host, $port); - } - } - - /** - * Send request to the proxy server - * - * @param string $method - * @param Zend_Uri_Http $uri - * @param string $http_ver - * @param array $headers - * @param string $body - * @return string Request as string - */ - public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') - { - // If no proxy is set, fall back to default Socket adapter - if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body); - - // Make sure we're properly connected - if (! $this->socket) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected"); - } - - $host = $this->config['proxy_host']; - $port = $this->config['proxy_port']; - - if ($this->connected_to[0] != $host || $this->connected_to[1] != $port) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server"); - } - - // Add Proxy-Authorization header - if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) - $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader( - $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth'] - ); - - // if we are proxying HTTPS, preform CONNECT handshake with the proxy - if ($uri->getScheme() == 'https' && (! $this->negotiated)) { - $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers); - $this->negotiated = true; - } - - // Save request method for later - $this->method = $method; - - // Build request headers - $request = "{$method} {$uri->__toString()} HTTP/{$http_ver}\r\n"; - - // Add all headers to the request string - foreach ($headers as $k => $v) { - if (is_string($k)) $v = "$k: $v"; - $request .= "$v\r\n"; - } - - // Add the request body - $request .= "\r\n" . $body; - - // Send the request - if (! @fwrite($this->socket, $request)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); - } - - return $request; - } - - /** - * Preform handshaking with HTTPS proxy using CONNECT method - * - * @param string $host - * @param integer $port - * @param string $http_ver - * @param array $headers - */ - protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) - { - $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . - "Host: " . $this->config['proxy_host'] . "\r\n"; - - // Add the user-agent header - if (isset($this->config['useragent'])) { - $request .= "User-agent: " . $this->config['useragent'] . "\r\n"; - } - - // If the proxy-authorization header is set, send it to proxy but remove - // it from headers sent to target host - if (isset($headers['proxy-authorization'])) { - $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n"; - unset($headers['proxy-authorization']); - } - - $request .= "\r\n"; - - // Send the request - if (! @fwrite($this->socket, $request)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); - } - - // Read response headers only - $response = ''; - $gotStatus = false; - while ($line = @fgets($this->socket)) { - $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); - if ($gotStatus) { - $response .= $line; - if (!chop($line)) break; - } - } - - // Check that the response from the proxy is 200 - if (Zend_Http_Response::extractCode($response) != 200) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response); - } - - // If all is good, switch socket to secure mode. We have to fall back - // through the different modes - $modes = array( - STREAM_CRYPTO_METHOD_TLS_CLIENT, - STREAM_CRYPTO_METHOD_SSLv3_CLIENT, - STREAM_CRYPTO_METHOD_SSLv23_CLIENT, - STREAM_CRYPTO_METHOD_SSLv2_CLIENT - ); - - $success = false; - foreach($modes as $mode) { - $success = stream_socket_enable_crypto($this->socket, true, $mode); - if ($success) break; - } - - if (! $success) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" . - " HTTPS server through proxy: could not negotiate secure connection."); - } - } - - /** - * Close the connection to the server - * - */ - public function close() - { - parent::close(); - $this->negotiated = false; - } - - /** - * Destructor: make sure the socket is disconnected - * - */ - public function __destruct() - { - if ($this->socket) $this->close(); - } -} diff --git a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Socket.php b/phpQuery/phpQuery/Zend/Http/Client/Adapter/Socket.php deleted file mode 100644 index 01b6ef3..0000000 --- a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Socket.php +++ /dev/null @@ -1,332 +0,0 @@ - false, - 'ssltransport' => 'ssl', - 'sslcert' => null, - 'sslpassphrase' => null - ); - - /** - * Request method - will be set by write() and might be used by read() - * - * @var string - */ - protected $method = null; - - /** - * Adapter constructor, currently empty. Config is set using setConfig() - * - */ - public function __construct() - { - } - - /** - * Set the configuration array for the adapter - * - * @param array $config - */ - public function setConfig($config = array()) - { - if (! is_array($config)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception( - '$config expects an array, ' . gettype($config) . ' recieved.'); - } - - foreach ($config as $k => $v) { - $this->config[strtolower($k)] = $v; - } - } - - /** - * Connect to the remote server - * - * @param string $host - * @param int $port - * @param boolean $secure - * @param int $timeout - */ - public function connect($host, $port = 80, $secure = false) - { - // If the URI should be accessed via SSL, prepend the Hostname with ssl:// - $host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host; - - // If we are connected to the wrong host, disconnect first - if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) { - if (is_resource($this->socket)) $this->close(); - } - - // Now, if we are not connected, connect - if (! is_resource($this->socket) || ! $this->config['keepalive']) { - $context = stream_context_create(); - if ($secure) { - if ($this->config['sslcert'] !== null) { - if (! stream_context_set_option($context, 'ssl', 'local_cert', - $this->config['sslcert'])) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Unable to set sslcert option'); - } - } - if ($this->config['sslpassphrase'] !== null) { - if (! stream_context_set_option($context, 'ssl', 'passphrase', - $this->config['sslpassphrase'])) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Unable to set sslpassphrase option'); - } - } - } - - $flags = STREAM_CLIENT_CONNECT; - if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT; - - $this->socket = @stream_socket_client($host . ':' . $port, - $errno, - $errstr, - (int) $this->config['timeout'], - $flags, - $context); - if (! $this->socket) { - $this->close(); - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception( - 'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr); - } - - // Set the stream timeout - if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout'); - } - - // Update connected_to - $this->connected_to = array($host, $port); - } - } - - /** - * Send request to the remote server - * - * @param string $method - * @param Zend_Uri_Http $uri - * @param string $http_ver - * @param array $headers - * @param string $body - * @return string Request as string - */ - public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') - { - // Make sure we're properly connected - if (! $this->socket) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are not connected'); - } - - $host = $uri->getHost(); - $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host; - if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are connected to the wrong host'); - } - - // Save request method for later - $this->method = $method; - - // Build request headers - $path = $uri->getPath(); - if ($uri->getQuery()) $path .= '?' . $uri->getQuery(); - $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; - foreach ($headers as $k => $v) { - if (is_string($k)) $v = ucfirst($k) . ": $v"; - $request .= "$v\r\n"; - } - - // Add the request body - $request .= "\r\n" . $body; - - // Send the request - if (! @fwrite($this->socket, $request)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Error writing request to server'); - } - - return $request; - } - - /** - * Read response from server - * - * @return string - */ - public function read() - { - // First, read headers only - $response = ''; - $gotStatus = false; - while ($line = @fgets($this->socket)) { - $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); - if ($gotStatus) { - $response .= $line; - if (!chop($line)) break; - } - } - - $statusCode = Zend_Http_Response::extractCode($response); - - // Handle 100 and 101 responses internally by restarting the read again - if ($statusCode == 100 || $statusCode == 101) return $this->read(); - - /** - * Responses to HEAD requests and 204 or 304 responses are not expected - * to have a body - stop reading here - */ - if ($statusCode == 304 || $statusCode == 204 || - $this->method == Zend_Http_Client::HEAD) return $response; - - // Check headers to see what kind of connection / transfer encoding we have - $headers = Zend_Http_Response::extractHeaders($response); - - // if the connection is set to close, just read until socket closes - if (isset($headers['connection']) && $headers['connection'] == 'close') { - while ($buff = @fread($this->socket, 8192)) { - $response .= $buff; - } - - $this->close(); - - // Else, if we got a transfer-encoding header (chunked body) - } elseif (isset($headers['transfer-encoding'])) { - if ($headers['transfer-encoding'] == 'chunked') { - do { - $chunk = ''; - $line = @fgets($this->socket); - $chunk .= $line; - - $hexchunksize = ltrim(chop($line), '0'); - $hexchunksize = strlen($hexchunksize) ? strtolower($hexchunksize) : 0; - - $chunksize = hexdec(chop($line)); - if (dechex($chunksize) != $hexchunksize) { - @fclose($this->socket); - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' . - $hexchunksize . '" unable to read chunked body'); - } - - $left_to_read = $chunksize; - while ($left_to_read > 0) { - $line = @fread($this->socket, $left_to_read); - $chunk .= $line; - $left_to_read -= strlen($line); - } - - $chunk .= @fgets($this->socket); - $response .= $chunk; - } while ($chunksize > 0); - } else { - throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' . - $headers['transfer-encoding'] . '" transfer encoding'); - } - - // Else, if we got the content-length header, read this number of bytes - } elseif (isset($headers['content-length'])) { - $left_to_read = $headers['content-length']; - $chunk = ''; - while ($left_to_read > 0) { - $chunk = @fread($this->socket, $left_to_read); - $left_to_read -= strlen($chunk); - $response .= $chunk; - } - - // Fallback: just read the response (should not happen) - } else { - while ($buff = @fread($this->socket, 8192)) { - $response .= $buff; - } - - $this->close(); - } - - return $response; - } - - /** - * Close the connection to the server - * - */ - public function close() - { - if (is_resource($this->socket)) @fclose($this->socket); - $this->socket = null; - $this->connected_to = array(null, null); - } - - /** - * Destructor: make sure the socket is disconnected - * - * If we are in persistent TCP mode, will not close the connection - * - */ - public function __destruct() - { - if (! $this->config['persistent']) { - if ($this->socket) $this->close(); - } - } -} diff --git a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Test.php b/phpQuery/phpQuery/Zend/Http/Client/Adapter/Test.php deleted file mode 100644 index ce5c468..0000000 --- a/phpQuery/phpQuery/Zend/Http/Client/Adapter/Test.php +++ /dev/null @@ -1,193 +0,0 @@ - $v) { - $this->config[strtolower($k)] = $v; - } - } - - /** - * Connect to the remote server - * - * @param string $host - * @param int $port - * @param boolean $secure - * @param int $timeout - */ - public function connect($host, $port = 80, $secure = false) - { } - - /** - * Send request to the remote server - * - * @param string $method - * @param Zend_Uri_Http $uri - * @param string $http_ver - * @param array $headers - * @param string $body - * @return string Request as string - */ - public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') - { - $host = $uri->getHost(); - $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host); - - // Build request headers - $path = $uri->getPath(); - if ($uri->getQuery()) $path .= '?' . $uri->getQuery(); - $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; - foreach ($headers as $k => $v) { - if (is_string($k)) $v = ucfirst($k) . ": $v"; - $request .= "$v\r\n"; - } - - // Add the request body - $request .= "\r\n" . $body; - - // Do nothing - just return the request as string - - return $request; - } - - /** - * Return the response set in $this->setResponse() - * - * @return string - */ - public function read() - { - if ($this->responseIndex >= count($this->responses)) { - $this->responseIndex = 0; - } - return $this->responses[$this->responseIndex++]; - } - - /** - * Close the connection (dummy) - * - */ - public function close() - { } - - /** - * Set the HTTP response(s) to be returned by this adapter - * - * @param Zend_Http_Response|array|string $response - */ - public function setResponse($response) - { - if ($response instanceof Zend_Http_Response) { - $response = $response->asString(); - } - - $this->responses = (array)$response; - $this->responseIndex = 0; - } - - /** - * Add another response to the response buffer. - * - * @param string $response - */ - public function addResponse($response) - { - $this->responses[] = $response; - } - - /** - * Sets the position of the response buffer. Selects which - * response will be returned on the next call to read(). - * - * @param integer $index - */ - public function setResponseIndex($index) - { - if ($index < 0 || $index >= count($this->responses)) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception( - 'Index out of range of response buffer size'); - } - $this->responseIndex = $index; - } -} diff --git a/phpQuery/phpQuery/Zend/Http/Client/Exception.php b/phpQuery/phpQuery/Zend/Http/Client/Exception.php deleted file mode 100644 index 70c8e01..0000000 --- a/phpQuery/phpQuery/Zend/Http/Client/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ -name = (string) $name) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Cookies must have a name'); - } - - if (! $this->domain = (string) $domain) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Cookies must have a domain'); - } - - $this->value = (string) $value; - $this->expires = ($expires === null ? null : (int) $expires); - $this->path = ($path ? $path : '/'); - $this->secure = $secure; - } - - /** - * Get Cookie name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get cookie value - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * Get cookie domain - * - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * Get the cookie path - * - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * Get the expiry time of the cookie, or null if no expiry time is set - * - * @return int|null - */ - public function getExpiryTime() - { - return $this->expires; - } - - /** - * Check whether the cookie should only be sent over secure connections - * - * @return boolean - */ - public function isSecure() - { - return $this->secure; - } - - /** - * Check whether the cookie has expired - * - * Always returns false if the cookie is a session cookie (has no expiry time) - * - * @param int $now Timestamp to consider as "now" - * @return boolean - */ - public function isExpired($now = null) - { - if ($now === null) $now = time(); - if (is_int($this->expires) && $this->expires < $now) { - return true; - } else { - return false; - } - } - - /** - * Check whether the cookie is a session cookie (has no expiry time set) - * - * @return boolean - */ - public function isSessionCookie() - { - return ($this->expires === null); - } - - /** - * Checks whether the cookie should be sent or not in a specific scenario - * - * @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path) - * @param boolean $matchSessionCookies Whether to send session cookies - * @param int $now Override the current time when checking for expiry time - * @return boolean - */ - public function match($uri, $matchSessionCookies = true, $now = null) - { - if (is_string ($uri)) { - $uri = Zend_Uri_Http::factory($uri); - } - - // Make sure we have a valid Zend_Uri_Http object - if (! ($uri->valid() && ($uri->getScheme() == 'http' || $uri->getScheme() =='https'))) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Passed URI is not a valid HTTP or HTTPS URI'); - } - - // Check that the cookie is secure (if required) and not expired - if ($this->secure && $uri->getScheme() != 'https') return false; - if ($this->isExpired($now)) return false; - if ($this->isSessionCookie() && ! $matchSessionCookies) return false; - - // Validate domain and path - // Domain is validated using tail match, while path is validated using head match - $domain_preg = preg_quote($this->getDomain(), "/"); - if (! preg_match("/{$domain_preg}$/", $uri->getHost())) return false; - $path_preg = preg_quote($this->getPath(), "/"); - if (! preg_match("/^{$path_preg}/", $uri->getPath())) return false; - - // If we didn't die until now, return true. - return true; - } - - /** - * Get the cookie as a string, suitable for sending as a "Cookie" header in an - * HTTP request - * - * @return string - */ - public function __toString() - { - return $this->name . '=' . urlencode($this->value) . ';'; - } - - /** - * Generate a new Cookie object from a cookie string - * (for example the value of the Set-Cookie HTTP header) - * - * @param string $cookieStr - * @param Zend_Uri_Http|string $ref_uri Reference URI for default values (domain, path) - * @return Zend_Http_Cookie A new Zend_Http_Cookie object or false on failure. - */ - public static function fromString($cookieStr, $ref_uri = null) - { - // Set default values - if (is_string($ref_uri)) { - $ref_uri = Zend_Uri_Http::factory($ref_uri); - } - - $name = ''; - $value = ''; - $domain = ''; - $path = ''; - $expires = null; - $secure = false; - $parts = explode(';', $cookieStr); - - // If first part does not include '=', fail - if (strpos($parts[0], '=') === false) return false; - - // Get the name and value of the cookie - list($name, $value) = explode('=', trim(array_shift($parts)), 2); - $name = trim($name); - $value = urldecode(trim($value)); - - // Set default domain and path - if ($ref_uri instanceof Zend_Uri_Http) { - $domain = $ref_uri->getHost(); - $path = $ref_uri->getPath(); - $path = substr($path, 0, strrpos($path, '/')); - } - - // Set other cookie parameters - foreach ($parts as $part) { - $part = trim($part); - if (strtolower($part) == 'secure') { - $secure = true; - continue; - } - - $keyValue = explode('=', $part, 2); - if (count($keyValue) == 2) { - list($k, $v) = $keyValue; - switch (strtolower($k)) { - case 'expires': - $expires = strtotime($v); - break; - case 'path': - $path = $v; - break; - case 'domain': - $domain = $v; - break; - default: - break; - } - } - } - - if ($name !== '') { - return new Zend_Http_Cookie($name, $value, $domain, $expires, $path, $secure); - } else { - return false; - } - } -} diff --git a/phpQuery/phpQuery/Zend/Http/CookieJar.php b/phpQuery/phpQuery/Zend/Http/CookieJar.php deleted file mode 100644 index c11174e..0000000 --- a/phpQuery/phpQuery/Zend/Http/CookieJar.php +++ /dev/null @@ -1,350 +0,0 @@ -getDomain(); - $path = $cookie->getPath(); - if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array(); - if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array(); - $this->cookies[$domain][$path][$cookie->getName()] = $cookie; - } else { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Supplient argument is not a valid cookie string or object'); - } - } - - /** - * Parse an HTTP response, adding all the cookies set in that response - * to the cookie jar. - * - * @param Zend_Http_Response $response - * @param Zend_Uri_Http|string $ref_uri Requested URI - */ - public function addCookiesFromResponse($response, $ref_uri) - { - if (! $response instanceof Zend_Http_Response) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('$response is expected to be a Response object, ' . - gettype($response) . ' was passed'); - } - - $cookie_hdrs = $response->getHeader('Set-Cookie'); - - if (is_array($cookie_hdrs)) { - foreach ($cookie_hdrs as $cookie) { - $this->addCookie($cookie, $ref_uri); - } - } elseif (is_string($cookie_hdrs)) { - $this->addCookie($cookie_hdrs, $ref_uri); - } - } - - /** - * Get all cookies in the cookie jar as an array - * - * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings - * @return array|string - */ - public function getAllCookies($ret_as = self::COOKIE_OBJECT) - { - $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as); - return $cookies; - } - - /** - * Return an array of all cookies matching a specific request according to the request URI, - * whether session cookies should be sent or not, and the time to consider as "now" when - * checking cookie expiry time. - * - * @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path) - * @param boolean $matchSessionCookies Whether to send session cookies - * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings - * @param int $now Override the current time when checking for expiry time - * @return array|string - */ - public function getMatchingCookies($uri, $matchSessionCookies = true, - $ret_as = self::COOKIE_OBJECT, $now = null) - { - if (is_string($uri)) $uri = Zend_Uri::factory($uri); - if (! $uri instanceof Zend_Uri_Http) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception("Invalid URI string or object passed"); - } - - // Set path - $path = $uri->getPath(); - $path = substr($path, 0, strrpos($path, '/')); - if (! $path) $path = '/'; - - // First, reduce the array of cookies to only those matching domain and path - $cookies = $this->_matchDomain($uri->getHost()); - $cookies = $this->_matchPath($cookies, $path); - $cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT); - - // Next, run Cookie->match on all cookies to check secure, time and session mathcing - $ret = array(); - foreach ($cookies as $cookie) - if ($cookie->match($uri, $matchSessionCookies, $now)) - $ret[] = $cookie; - - // Now, use self::_flattenCookiesArray again - only to convert to the return format ;) - $ret = $this->_flattenCookiesArray($ret, $ret_as); - - return $ret; - } - - /** - * Get a specific cookie according to a URI and name - * - * @param Zend_Uri_Http|string $uri The uri (domain and path) to match - * @param string $cookie_name The cookie's name - * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings - * @return Zend_Http_Cookie|string - */ - public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT) - { - if (is_string($uri)) { - $uri = Zend_Uri::factory($uri); - } - - if (! $uri instanceof Zend_Uri_Http) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Invalid URI specified'); - } - - // Get correct cookie path - $path = $uri->getPath(); - $path = substr($path, 0, strrpos($path, '/')); - if (! $path) $path = '/'; - - if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) { - $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name]; - - switch ($ret_as) { - case self::COOKIE_OBJECT: - return $cookie; - break; - - case self::COOKIE_STRING_ARRAY: - case self::COOKIE_STRING_CONCAT: - return $cookie->__toString(); - break; - - default: - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}"); - break; - } - } else { - return false; - } - } - - /** - * Helper function to recursivly flatten an array. Shoud be used when exporting the - * cookies array (or parts of it) - * - * @param Zend_Http_Cookie|array $ptr - * @param int $ret_as What value to return - * @return array|string - */ - protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) { - if (is_array($ptr)) { - $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array()); - foreach ($ptr as $item) { - if ($ret_as == self::COOKIE_STRING_CONCAT) { - $ret .= $this->_flattenCookiesArray($item, $ret_as); - } else { - $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as)); - } - } - return $ret; - } elseif ($ptr instanceof Zend_Http_Cookie) { - switch ($ret_as) { - case self::COOKIE_STRING_ARRAY: - return array($ptr->__toString()); - break; - - case self::COOKIE_STRING_CONCAT: - return $ptr->__toString(); - break; - - case self::COOKIE_OBJECT: - default: - return array($ptr); - break; - } - } - - return null; - } - - /** - * Return a subset of the cookies array matching a specific domain - * - * Returned array is actually an array of pointers to items in the $this->cookies array. - * - * @param string $domain - * @return array - */ - protected function _matchDomain($domain) { - $ret = array(); - - foreach (array_keys($this->cookies) as $cdom) { - $regex = "/" . preg_quote($cdom, "/") . "$/i"; - if (preg_match($regex, $domain)) $ret[$cdom] = &$this->cookies[$cdom]; - } - - return $ret; - } - - /** - * Return a subset of a domain-matching cookies that also match a specified path - * - * Returned array is actually an array of pointers to items in the $passed array. - * - * @param array $dom_array - * @param string $path - * @return array - */ - protected function _matchPath($domains, $path) { - $ret = array(); - if (substr($path, -1) != '/') $path .= '/'; - - foreach ($domains as $dom => $paths_array) { - foreach (array_keys($paths_array) as $cpath) { - $regex = "|^" . preg_quote($cpath, "|") . "|i"; - if (preg_match($regex, $path)) { - if (! isset($ret[$dom])) $ret[$dom] = array(); - $ret[$dom][$cpath] = &$paths_array[$cpath]; - } - } - } - - return $ret; - } - - /** - * Create a new CookieJar object and automatically load into it all the - * cookies set in an Http_Response object. If $uri is set, it will be - * considered as the requested URI for setting default domain and path - * of the cookie. - * - * @param Zend_Http_Response $response HTTP Response object - * @param Zend_Uri_Http|string $uri The requested URI - * @return Zend_Http_CookieJar - * @todo Add the $uri functionality. - */ - public static function fromResponse(Zend_Http_Response $response, $ref_uri) - { - $jar = new self(); - $jar->addCookiesFromResponse($response, $ref_uri); - return $jar; - } -} diff --git a/phpQuery/phpQuery/Zend/Http/Exception.php b/phpQuery/phpQuery/Zend/Http/Exception.php deleted file mode 100644 index 76e2a8d..0000000 --- a/phpQuery/phpQuery/Zend/Http/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - - // Success 2xx - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - - // Redirection 3xx - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', // 1.1 - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - // 306 is deprecated but reserved - 307 => 'Temporary Redirect', - - // Client Error 4xx - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - - // Server Error 5xx - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 509 => 'Bandwidth Limit Exceeded' - ); - - /** - * The HTTP version (1.0, 1.1) - * - * @var string - */ - protected $version; - - /** - * The HTTP response code - * - * @var int - */ - protected $code; - - /** - * The HTTP response code as string - * (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500) - * - * @var string - */ - protected $message; - - /** - * The HTTP response headers array - * - * @var array - */ - protected $headers = array(); - - /** - * The HTTP response body - * - * @var string - */ - protected $body; - - /** - * HTTP response constructor - * - * In most cases, you would use Zend_Http_Response::fromString to parse an HTTP - * response string and create a new Zend_Http_Response object. - * - * NOTE: The constructor no longer accepts nulls or empty values for the code and - * headers and will throw an exception if the passed values do not form a valid HTTP - * responses. - * - * If no message is passed, the message will be guessed according to the response code. - * - * @param int $code Response code (200, 404, ...) - * @param array $headers Headers array - * @param string $body Response body - * @param string $version HTTP version - * @param string $message Response code as text - * @throws Zend_Http_Exception - */ - public function __construct($code, $headers, $body = null, $version = '1.1', $message = null) - { - // Make sure the response code is valid and set it - if (self::responseCodeAsText($code) === null) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception("{$code} is not a valid HTTP response code"); - } - - $this->code = $code; - - // Make sure we got valid headers and set them - if (! is_array($headers)) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('No valid headers were passed'); - } - - foreach ($headers as $name => $value) { - if (is_int($name)) - list($name, $value) = explode(": ", $value, 1); - - $this->headers[ucwords(strtolower($name))] = $value; - } - - // Set the body - $this->body = $body; - - // Set the HTTP version - if (! preg_match('|^\d\.\d$|', $version)) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception("Invalid HTTP response version: $version"); - } - - $this->version = $version; - - // If we got the response message, set it. Else, set it according to - // the response code - if (is_string($message)) { - $this->message = $message; - } else { - $this->message = self::responseCodeAsText($code); - } - } - - /** - * Check whether the response is an error - * - * @return boolean - */ - public function isError() - { - $restype = floor($this->code / 100); - if ($restype == 4 || $restype == 5) { - return true; - } - - return false; - } - - /** - * Check whether the response in successful - * - * @return boolean - */ - public function isSuccessful() - { - $restype = floor($this->code / 100); - if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ??? - return true; - } - - return false; - } - - /** - * Check whether the response is a redirection - * - * @return boolean - */ - public function isRedirect() - { - $restype = floor($this->code / 100); - if ($restype == 3) { - return true; - } - - return false; - } - - /** - * Get the response body as string - * - * This method returns the body of the HTTP response (the content), as it - * should be in it's readable version - that is, after decoding it (if it - * was decoded), deflating it (if it was gzip compressed), etc. - * - * If you want to get the raw body (as transfered on wire) use - * $this->getRawBody() instead. - * - * @return string - */ - public function getBody() - { - $body = ''; - - // Decode the body if it was transfer-encoded - switch ($this->getHeader('transfer-encoding')) { - - // Handle chunked body - case 'chunked': - $body = self::decodeChunkedBody($this->body); - break; - - // No transfer encoding, or unknown encoding extension: - // return body as is - default: - $body = $this->body; - break; - } - - // Decode any content-encoding (gzip or deflate) if needed - switch (strtolower($this->getHeader('content-encoding'))) { - - // Handle gzip encoding - case 'gzip': - $body = self::decodeGzip($body); - break; - - // Handle deflate encoding - case 'deflate': - $body = self::decodeDeflate($body); - break; - - default: - break; - } - - return $body; - } - - /** - * Get the raw response body (as transfered "on wire") as string - * - * If the body is encoded (with Transfer-Encoding, not content-encoding - - * IE "chunked" body), gzip compressed, etc. it will not be decoded. - * - * @return string - */ - public function getRawBody() - { - return $this->body; - } - - /** - * Get the HTTP version of the response - * - * @return string - */ - public function getVersion() - { - return $this->version; - } - - /** - * Get the HTTP response status code - * - * @return int - */ - public function getStatus() - { - return $this->code; - } - - /** - * Return a message describing the HTTP response code - * (Eg. "OK", "Not Found", "Moved Permanently") - * - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * Get the response headers - * - * @return array - */ - public function getHeaders() - { - return $this->headers; - } - - /** - * Get a specific header as string, or null if it is not set - * - * @param string$header - * @return string|array|null - */ - public function getHeader($header) - { - $header = ucwords(strtolower($header)); - if (! is_string($header) || ! isset($this->headers[$header])) return null; - - return $this->headers[$header]; - } - - /** - * Get all headers as string - * - * @param boolean $status_line Whether to return the first status line (IE "HTTP 200 OK") - * @param string $br Line breaks (eg. "\n", "\r\n", "
") - * @return string - */ - public function getHeadersAsString($status_line = true, $br = "\n") - { - $str = ''; - - if ($status_line) { - $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}"; - } - - // Iterate over the headers and stringify them - foreach ($this->headers as $name => $value) - { - if (is_string($value)) - $str .= "{$name}: {$value}{$br}"; - - elseif (is_array($value)) { - foreach ($value as $subval) { - $str .= "{$name}: {$subval}{$br}"; - } - } - } - - return $str; - } - - /** - * Get the entire response as string - * - * @param string $br Line breaks (eg. "\n", "\r\n", "
") - * @return string - */ - public function asString($br = "\n") - { - return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody(); - } - - /** - * A convenience function that returns a text representation of - * HTTP response codes. Returns 'Unknown' for unknown codes. - * Returns array of all codes, if $code is not specified. - * - * Conforms to HTTP/1.1 as defined in RFC 2616 (except for 'Unknown') - * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 for reference - * - * @param int $code HTTP response code - * @param boolean $http11 Use HTTP version 1.1 - * @return string - */ - public static function responseCodeAsText($code = null, $http11 = true) - { - $messages = self::$messages; - if (! $http11) $messages[302] = 'Moved Temporarily'; - - if ($code === null) { - return $messages; - } elseif (isset($messages[$code])) { - return $messages[$code]; - } else { - return 'Unknown'; - } - } - - /** - * Extract the response code from a response string - * - * @param string $response_str - * @return int - */ - public static function extractCode($response_str) - { - preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m); - - if (isset($m[1])) { - return (int) $m[1]; - } else { - return false; - } - } - - /** - * Extract the HTTP message from a response - * - * @param string $response_str - * @return string - */ - public static function extractMessage($response_str) - { - preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m); - - if (isset($m[1])) { - return $m[1]; - } else { - return false; - } - } - - /** - * Extract the HTTP version from a response - * - * @param string $response_str - * @return string - */ - public static function extractVersion($response_str) - { - preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m); - - if (isset($m[1])) { - return $m[1]; - } else { - return false; - } - } - - /** - * Extract the headers from a response string - * - * @param string $response_str - * @return array - */ - public static function extractHeaders($response_str) - { - $headers = array(); - - // First, split body and headers - $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2); - if (! $parts[0]) return $headers; - - // Split headers part to lines - $lines = explode("\n", $parts[0]); - unset($parts); - $last_header = null; - - foreach($lines as $line) { - $line = trim($line, "\r\n"); - if ($line == "") break; - - if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) { - unset($last_header); - $h_name = strtolower($m[1]); - $h_value = $m[2]; - - if (isset($headers[$h_name])) { - if (! is_array($headers[$h_name])) { - $headers[$h_name] = array($headers[$h_name]); - } - - $headers[$h_name][] = $h_value; - } else { - $headers[$h_name] = $h_value; - } - $last_header = $h_name; - } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) { - if (is_array($headers[$last_header])) { - end($headers[$last_header]); - $last_header_key = key($headers[$last_header]); - $headers[$last_header][$last_header_key] .= $m[1]; - } else { - $headers[$last_header] .= $m[1]; - } - } - } - - return $headers; - } - - /** - * Extract the body from a response string - * - * @param string $response_str - * @return string - */ - public static function extractBody($response_str) - { - $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2); - if (isset($parts[1])) { - return $parts[1]; - } else { - return ''; - } - } - - /** - * Decode a "chunked" transfer-encoded body and return the decoded text - * - * @param string $body - * @return string - */ - public static function decodeChunkedBody($body) - { - $decBody = ''; - - while (trim($body)) { - if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception("Error parsing body - doesn't seem to be a chunked message"); - } - - $length = hexdec(trim($m[1])); - $cut = strlen($m[0]); - - $decBody .= substr($body, $cut, $length); - $body = substr($body, $cut + $length + 2); - } - - return $decBody; - } - - /** - * Decode a gzip encoded message (when Content-encoding = gzip) - * - * Currently requires PHP with zlib support - * - * @param string $body - * @return string - */ - public static function decodeGzip($body) - { - if (! function_exists('gzinflate')) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Unable to decode gzipped response ' . - 'body: perhaps the zlib extension is not loaded?'); - } - - return gzinflate(substr($body, 10)); - } - - /** - * Decode a zlib deflated message (when Content-encoding = deflate) - * - * Currently requires PHP with zlib support - * - * @param string $body - * @return string - */ - public static function decodeDeflate($body) - { - if (! function_exists('gzuncompress')) { - require_once 'Zend/Http/Exception.php'; - throw new Zend_Http_Exception('Unable to decode deflated response ' . - 'body: perhaps the zlib extension is not loaded?'); - } - - return gzuncompress($body); - } - - /** - * Create a new Zend_Http_Response object from a string - * - * @param string $response_str - * @return Zend_Http_Response - */ - public static function fromString($response_str) - { - $code = self::extractCode($response_str); - $headers = self::extractHeaders($response_str); - $body = self::extractBody($response_str); - $version = self::extractVersion($response_str); - $message = self::extractMessage($response_str); - - return new Zend_Http_Response($code, $headers, $body, $version, $message); - } -} diff --git a/phpQuery/phpQuery/Zend/Json/Decoder.php b/phpQuery/phpQuery/Zend/Json/Decoder.php deleted file mode 100644 index b9bf8ba..0000000 --- a/phpQuery/phpQuery/Zend/Json/Decoder.php +++ /dev/null @@ -1,457 +0,0 @@ -_source = $source; - $this->_sourceLength = strlen($source); - $this->_token = self::EOF; - $this->_offset = 0; - - // Normalize and set $decodeType - if (!in_array($decodeType, array(Zend_Json::TYPE_ARRAY, Zend_Json::TYPE_OBJECT))) - { - $decodeType = Zend_Json::TYPE_ARRAY; - } - $this->_decodeType = $decodeType; - - // Set pointer at first token - $this->_getNextToken(); - } - - /** - * Decode a JSON source string - * - * Decodes a JSON encoded string. The value returned will be one of the - * following: - * - integer - * - float - * - boolean - * - null - * - StdClass - * - array - * - array of one or more of the above types - * - * By default, decoded objects will be returned as associative arrays; to - * return a StdClass object instead, pass {@link Zend_Json::TYPE_OBJECT} to - * the $objectDecodeType parameter. - * - * Throws a Zend_Json_Exception if the source string is null. - * - * @static - * @access public - * @param string $source String to be decoded - * @param int $objectDecodeType How objects should be decoded; should be - * either or {@link Zend_Json::TYPE_ARRAY} or - * {@link Zend_Json::TYPE_OBJECT}; defaults to TYPE_ARRAY - * @return mixed - * @throws Zend_Json_Exception - */ - public static function decode($source = null, $objectDecodeType = Zend_Json::TYPE_ARRAY) - { - if (null === $source) { - throw new Zend_Json_Exception('Must specify JSON encoded source for decoding'); - } elseif (!is_string($source)) { - throw new Zend_Json_Exception('Can only decode JSON encoded strings'); - } - - $decoder = new self($source, $objectDecodeType); - - return $decoder->_decodeValue(); - } - - - /** - * Recursive driving rountine for supported toplevel tops - * - * @return mixed - */ - protected function _decodeValue() - { - switch ($this->_token) { - case self::DATUM: - $result = $this->_tokenValue; - $this->_getNextToken(); - return($result); - break; - case self::LBRACE: - return($this->_decodeObject()); - break; - case self::LBRACKET: - return($this->_decodeArray()); - break; - default: - return null; - break; - } - } - - /** - * Decodes an object of the form: - * { "attribute: value, "attribute2" : value,...} - * - * If Zend_Json_Encoder was used to encode the original object then - * a special attribute called __className which specifies a class - * name that should wrap the data contained within the encoded source. - * - * Decodes to either an array or StdClass object, based on the value of - * {@link $_decodeType}. If invalid $_decodeType present, returns as an - * array. - * - * @return array|StdClass - */ - protected function _decodeObject() - { - $members = array(); - $tok = $this->_getNextToken(); - - while ($tok && $tok != self::RBRACE) { - if ($tok != self::DATUM || ! is_string($this->_tokenValue)) { - throw new Zend_Json_Exception('Missing key in object encoding: ' . $this->_source); - } - - $key = $this->_tokenValue; - $tok = $this->_getNextToken(); - - if ($tok != self::COLON) { - throw new Zend_Json_Exception('Missing ":" in object encoding: ' . $this->_source); - } - - $tok = $this->_getNextToken(); - $members[$key] = $this->_decodeValue(); - $tok = $this->_token; - - if ($tok == self::RBRACE) { - break; - } - - if ($tok != self::COMMA) { - throw new Zend_Json_Exception('Missing "," in object encoding: ' . $this->_source); - } - - $tok = $this->_getNextToken(); - } - - switch ($this->_decodeType) { - case Zend_Json::TYPE_OBJECT: - // Create new StdClass and populate with $members - $result = new StdClass(); - foreach ($members as $key => $value) { - $result->$key = $value; - } - break; - case Zend_Json::TYPE_ARRAY: - default: - $result = $members; - break; - } - - $this->_getNextToken(); - return $result; - } - - /** - * Decodes a JSON array format: - * [element, element2,...,elementN] - * - * @return array - */ - protected function _decodeArray() - { - $result = array(); - $starttok = $tok = $this->_getNextToken(); // Move past the '[' - $index = 0; - - while ($tok && $tok != self::RBRACKET) { - $result[$index++] = $this->_decodeValue(); - - $tok = $this->_token; - - if ($tok == self::RBRACKET || !$tok) { - break; - } - - if ($tok != self::COMMA) { - throw new Zend_Json_Exception('Missing "," in array encoding: ' . $this->_source); - } - - $tok = $this->_getNextToken(); - } - - $this->_getNextToken(); - return($result); - } - - - /** - * Removes whitepsace characters from the source input - */ - protected function _eatWhitespace() - { - if (preg_match( - '/([\t\b\f\n\r ])*/s', - $this->_source, - $matches, - PREG_OFFSET_CAPTURE, - $this->_offset) - && $matches[0][1] == $this->_offset) - { - $this->_offset += strlen($matches[0][0]); - } - } - - - /** - * Retrieves the next token from the source stream - * - * @return int Token constant value specified in class definition - */ - protected function _getNextToken() - { - $this->_token = self::EOF; - $this->_tokenValue = null; - $this->_eatWhitespace(); - - if ($this->_offset >= $this->_sourceLength) { - return(self::EOF); - } - - $str = $this->_source; - $str_length = $this->_sourceLength; - $i = $this->_offset; - $start = $i; - - switch ($str{$i}) { - case '{': - $this->_token = self::LBRACE; - break; - case '}': - $this->_token = self::RBRACE; - break; - case '[': - $this->_token = self::LBRACKET; - break; - case ']': - $this->_token = self::RBRACKET; - break; - case ',': - $this->_token = self::COMMA; - break; - case ':': - $this->_token = self::COLON; - break; - case '"': - $result = ''; - do { - $i++; - if ($i >= $str_length) { - break; - } - - $chr = $str{$i}; - if ($chr == '\\') { - $i++; - if ($i >= $str_length) { - break; - } - $chr = $str{$i}; - switch ($chr) { - case '"' : - $result .= '"'; - break; - case '\\': - $result .= '\\'; - break; - case '/' : - $result .= '/'; - break; - case 'b' : - $result .= chr(8); - break; - case 'f' : - $result .= chr(12); - break; - case 'n' : - $result .= chr(10); - break; - case 'r' : - $result .= chr(13); - break; - case 't' : - $result .= chr(9); - break; - case '\'' : - $result .= '\''; - break; - default: - throw new Zend_Json_Exception("Illegal escape " - . "sequence '" . $chr . "'"); - } - } elseif ($chr == '"') { - break; - } else { - $result .= $chr; - } - } while ($i < $str_length); - - $this->_token = self::DATUM; - //$this->_tokenValue = substr($str, $start + 1, $i - $start - 1); - $this->_tokenValue = $result; - break; - case 't': - if (($i+ 3) < $str_length && substr($str, $start, 4) == "true") { - $this->_token = self::DATUM; - } - $this->_tokenValue = true; - $i += 3; - break; - case 'f': - if (($i+ 4) < $str_length && substr($str, $start, 5) == "false") { - $this->_token = self::DATUM; - } - $this->_tokenValue = false; - $i += 4; - break; - case 'n': - if (($i+ 3) < $str_length && substr($str, $start, 4) == "null") { - $this->_token = self::DATUM; - } - $this->_tokenValue = NULL; - $i += 3; - break; - } - - if ($this->_token != self::EOF) { - $this->_offset = $i + 1; // Consume the last token character - return($this->_token); - } - - $chr = $str{$i}; - if ($chr == '-' || $chr == '.' || ($chr >= '0' && $chr <= '9')) { - if (preg_match('/-?([0-9])*(\.[0-9]*)?((e|E)((-|\+)?)[0-9]+)?/s', - $str, $matches, PREG_OFFSET_CAPTURE, $start) && $matches[0][1] == $start) { - - $datum = $matches[0][0]; - - if (is_numeric($datum)) { - if (preg_match('/^0\d+$/', $datum)) { - throw new Zend_Json_Exception("Octal notation not supported by JSON (value: $datum)"); - } else { - $val = intval($datum); - $fVal = floatval($datum); - $this->_tokenValue = ($val == $fVal ? $val : $fVal); - } - } else { - throw new Zend_Json_Exception("Illegal number format: $datum"); - } - - $this->_token = self::DATUM; - $this->_offset = $start + strlen($datum); - } - } else { - throw new Zend_Json_Exception('Illegal Token'); - } - - return($this->_token); - } -} - diff --git a/phpQuery/phpQuery/Zend/Json/Encoder.php b/phpQuery/phpQuery/Zend/Json/Encoder.php deleted file mode 100644 index ce2024a..0000000 --- a/phpQuery/phpQuery/Zend/Json/Encoder.php +++ /dev/null @@ -1,431 +0,0 @@ -_cycleCheck = $cycleCheck; - $this->_options = $options; - } - - /** - * Use the JSON encoding scheme for the value specified - * - * @param mixed $value The value to be encoded - * @param boolean $cycleCheck Whether or not to check for possible object recursion when encoding - * @param array $options Additional options used during encoding - * @return string The encoded value - */ - public static function encode($value, $cycleCheck = false, $options = array()) - { - $encoder = new self(($cycleCheck) ? true : false, $options); - - return $encoder->_encodeValue($value); - } - - /** - * Recursive driver which determines the type of value to be encoded - * and then dispatches to the appropriate method. $values are either - * - objects (returns from {@link _encodeObject()}) - * - arrays (returns from {@link _encodeArray()}) - * - basic datums (e.g. numbers or strings) (returns from {@link _encodeDatum()}) - * - * @param $value mixed The value to be encoded - * @return string Encoded value - */ - protected function _encodeValue(&$value) - { - if (is_object($value)) { - return $this->_encodeObject($value); - } else if (is_array($value)) { - return $this->_encodeArray($value); - } - - return $this->_encodeDatum($value); - } - - - - /** - * Encode an object to JSON by encoding each of the public properties - * - * A special property is added to the JSON object called '__className' - * that contains the name of the class of $value. This is used to decode - * the object on the client into a specific class. - * - * @param $value object - * @return string - * @throws Zend_Json_Exception If recursive checks are enabled and the object has been serialized previously - */ - protected function _encodeObject(&$value) - { - if ($this->_cycleCheck) { - if ($this->_wasVisited($value)) { - - if (isset($this->_options['silenceCyclicalExceptions']) - && $this->_options['silenceCyclicalExceptions']===true) { - - return '"* RECURSION (' . get_class($value) . ') *"'; - - } else { - throw new Zend_Json_Exception( - 'Cycles not supported in JSON encoding, cycle introduced by ' - . 'class "' . get_class($value) . '"' - ); - } - } - - $this->_visited[] = $value; - } - - $props = ''; - foreach (get_object_vars($value) as $name => $propValue) { - if (isset($propValue)) { - $props .= ',' - . $this->_encodeValue($name) - . ':' - . $this->_encodeValue($propValue); - } - } - - return '{"__className":"' . get_class($value) . '"' - . $props . '}'; - } - - - /** - * Determine if an object has been serialized already - * - * @param mixed $value - * @return boolean - */ - protected function _wasVisited(&$value) - { - if (in_array($value, $this->_visited, true)) { - return true; - } - - return false; - } - - - /** - * JSON encode an array value - * - * Recursively encodes each value of an array and returns a JSON encoded - * array string. - * - * Arrays are defined as integer-indexed arrays starting at index 0, where - * the last index is (count($array) -1); any deviation from that is - * considered an associative array, and will be encoded as such. - * - * @param $array array - * @return string - */ - protected function _encodeArray(&$array) - { - $tmpArray = array(); - - // Check for associative array - if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) { - // Associative array - $result = '{'; - foreach ($array as $key => $value) { - $key = (string) $key; - $tmpArray[] = $this->_encodeString($key) - . ':' - . $this->_encodeValue($value); - } - $result .= implode(',', $tmpArray); - $result .= '}'; - } else { - // Indexed array - $result = '['; - $length = count($array); - for ($i = 0; $i < $length; $i++) { - $tmpArray[] = $this->_encodeValue($array[$i]); - } - $result .= implode(',', $tmpArray); - $result .= ']'; - } - - return $result; - } - - - /** - * JSON encode a basic data type (string, number, boolean, null) - * - * If value type is not a string, number, boolean, or null, the string - * 'null' is returned. - * - * @param $value mixed - * @return string - */ - protected function _encodeDatum(&$value) - { - $result = 'null'; - - if (is_int($value) || is_float($value)) { - $result = (string)$value; - } elseif (is_string($value)) { - $result = $this->_encodeString($value); - } elseif (is_bool($value)) { - $result = $value ? 'true' : 'false'; - } - - return $result; - } - - - /** - * JSON encode a string value by escaping characters as necessary - * - * @param $value string - * @return string - */ - protected function _encodeString(&$string) - { - // Escape these characters with a backslash: - // " \ / \n \r \t \b \f - $search = array('\\', "\n", "\t", "\r", "\b", "\f", '"'); - $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'); - $string = str_replace($search, $replace, $string); - - // Escape certain ASCII characters: - // 0x08 => \b - // 0x0c => \f - $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string); - - return '"' . $string . '"'; - } - - - /** - * Encode the constants associated with the ReflectionClass - * parameter. The encoding format is based on the class2 format - * - * @param $cls ReflectionClass - * @return string Encoded constant block in class2 format - */ - private static function _encodeConstants(ReflectionClass $cls) - { - $result = "constants : {"; - $constants = $cls->getConstants(); - - $tmpArray = array(); - if (!empty($constants)) { - foreach ($constants as $key => $value) { - $tmpArray[] = "$key: " . self::encode($value); - } - - $result .= implode(', ', $tmpArray); - } - - return $result . "}"; - } - - - /** - * Encode the public methods of the ReflectionClass in the - * class2 format - * - * @param $cls ReflectionClass - * @return string Encoded method fragment - * - */ - private static function _encodeMethods(ReflectionClass $cls) - { - $methods = $cls->getMethods(); - $result = 'methods:{'; - - $started = false; - foreach ($methods as $method) { - if (! $method->isPublic() || !$method->isUserDefined()) { - continue; - } - - if ($started) { - $result .= ','; - } - $started = true; - - $result .= '' . $method->getName(). ':function('; - - if ('__construct' != $method->getName()) { - $parameters = $method->getParameters(); - $paramCount = count($parameters); - $argsStarted = false; - - $argNames = "var argNames=["; - foreach ($parameters as $param) { - if ($argsStarted) { - $result .= ','; - } - - $result .= $param->getName(); - - if ($argsStarted) { - $argNames .= ','; - } - - $argNames .= '"' . $param->getName() . '"'; - - $argsStarted = true; - } - $argNames .= "];"; - - $result .= "){" - . $argNames - . 'var result = ZAjaxEngine.invokeRemoteMethod(' - . "this, '" . $method->getName() - . "',argNames,arguments);" - . 'return(result);}'; - } else { - $result .= "){}"; - } - } - - return $result . "}"; - } - - - /** - * Encode the public properties of the ReflectionClass in the class2 - * format. - * - * @param $cls ReflectionClass - * @return string Encode properties list - * - */ - private static function _encodeVariables(ReflectionClass $cls) - { - $properties = $cls->getProperties(); - $propValues = get_class_vars($cls->getName()); - $result = "variables:{"; - $cnt = 0; - - $tmpArray = array(); - foreach ($properties as $prop) { - if (! $prop->isPublic()) { - continue; - } - - $tmpArray[] = $prop->getName() - . ':' - . self::encode($propValues[$prop->getName()]); - } - $result .= implode(',', $tmpArray); - - return $result . "}"; - } - - /** - * Encodes the given $className into the class2 model of encoding PHP - * classes into JavaScript class2 classes. - * NOTE: Currently only public methods and variables are proxied onto - * the client machine - * - * @param $className string The name of the class, the class must be - * instantiable using a null constructor - * @param $package string Optional package name appended to JavaScript - * proxy class name - * @return string The class2 (JavaScript) encoding of the class - * @throws Zend_Json_Exception - */ - public static function encodeClass($className, $package = '') - { - $cls = new ReflectionClass($className); - if (! $cls->isInstantiable()) { - throw new Zend_Json_Exception("$className must be instantiable"); - } - - return "Class.create('$package$className',{" - . self::_encodeConstants($cls) ."," - . self::_encodeMethods($cls) ."," - . self::_encodeVariables($cls) .'});'; - } - - - /** - * Encode several classes at once - * - * Returns JSON encoded classes, using {@link encodeClass()}. - * - * @param array $classNames - * @param string $package - * @return string - */ - public static function encodeClasses(array $classNames, $package = '') - { - $result = ''; - foreach ($classNames as $className) { - $result .= self::encodeClass($className, $package); - } - - return $result; - } - -} - diff --git a/phpQuery/phpQuery/Zend/Json/Exception.php b/phpQuery/phpQuery/Zend/Json/Exception.php deleted file mode 100644 index 5b99095..0000000 --- a/phpQuery/phpQuery/Zend/Json/Exception.php +++ /dev/null @@ -1,36 +0,0 @@ - $dir) { - if ($dir == '.') { - $dirs[$key] = $dirPath; - } else { - $dir = rtrim($dir, '\\/'); - $dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath; - } - } - $file = basename($file); - self::loadFile($file, $dirs, true); - } else { - self::_securityCheck($file); - include_once $file; - } - - if (!class_exists($class, false) && !interface_exists($class, false)) { - require_once 'Zend/Exception.php'; - throw new Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file"); - } - } - - /** - * Loads a PHP file. This is a wrapper for PHP's include() function. - * - * $filename must be the complete filename, including any - * extension such as ".php". Note that a security check is performed that - * does not permit extended characters in the filename. This method is - * intended for loading Zend Framework files. - * - * If $dirs is a string or an array, it will search the directories - * in the order supplied, and attempt to load the first matching file. - * - * If the file was not found in the $dirs, or if no $dirs were specified, - * it will attempt to load it from PHP's include_path. - * - * If $once is TRUE, it will use include_once() instead of include(). - * - * @param string $filename - * @param string|array $dirs - OPTIONAL either a path or array of paths - * to search. - * @param boolean $once - * @return boolean - * @throws Zend_Exception - */ - public static function loadFile($filename, $dirs = null, $once = false) - { - self::_securityCheck($filename); - - /** - * Search in provided directories, as well as include_path - */ - $incPath = false; - if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) { - if (is_array($dirs)) { - $dirs = implode(PATH_SEPARATOR, $dirs); - } - $incPath = get_include_path(); - set_include_path($dirs . PATH_SEPARATOR . $incPath); - } - - /** - * Try finding for the plain filename in the include_path. - */ - if ($once) { - include_once $filename; - } else { - include $filename; - } - - /** - * If searching in directories, reset include_path - */ - if ($incPath) { - set_include_path($incPath); - } - - return true; - } - - /** - * Returns TRUE if the $filename is readable, or FALSE otherwise. - * This function uses the PHP include_path, where PHP's is_readable() - * does not. - * - * @param string $filename - * @return boolean - */ - public static function isReadable($filename) - { - if (!$fh = @fopen($filename, 'r', true)) { - return false; - } - @fclose($fh); - return true; - } - - /** - * spl_autoload() suitable implementation for supporting class autoloading. - * - * Attach to spl_autoload() using the following: - * - * spl_autoload_register(array('Zend_Loader', 'autoload')); - * - * - * @param string $class - * @return string|false Class name on success; false on failure - */ - public static function autoload($class) - { - try { - self::loadClass($class); - return $class; - } catch (Exception $e) { - return false; - } - } - - /** - * Register {@link autoload()} with spl_autoload() - * - * @param string $class (optional) - * @param boolean $enabled (optional) - * @return void - * @throws Zend_Exception if spl_autoload() is not found - * or if the specified class does not have an autoload() method. - */ - public static function registerAutoload($class = 'Zend_Loader', $enabled = true) - { - if (!function_exists('spl_autoload_register')) { - require_once 'Zend/Exception.php'; - throw new Zend_Exception('spl_autoload does not exist in this PHP installation'); - } - - self::loadClass($class); - $methods = get_class_methods($class); - if (!in_array('autoload', (array) $methods)) { - require_once 'Zend/Exception.php'; - throw new Zend_Exception("The class \"$class\" does not have an autoload() method"); - } - - if ($enabled === true) { - spl_autoload_register(array($class, 'autoload')); - } else { - spl_autoload_unregister(array($class, 'autoload')); - } - } - - /** - * Ensure that filename does not contain exploits - * - * @param string $filename - * @return void - * @throws Zend_Exception - */ - protected static function _securityCheck($filename) - { - /** - * Security check - */ - if (preg_match('/[^a-z0-9\\/\\\\_.-]/i', $filename)) { - require_once 'Zend/Exception.php'; - throw new Zend_Exception('Security check: Illegal character in filename'); - } - } - - /** - * Attempt to include() the file. - * - * include() is not prefixed with the @ operator because if - * the file is loaded and contains a parse error, execution - * will halt silently and this is difficult to debug. - * - * Always set display_errors = Off on production servers! - * - * @param string $filespec - * @param boolean $once - * @return boolean - * @deprecated Since 1.5.0; use loadFile() instead - */ - protected static function _includeFile($filespec, $once = false) - { - if ($once) { - return include_once $filespec; - } else { - return include $filespec ; - } - } -} diff --git a/phpQuery/phpQuery/Zend/Registry.php b/phpQuery/phpQuery/Zend/Registry.php deleted file mode 100644 index 62d9ceb..0000000 --- a/phpQuery/phpQuery/Zend/Registry.php +++ /dev/null @@ -1,195 +0,0 @@ -offsetExists($index)) { - require_once 'Zend/Exception.php'; - throw new Zend_Exception("No entry is registered for key '$index'"); - } - - return $instance->offsetGet($index); - } - - /** - * setter method, basically same as offsetSet(). - * - * This method can be called from an object of type Zend_Registry, or it - * can be called statically. In the latter case, it uses the default - * static instance stored in the class. - * - * @param string $index The location in the ArrayObject in which to store - * the value. - * @param mixed $value The object to store in the ArrayObject. - * @return void - */ - public static function set($index, $value) - { - $instance = self::getInstance(); - $instance->offsetSet($index, $value); - } - - /** - * Returns TRUE if the $index is a named value in the registry, - * or FALSE if $index was not found in the registry. - * - * @param string $index - * @return boolean - */ - public static function isRegistered($index) - { - if (self::$_registry === null) { - return false; - } - return self::$_registry->offsetExists($index); - } - - /** - * @param string $index - * @returns mixed - * - * Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960). - */ - public function offsetExists($index) - { - return array_key_exists($index, $this); - } - -} diff --git a/phpQuery/phpQuery/Zend/Uri.php b/phpQuery/phpQuery/Zend/Uri.php deleted file mode 100644 index 4c5776b..0000000 --- a/phpQuery/phpQuery/Zend/Uri.php +++ /dev/null @@ -1,164 +0,0 @@ -getUri(); - } - - /** - * Convenience function, checks that a $uri string is well-formed - * by validating it but not returning an object. Returns TRUE if - * $uri is a well-formed URI, or FALSE otherwise. - * - * @param string $uri The URI to check - * @return boolean - */ - public static function check($uri) - { - try { - $uri = self::factory($uri); - } catch (Exception $e) { - return false; - } - - return $uri->valid(); - } - - /** - * Create a new Zend_Uri object for a URI. If building a new URI, then $uri should contain - * only the scheme (http, ftp, etc). Otherwise, supply $uri with the complete URI. - * - * @param string $uri The URI form which a Zend_Uri instance is created - * @throws Zend_Uri_Exception When an empty string was supplied for the scheme - * @throws Zend_Uri_Exception When an illegal scheme is supplied - * @throws Zend_Uri_Exception When the scheme is not supported - * @return Zend_Uri - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public static function factory($uri = 'http') - { - // Separate the scheme from the scheme-specific parts - $uri = explode(':', $uri, 2); - $scheme = strtolower($uri[0]); - $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; - - if (strlen($scheme) === 0) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('An empty string was supplied for the scheme'); - } - - // Security check: $scheme is used to load a class file, so only alphanumerics are allowed. - if (ctype_alnum($scheme) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted'); - } - - /** - * Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the - * scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown. - */ - switch ($scheme) { - case 'http': - // Break intentionally omitted - case 'https': - $className = 'Zend_Uri_Http'; - break; - - case 'mailto': - // TODO - default: - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported"); - break; - } - - Zend_Loader::loadClass($className); - $schemeHandler = new $className($scheme, $schemeSpecific); - - return $schemeHandler; - } - - /** - * Get the URI's scheme - * - * @return string|false Scheme or false if no scheme is set. - */ - public function getScheme() - { - if (empty($this->_scheme) === false) { - return $this->_scheme; - } else { - return false; - } - } - - /** - * Zend_Uri and its subclasses cannot be instantiated directly. - * Use Zend_Uri::factory() to return a new Zend_Uri object. - * - * @param string $scheme The scheme of the URI - * @param string $schemeSpecific The scheme-specific part of the URI - */ - abstract protected function __construct($scheme, $schemeSpecific = ''); - - /** - * Return a string representation of this URI. - * - * @return string - */ - abstract public function getUri(); - - /** - * Returns TRUE if this URI is valid, or FALSE otherwise. - * - * @return boolean - */ - abstract public function valid(); -} diff --git a/phpQuery/phpQuery/Zend/Uri/Exception.php b/phpQuery/phpQuery/Zend/Uri/Exception.php deleted file mode 100644 index d327f3c..0000000 --- a/phpQuery/phpQuery/Zend/Uri/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ -_scheme = $scheme; - - // Set up grammar rules for validation via regular expressions. These - // are to be used with slash-delimited regular expression strings. - $this->_regex['alphanum'] = '[^\W_]'; - $this->_regex['escaped'] = '(?:%[\da-fA-F]{2})'; - $this->_regex['mark'] = '[-_.!~*\'()\[\]]'; - $this->_regex['reserved'] = '[;\/?:@&=+$,]'; - $this->_regex['unreserved'] = '(?:' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . ')'; - $this->_regex['segment'] = '(?:(?:' . $this->_regex['unreserved'] . '|' . $this->_regex['escaped'] - . '|[:@&=+$,;])*)'; - $this->_regex['path'] = '(?:\/' . $this->_regex['segment'] . '?)+'; - $this->_regex['uric'] = '(?:' . $this->_regex['reserved'] . '|' . $this->_regex['unreserved'] . '|' - . $this->_regex['escaped'] . ')'; - // If no scheme-specific part was supplied, the user intends to create - // a new URI with this object. No further parsing is required. - if (strlen($schemeSpecific) === 0) { - return; - } - - // Parse the scheme-specific URI parts into the instance variables. - $this->_parseUri($schemeSpecific); - - // Validate the URI - if ($this->valid() === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Invalid URI supplied'); - } - } - - /** - * Creates a Zend_Uri_Http from the given string - * - * @param string $uri String to create URI from, must start with - * 'http://' or 'https://' - * @throws InvalidArgumentException When the given $uri is not a string or - * does not start with http:// or https:// - * @throws Zend_Uri_Exception When the given $uri is invalid - * @return Zend_Uri_Http - */ - public static function fromString($uri) - { - if (is_string($uri) === false) { - throw new InvalidArgumentException('$uri is not a string'); - } - - $uri = explode(':', $uri, 2); - $scheme = strtolower($uri[0]); - $schemeSpecific = isset($uri[1]) === true ? $uri[1] : ''; - - if (in_array($scheme, array('http', 'https')) === false) { - throw new Zend_Uri_Exception("Invalid scheme: '$scheme'"); - } - - $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific); - return $schemeHandler; - } - - /** - * Parse the scheme-specific portion of the URI and place its parts into instance variables. - * - * @param string $schemeSpecific The scheme-specific portion to parse - * @throws Zend_Uri_Exception When scheme-specific decoposition fails - * @throws Zend_Uri_Exception When authority decomposition fails - * @return void - */ - protected function _parseUri($schemeSpecific) - { - // High-level decomposition parser - $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~'; - $status = @preg_match($pattern, $schemeSpecific, $matches); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed'); - } - - // Failed decomposition; no further processing needed - if ($status === false) { - return; - } - - // Save URI components that need no further decomposition - $this->_path = isset($matches[4]) === true ? $matches[4] : ''; - $this->_query = isset($matches[6]) === true ? $matches[6] : ''; - $this->_fragment = isset($matches[8]) === true ? $matches[8] : ''; - - // Additional decomposition to get username, password, host, and port - $combo = isset($matches[3]) === true ? $matches[3] : ''; - $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~'; - $status = @preg_match($pattern, $combo, $matches); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: authority decomposition failed'); - } - - // Failed decomposition; no further processing needed - if ($status === false) { - return; - } - - // Save remaining URI components - $this->_username = isset($matches[2]) === true ? $matches[2] : ''; - $this->_password = isset($matches[4]) === true ? $matches[4] : ''; - $this->_host = isset($matches[5]) === true ? $matches[5] : ''; - $this->_port = isset($matches[7]) === true ? $matches[7] : ''; - - } - - /** - * Returns a URI based on current values of the instance variables. If any - * part of the URI does not pass validation, then an exception is thrown. - * - * @throws Zend_Uri_Exception When one or more parts of the URI are invalid - * @return string - */ - public function getUri() - { - if ($this->valid() === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('One or more parts of the URI are invalid'); - } - - $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; - $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; - $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; - $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; - $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; - - return $this->_scheme - . '://' - . $auth - . $this->_host - . $port - . $this->_path - . $query - . $fragment; - } - - /** - * Validate the current URI from the instance variables. Returns true if and only if all - * parts pass validation. - * - * @return boolean - */ - public function valid() - { - // Return true if and only if all parts of the URI have passed validation - return $this->validateUsername() - and $this->validatePassword() - and $this->validateHost() - and $this->validatePort() - and $this->validatePath() - and $this->validateQuery() - and $this->validateFragment(); - } - - /** - * Returns the username portion of the URL, or FALSE if none. - * - * @return string - */ - public function getUsername() - { - return strlen($this->_username) > 0 ? $this->_username : false; - } - - /** - * Returns true if and only if the username passes validation. If no username is passed, - * then the username contained in the instance variable is used. - * - * @param string $username The HTTP username - * @throws Zend_Uri_Exception When username validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateUsername($username = null) - { - if ($username === null) { - $username = $this->_username; - } - - // If the username is empty, then it is considered valid - if (strlen($username) === 0) { - return true; - } - - // Check the username against the allowed values - $status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|' - . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $username); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: username validation failed'); - } - - return $status === 1; - } - - /** - * Sets the username for the current URI, and returns the old username - * - * @param string $username The HTTP username - * @throws Zend_Uri_Exception When $username is not a valid HTTP username - * @return string - */ - public function setUsername($username) - { - if ($this->validateUsername($username) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username"); - } - - $oldUsername = $this->_username; - $this->_username = $username; - - return $oldUsername; - } - - /** - * Returns the password portion of the URL, or FALSE if none. - * - * @return string - */ - public function getPassword() - { - return strlen($this->_password) > 0 ? $this->_password : false; - } - - /** - * Returns true if and only if the password passes validation. If no password is passed, - * then the password contained in the instance variable is used. - * - * @param string $password The HTTP password - * @throws Zend_Uri_Exception When password validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validatePassword($password = null) - { - if ($password === null) { - $password = $this->_password; - } - - // If the password is empty, then it is considered valid - if (strlen($password) === 0) { - return true; - } - - // If the password is nonempty, but there is no username, then it is considered invalid - if (strlen($password) > 0 and strlen($this->_username) === 0) { - return false; - } - - // Check the password against the allowed values - $status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|' - . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $password); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: password validation failed.'); - } - - return $status == 1; - } - - /** - * Sets the password for the current URI, and returns the old password - * - * @param string $password The HTTP password - * @throws Zend_Uri_Exception When $password is not a valid HTTP password - * @return string - */ - public function setPassword($password) - { - if ($this->validatePassword($password) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password."); - } - - $oldPassword = $this->_password; - $this->_password = $password; - - return $oldPassword; - } - - /** - * Returns the domain or host IP portion of the URL, or FALSE if none. - * - * @return string - */ - public function getHost() - { - return strlen($this->_host) > 0 ? $this->_host : false; - } - - /** - * Returns true if and only if the host string passes validation. If no host is passed, - * then the host contained in the instance variable is used. - * - * @param string $host The HTTP host - * @return boolean - * @uses Zend_Filter - */ - public function validateHost($host = null) - { - if ($host === null) { - $host = $this->_host; - } - - // If the host is empty, then it is considered invalid - if (strlen($host) === 0) { - return false; - } - - // Check the host against the allowed values; delegated to Zend_Filter. - $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL); - - return $validate->isValid($host); - } - - /** - * Sets the host for the current URI, and returns the old host - * - * @param string $host The HTTP host - * @throws Zend_Uri_Exception When $host is nota valid HTTP host - * @return string - */ - public function setHost($host) - { - if ($this->validateHost($host) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host"); - } - - $oldHost = $this->_host; - $this->_host = $host; - - return $oldHost; - } - - /** - * Returns the TCP port, or FALSE if none. - * - * @return string - */ - public function getPort() - { - return strlen($this->_port) > 0 ? $this->_port : false; - } - - /** - * Returns true if and only if the TCP port string passes validation. If no port is passed, - * then the port contained in the instance variable is used. - * - * @param string $port The HTTP port - * @return boolean - */ - public function validatePort($port = null) - { - if ($port === null) { - $port = $this->_port; - } - - // If the port is empty, then it is considered valid - if (strlen($port) === 0) { - return true; - } - - // Check the port against the allowed values - return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; - } - - /** - * Sets the port for the current URI, and returns the old port - * - * @param string $port The HTTP port - * @throws Zend_Uri_Exception When $port is not a valid HTTP port - * @return string - */ - public function setPort($port) - { - if ($this->validatePort($port) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port."); - } - - $oldPort = $this->_port; - $this->_port = $port; - - return $oldPort; - } - - /** - * Returns the path and filename portion of the URL, or FALSE if none. - * - * @return string - */ - public function getPath() - { - return strlen($this->_path) > 0 ? $this->_path : '/'; - } - - /** - * Returns true if and only if the path string passes validation. If no path is passed, - * then the path contained in the instance variable is used. - * - * @param string $path The HTTP path - * @throws Zend_Uri_Exception When path validation fails - * @return boolean - */ - public function validatePath($path = null) - { - if ($path === null) { - $path = $this->_path; - } - - // If the path is empty, then it is considered valid - if (strlen($path) === 0) { - return true; - } - - // Determine whether the path is well-formed - $pattern = '/^' . $this->_regex['path'] . '$/'; - $status = @preg_match($pattern, $path); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: path validation failed'); - } - - return (boolean) $status; - } - - /** - * Sets the path for the current URI, and returns the old path - * - * @param string $path The HTTP path - * @throws Zend_Uri_Exception When $path is not a valid HTTP path - * @return string - */ - public function setPath($path) - { - if ($this->validatePath($path) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path"); - } - - $oldPath = $this->_path; - $this->_path = $path; - - return $oldPath; - } - - /** - * Returns the query portion of the URL (after ?), or FALSE if none. - * - * @return string - */ - public function getQuery() - { - return strlen($this->_query) > 0 ? $this->_query : false; - } - - /** - * Returns true if and only if the query string passes validation. If no query is passed, - * then the query string contained in the instance variable is used. - * - * @param string $query The query to validate - * @throws Zend_Uri_Exception When query validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateQuery($query = null) - { - if ($query === null) { - $query = $this->_query; - } - - // If query is empty, it is considered to be valid - if (strlen($query) === 0) { - return true; - } - - // Determine whether the query is well-formed - $pattern = '/^' . $this->_regex['uric'] . '*$/'; - $status = @preg_match($pattern, $query); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: query validation failed'); - } - - return $status == 1; - } - - /** - * Set the query string for the current URI, and return the old query - * string This method accepts both strings and arrays. - * - * @param string|array $query The query string or array - * @throws Zend_Uri_Exception When $query is not a valid query string - * @return string Old query string - */ - public function setQuery($query) - { - $oldQuery = $this->_query; - - // If query is empty, set an empty string - if (empty($query) === true) { - $this->_query = ''; - return $oldQuery; - } - - // If query is an array, make a string out of it - if (is_array($query) === true) { - $query = http_build_query($query, '', '&'); - } else { - // If it is a string, make sure it is valid. If not parse and encode it - $query = (string) $query; - if ($this->validateQuery($query) === false) { - parse_str($query, $queryArray); - $query = http_build_query($queryArray, '', '&'); - } - } - - // Make sure the query is valid, and set it - if ($this->validateQuery($query) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("'$query' is not a valid query string"); - } - - $this->_query = $query; - - return $oldQuery; - } - - /** - * Returns the fragment portion of the URL (after #), or FALSE if none. - * - * @return string|false - */ - public function getFragment() - { - return strlen($this->_fragment) > 0 ? $this->_fragment : false; - } - - /** - * Returns true if and only if the fragment passes validation. If no fragment is passed, - * then the fragment contained in the instance variable is used. - * - * @param string $fragment Fragment of an URI - * @throws Zend_Uri_Exception When fragment validation fails - * @return boolean - * @link http://www.faqs.org/rfcs/rfc2396.html - */ - public function validateFragment($fragment = null) - { - if ($fragment === null) { - $fragment = $this->_fragment; - } - - // If fragment is empty, it is considered to be valid - if (strlen($fragment) === 0) { - return true; - } - - // Determine whether the fragment is well-formed - $pattern = '/^' . $this->_regex['uric'] . '*$/'; - $status = @preg_match($pattern, $fragment); - if ($status === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception('Internal error: fragment validation failed'); - } - - return (boolean) $status; - } - - /** - * Sets the fragment for the current URI, and returns the old fragment - * - * @param string $fragment Fragment of the current URI - * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment - * @return string - */ - public function setFragment($fragment) - { - if ($this->validateFragment($fragment) === false) { - require_once 'Zend/Uri/Exception.php'; - throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment"); - } - - $oldFragment = $this->_fragment; - $this->_fragment = $fragment; - - return $oldFragment; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Abstract.php b/phpQuery/phpQuery/Zend/Validate/Abstract.php deleted file mode 100644 index 1c11d54..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Abstract.php +++ /dev/null @@ -1,348 +0,0 @@ -_messages; - } - - /** - * Returns an array of the names of variables that are used in constructing validation failure messages - * - * @return array - */ - public function getMessageVariables() - { - return array_keys($this->_messageVariables); - } - - /** - * Sets the validation failure message template for a particular key - * - * @param string $messageString - * @param string $messageKey OPTIONAL - * @return Zend_Validate_Abstract Provides a fluent interface - * @throws Zend_Validate_Exception - */ - public function setMessage($messageString, $messageKey = null) - { - if ($messageKey === null) { - $keys = array_keys($this->_messageTemplates); - $messageKey = current($keys); - } - if (!isset($this->_messageTemplates[$messageKey])) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("No message template exists for key '$messageKey'"); - } - $this->_messageTemplates[$messageKey] = $messageString; - return $this; - } - - /** - * Sets validation failure message templates given as an array, where the array keys are the message keys, - * and the array values are the message template strings. - * - * @param array $messages - * @return Zend_Validate_Abstract - */ - public function setMessages(array $messages) - { - foreach ($messages as $key => $message) { - $this->setMessage($message, $key); - } - return $this; - } - - /** - * Magic function returns the value of the requested property, if and only if it is the value or a - * message variable. - * - * @param string $property - * @return mixed - * @throws Zend_Validate_Exception - */ - public function __get($property) - { - if ($property == 'value') { - return $this->_value; - } - if (array_key_exists($property, $this->_messageVariables)) { - return $this->{$this->_messageVariables[$property]}; - } - /** - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("No property exists by the name '$property'"); - } - - /** - * Constructs and returns a validation failure message with the given message key and value. - * - * Returns null if and only if $messageKey does not correspond to an existing template. - * - * If a translator is available and a translation exists for $messageKey, - * the translation will be used. - * - * @param string $messageKey - * @param string $value - * @return string - */ - protected function _createMessage($messageKey, $value) - { - if (!isset($this->_messageTemplates[$messageKey])) { - return null; - } - - $message = $this->_messageTemplates[$messageKey]; - - if (null !== ($translator = $this->getTranslator())) { - if ($translator->isTranslated($message)) { - $message = $translator->translate($message); - } elseif ($translator->isTranslated($messageKey)) { - $message = $translator->translate($messageKey); - } - } - - if ($this->getObscureValue()) { - $value = str_repeat('*', strlen($value)); - } - - $message = str_replace('%value%', (string) $value, $message); - foreach ($this->_messageVariables as $ident => $property) { - $message = str_replace("%$ident%", $this->$property, $message); - } - return $message; - } - - /** - * @param string $messageKey OPTIONAL - * @param string $value OPTIONAL - * @return void - */ - protected function _error($messageKey = null, $value = null) - { - if ($messageKey === null) { - $keys = array_keys($this->_messageTemplates); - $messageKey = current($keys); - } - if ($value === null) { - $value = $this->_value; - } - $this->_errors[] = $messageKey; - $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value); - } - - /** - * Sets the value to be validated and clears the messages and errors arrays - * - * @param mixed $value - * @return void - */ - protected function _setValue($value) - { - $this->_value = $value; - $this->_messages = array(); - $this->_errors = array(); - } - - /** - * Returns array of validation failure message codes - * - * @return array - * @deprecated Since 1.5.0 - */ - public function getErrors() - { - return $this->_errors; - } - - /** - * Set flag indicating whether or not value should be obfuscated in messages - * - * @param bool $flag - * @return Zend_Validate_Abstract - */ - public function setObscureValue($flag) - { - $this->_obscureValue = (bool) $flag; - return $this; - } - - /** - * Retrieve flag indicating whether or not value should be obfuscated in - * messages - * - * @return bool - */ - public function getObscureValue() - { - return $this->_obscureValue; - } - - /** - * Set translation object - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - * @return Zend_Validate_Abstract - */ - public function setTranslator($translator = null) - { - if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) { - $this->_translator = $translator; - } elseif ($translator instanceof Zend_Translate) { - $this->_translator = $translator->getAdapter(); - } else { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid translator specified'); - } - return $this; - } - - /** - * Return translation object - * - * @return Zend_Translate_Adapter|null - */ - public function getTranslator() - { - if (null === $this->_translator) { - return self::getDefaultTranslator(); - } - - return $this->_translator; - } - - /** - * Set default translation object for all validate objects - * - * @param Zend_Translate|Zend_Translate_Adapter|null $translator - * @return void - */ - public static function setDefaultTranslator($translator = null) - { - if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) { - self::$_defaultTranslator = $translator; - } elseif ($translator instanceof Zend_Translate) { - self::$_defaultTranslator = $translator->getAdapter(); - } else { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Invalid translator specified'); - } - } - - /** - * Get default translation object for all validate objects - * - * @return Zend_Translate_Adapter|null - */ - public static function getDefaultTranslator() - { - if (null === self::$_defaultTranslator) { - require_once 'Zend/Registry.php'; - if (Zend_Registry::isRegistered('Zend_Translate')) { - $translator = Zend_Registry::get('Zend_Translate'); - if ($translator instanceof Zend_Translate_Adapter) { - return $translator; - } elseif ($translator instanceof Zend_Translate) { - return $translator->getAdapter(); - } - } - } - return self::$_defaultTranslator; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Alnum.php b/phpQuery/phpQuery/Zend/Validate/Alnum.php deleted file mode 100644 index 36b0adc..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Alnum.php +++ /dev/null @@ -1,120 +0,0 @@ - "'%value%' has not only alphabetic and digit characters", - self::STRING_EMPTY => "'%value%' is an empty string" - ); - - /** - * Sets default option values for this instance - * - * @param boolean $allowWhiteSpace - * @return void - */ - public function __construct($allowWhiteSpace = false) - { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only alphabetic and digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if ('' === $valueString) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Alnum - */ - require_once 'Zend/Filter/Alnum.php'; - self::$_filter = new Zend_Filter_Alnum(); - } - - self::$_filter->allowWhiteSpace = $this->allowWhiteSpace; - - if ($valueString !== self::$_filter->filter($valueString)) { - $this->_error(self::NOT_ALNUM); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Alpha.php b/phpQuery/phpQuery/Zend/Validate/Alpha.php deleted file mode 100644 index 0f2298e..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Alpha.php +++ /dev/null @@ -1,120 +0,0 @@ - "'%value%' has not only alphabetic characters", - self::STRING_EMPTY => "'%value%' is an empty string" - ); - - /** - * Sets default option values for this instance - * - * @param boolean $allowWhiteSpace - * @return void - */ - public function __construct($allowWhiteSpace = false) - { - $this->allowWhiteSpace = (boolean) $allowWhiteSpace; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only alphabetic characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if ('' === $valueString) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Alpha - */ - require_once 'Zend/Filter/Alpha.php'; - self::$_filter = new Zend_Filter_Alpha(); - } - - self::$_filter->allowWhiteSpace = $this->allowWhiteSpace; - - if ($valueString !== self::$_filter->filter($valueString)) { - $this->_error(self::NOT_ALPHA); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Barcode.php b/phpQuery/phpQuery/Zend/Validate/Barcode.php deleted file mode 100644 index d51f11b..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Barcode.php +++ /dev/null @@ -1,99 +0,0 @@ -setType($barcodeType); - } - - /** - * Sets a new barcode validator - * - * @param string $barcodeType - Barcode validator to use - * @return void - * @throws Zend_Validate_Exception - */ - public function setType($barcodeType) - { - switch (strtolower($barcodeType)) { - case 'upc': - case 'upc-a': - $className = 'UpcA'; - break; - case 'ean13': - case 'ean-13': - $className = 'Ean13'; - break; - default: - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Barcode type '$barcodeType' is not supported'"); - break; - } - - require_once 'Zend/Validate/Barcode/' . $className . '.php'; - - $class = 'Zend_Validate_Barcode_' . $className; - $this->_barcodeValidator = new $class; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains a valid barcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - return call_user_func(array($this->_barcodeValidator, 'isValid'), $value); - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Barcode/Ean13.php b/phpQuery/phpQuery/Zend/Validate/Barcode/Ean13.php deleted file mode 100644 index 7be797d..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Barcode/Ean13.php +++ /dev/null @@ -1,100 +0,0 @@ - "'%value%' is an invalid EAN-13 barcode", - self::INVALID_LENGTH => "'%value%' should be 13 characters", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains a valid barcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - $this->_setValue($valueString); - - if (strlen($valueString) !== 13) { - $this->_error(self::INVALID_LENGTH); - return false; - } - - $barcode = strrev(substr($valueString, 0, -1)); - $oddSum = 0; - $evenSum = 0; - - for ($i = 0; $i < 12; $i++) { - if ($i % 2 === 0) { - $oddSum += $barcode[$i] * 3; - } elseif ($i % 2 === 1) { - $evenSum += $barcode[$i]; - } - } - - $calculation = ($oddSum + $evenSum) % 10; - $checksum = ($calculation === 0) ? 0 : 10 - $calculation; - - if ($valueString[12] != $checksum) { - $this->_error(self::INVALID); - return false; - } - - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Barcode/UpcA.php b/phpQuery/phpQuery/Zend/Validate/Barcode/UpcA.php deleted file mode 100644 index c584e81..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Barcode/UpcA.php +++ /dev/null @@ -1,100 +0,0 @@ - "'%value%' is an invalid UPC-A barcode", - self::INVALID_LENGTH => "'%value%' should be 12 characters", - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains a valid barcode - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - $this->_setValue($valueString); - - if (strlen($valueString) !== 12) { - $this->_error(self::INVALID_LENGTH); - return false; - } - - $barcode = substr($valueString, 0, -1); - $oddSum = 0; - $evenSum = 0; - - for ($i = 0; $i < 11; $i++) { - if ($i % 2 === 0) { - $oddSum += $barcode[$i] * 3; - } elseif ($i % 2 === 1) { - $evenSum += $barcode[$i]; - } - } - - $calculation = ($oddSum + $evenSum) % 10; - $checksum = ($calculation === 0) ? 0 : 10 - $calculation; - - if ($valueString[11] != $checksum) { - $this->_error(self::INVALID); - return false; - } - - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Between.php b/phpQuery/phpQuery/Zend/Validate/Between.php deleted file mode 100644 index bb0b726..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Between.php +++ /dev/null @@ -1,200 +0,0 @@ - "'%value%' is not between '%min%' and '%max%', inclusively", - self::NOT_BETWEEN_STRICT => "'%value%' is not strictly between '%min%' and '%max%'" - ); - - /** - * Additional variables available for validation failure messages - * - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum value - * - * @var mixed - */ - protected $_min; - - /** - * Maximum value - * - * @var mixed - */ - protected $_max; - - /** - * Whether to do inclusive comparisons, allowing equivalence to min and/or max - * - * If false, then strict comparisons are done, and the value may equal neither - * the min nor max options - * - * @var boolean - */ - protected $_inclusive; - - /** - * Sets validator options - * - * @param mixed $min - * @param mixed $max - * @param boolean $inclusive - * @return void - */ - public function __construct($min, $max, $inclusive = true) - { - $this->setMin($min) - ->setMax($max) - ->setInclusive($inclusive); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param mixed $min - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setMin($min) - { - $this->_min = $min; - return $this; - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param mixed $max - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setMax($max) - { - $this->_max = $max; - return $this; - } - - /** - * Returns the inclusive option - * - * @return boolean - */ - public function getInclusive() - { - return $this->_inclusive; - } - - /** - * Sets the inclusive option - * - * @param boolean $inclusive - * @return Zend_Validate_Between Provides a fluent interface - */ - public function setInclusive($inclusive) - { - $this->_inclusive = $inclusive; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is between min and max options, inclusively - * if inclusive option is true. - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if ($this->_inclusive) { - if ($this->_min > $value || $value > $this->_max) { - $this->_error(self::NOT_BETWEEN); - return false; - } - } else { - if ($this->_min >= $value || $value >= $this->_max) { - $this->_error(self::NOT_BETWEEN_STRICT); - return false; - } - } - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Ccnum.php b/phpQuery/phpQuery/Zend/Validate/Ccnum.php deleted file mode 100644 index 227a4ec..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Ccnum.php +++ /dev/null @@ -1,111 +0,0 @@ - "'%value%' must contain between 13 and 19 digits", - self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum) - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Digits - */ - require_once 'Zend/Filter/Digits.php'; - self::$_filter = new Zend_Filter_Digits(); - } - - $valueFiltered = self::$_filter->filter($value); - - $length = strlen($valueFiltered); - - if ($length < 13 || $length > 19) { - $this->_error(self::LENGTH); - return false; - } - - $sum = 0; - $weight = 2; - - for ($i = $length - 2; $i >= 0; $i--) { - $digit = $weight * $valueFiltered[$i]; - $sum += floor($digit / 10) + $digit % 10; - $weight = $weight % 2 + 1; - } - - if ((10 - $sum % 10) % 10 != $valueFiltered[$length - 1]) { - $this->_error(self::CHECKSUM, $valueFiltered); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Date.php b/phpQuery/phpQuery/Zend/Validate/Date.php deleted file mode 100644 index 220b0ee..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Date.php +++ /dev/null @@ -1,250 +0,0 @@ - "'%value%' is not of the format YYYY-MM-DD", - self::INVALID => "'%value%' does not appear to be a valid date", - self::FALSEFORMAT => "'%value%' does not fit given date format" - ); - - /** - * Optional format - * - * @var string|null - */ - protected $_format; - - /** - * Optional locale - * - * @var string|Zend_Locale|null - */ - protected $_locale; - - /** - * Sets validator options - * - * @param string $format OPTIONAL - * @param string|Zend_Locale $locale OPTIONAL - * @return void - */ - public function __construct($format = null, $locale = null) - { - $this->setFormat($format); - $this->setLocale($locale); - } - - /** - * Returns the locale option - * - * @return string|Zend_Locale|null - */ - public function getLocale() - { - return $this->_locale; - } - - /** - * Sets the locale option - * - * @param string|Zend_Locale $locale - * @return Zend_Validate_Date provides a fluent interface - */ - public function setLocale($locale = null) - { - if ($locale === null) { - $this->_locale = null; - return $this; - } - - require_once 'Zend/Locale.php'; - if (!Zend_Locale::isLocale($locale, true)) { - if (!Zend_Locale::isLocale($locale, false)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The locale '$locale' is no known locale"); - } - - $locale = new Zend_Locale($locale); - } - - $this->_locale = (string) $locale; - return $this; - } - - /** - * Returns the locale option - * - * @return string|null - */ - public function getFormat() - { - return $this->_format; - } - - /** - * Sets the format option - * - * @param string $format - * @return Zend_Validate_Date provides a fluent interface - */ - public function setFormat($format = null) - { - $this->_format = $format; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if $value is a valid date of the format YYYY-MM-DD - * If optional $format or $locale is set the date format is checked - * according to Zend_Date, see Zend_Date::isDate() - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if (($this->_format !== null) or ($this->_locale !== null)) { - require_once 'Zend/Date.php'; - if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) { - if ($this->_checkFormat($value) === false) { - $this->_error(self::FALSEFORMAT); - } else { - $this->_error(self::INVALID); - } - return false; - } - } else { - if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $valueString)) { - $this->_error(self::NOT_YYYY_MM_DD); - return false; - } - - list($year, $month, $day) = sscanf($valueString, '%d-%d-%d'); - - if (!checkdate($month, $day, $year)) { - $this->_error(self::INVALID); - return false; - } - } - - return true; - } - - /** - * Check if the given date fits the given format - * - * @param string $value Date to check - * @return boolean False when date does not fit the format - */ - private function _checkFormat($value) - { - try { - require_once 'Zend/Locale/Format.php'; - $parsed = Zend_Locale_Format::getDate($value, array( - 'date_format' => $this->_format, 'format_type' => 'iso', - 'fix_date' => false)); - if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and - (strpos(strtoupper($this->_format), 'YYYY') === false))) { - $parsed['year'] = Zend_Date::_century($parsed['year']); - } - } catch (Exception $e) { - // Date can not be parsed - return false; - } - - if (((strpos($this->_format, 'Y') !== false) or (strpos($this->_format, 'y') !== false)) and - (!isset($parsed['year']))) { - // Year expected but not found - return false; - } - - if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) { - // Month expected but not found - return false; - } - - if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) { - // Day expected but not found - return false; - } - - if (((strpos($this->_format, 'H') !== false) or (strpos($this->_format, 'h') !== false)) and - (!isset($parsed['hour']))) { - // Hour expected but not found - return false; - } - - if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) { - // Minute expected but not found - return false; - } - - if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) { - // Second expected but not found - return false; - } - - // Date fits the format - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Digits.php b/phpQuery/phpQuery/Zend/Validate/Digits.php deleted file mode 100644 index c42ec0a..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Digits.php +++ /dev/null @@ -1,100 +0,0 @@ - "'%value%' contains not only digit characters", - self::STRING_EMPTY => "'%value%' is an empty string" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value only contains digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if ('' === $valueString) { - $this->_error(self::STRING_EMPTY); - return false; - } - - if (null === self::$_filter) { - /** - * @see Zend_Filter_Digits - */ - require_once 'Zend/Filter/Digits.php'; - self::$_filter = new Zend_Filter_Digits(); - } - - if ($valueString !== self::$_filter->filter($valueString)) { - $this->_error(self::NOT_DIGITS); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/EmailAddress.php b/phpQuery/phpQuery/Zend/Validate/EmailAddress.php deleted file mode 100644 index d8e9595..0000000 --- a/phpQuery/phpQuery/Zend/Validate/EmailAddress.php +++ /dev/null @@ -1,245 +0,0 @@ - "'%value%' is not a valid email address in the basic format local-part@hostname", - self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'", - self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'", - self::DOT_ATOM => "'%localPart%' not matched against dot-atom format", - self::QUOTED_STRING => "'%localPart%' not matched against quoted-string format", - self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'hostname' => '_hostname', - 'localPart' => '_localPart' - ); - - /** - * Local object for validating the hostname part of an email address - * - * @var Zend_Validate_Hostname - */ - public $hostnameValidator; - - /** - * Whether we check for a valid MX record via DNS - * - * @var boolean - */ - protected $_validateMx = false; - - /** - * @var string - */ - protected $_hostname; - - /** - * @var string - */ - protected $_localPart; - - /** - * Instantiates hostname validator for local use - * - * You can pass a bitfield to determine what types of hostnames are allowed. - * These bitfields are defined by the ALLOW_* constants in Zend_Validate_Hostname - * The default is to allow DNS hostnames only - * - * @param integer $allow OPTIONAL - * @param bool $validateMx OPTIONAL - * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL - * @return void - */ - public function __construct($allow = Zend_Validate_Hostname::ALLOW_DNS, $validateMx = false, Zend_Validate_Hostname $hostnameValidator = null) - { - $this->setValidateMx($validateMx); - $this->setHostnameValidator($hostnameValidator, $allow); - } - - /** - * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL - * @param int $allow OPTIONAL - * @return void - */ - public function setHostnameValidator(Zend_Validate_Hostname $hostnameValidator = null, $allow = Zend_Validate_Hostname::ALLOW_DNS) - { - if ($hostnameValidator === null) { - $hostnameValidator = new Zend_Validate_Hostname($allow); - } - $this->hostnameValidator = $hostnameValidator; - } - - /** - * Whether MX checking via dns_get_mx is supported or not - * - * This currently only works on UNIX systems - * - * @return boolean - */ - public function validateMxSupported() - { - return function_exists('dns_get_mx'); - } - - /** - * Set whether we check for a valid MX record via DNS - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate for MX records, and false to not validate them - */ - public function setValidateMx($allowed) - { - $this->_validateMx = (bool) $allowed; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid email address - * according to RFC2822 - * - * @link http://www.ietf.org/rfc/rfc2822.txt RFC2822 - * @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - // Split email address up - if (!preg_match('/^(.+)@([^@]+)$/', $valueString, $matches)) { - $this->_error(self::INVALID); - return false; - } - - $this->_localPart = $matches[1]; - $this->_hostname = $matches[2]; - - // Match hostname part - $hostnameResult = $this->hostnameValidator->setTranslator($this->getTranslator()) - ->isValid($this->_hostname); - if (!$hostnameResult) { - $this->_error(self::INVALID_HOSTNAME); - - // Get messages and errors from hostnameValidator - foreach ($this->hostnameValidator->getMessages() as $message) { - $this->_messages[] = $message; - } - foreach ($this->hostnameValidator->getErrors() as $error) { - $this->_errors[] = $error; - } - } - - // MX check on hostname via dns_get_record() - if ($this->_validateMx) { - if ($this->validateMxSupported()) { - $result = dns_get_mx($this->_hostname, $mxHosts); - if (count($mxHosts) < 1) { - $hostnameResult = false; - $this->_error(self::INVALID_MX_RECORD); - } - } else { - /** - * MX checks are not supported by this system - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Internal error: MX checking not available on this system'); - } - } - - // First try to match the local part on the common dot-atom format - $localResult = false; - - // Dot-atom characters are: 1*atext *("." 1*atext) - // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*", - // "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~" - $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d'; - if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) { - $localResult = true; - } else { - // Try quoted string format - - // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE - // qtext: Non white space controls, and the rest of the US-ASCII characters not - // including "\" or the quote character - $noWsCtl = '\x01-\x08\x0b\x0c\x0e-\x1f\x7f'; - $qtext = $noWsCtl . '\x21\x23-\x5b\x5d-\x7e'; - $ws = '\x20\x09'; - if (preg_match('/^\x22([' . $ws . $qtext . '])*[$ws]?\x22$/', $this->_localPart)) { - $localResult = true; - } else { - $this->_error(self::DOT_ATOM); - $this->_error(self::QUOTED_STRING); - $this->_error(self::INVALID_LOCAL_PART); - } - } - - // If both parts valid, return true - if ($localResult && $hostnameResult) { - return true; - } else { - return false; - } - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Exception.php b/phpQuery/phpQuery/Zend/Validate/Exception.php deleted file mode 100644 index a38077e..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Exception.php +++ /dev/null @@ -1,37 +0,0 @@ - "Too much files, only '%value%' are allowed", - self::TOO_LESS => "Too less files, minimum '%value%' must be given" - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum file count - * - * If null, there is no minimum file count - * - * @var integer - */ - protected $_min; - - /** - * Maximum file count - * - * If null, there is no maximum file count - * - * @var integer|null - */ - protected $_max; - - /** - * Internal file array - * @var array - */ - protected $_files; - - /** - * Sets validator options - * - * Min limits the file count, when used with max=null it is the maximum file count - * It also accepts an array with the keys 'min' and 'max' - * - * @param integer|array $min Minimum file count - * @param integer $max Maximum file count - * @return void - */ - public function __construct($min, $max = null) - { - $this->_files = array(); - if (is_array($min) === true) { - if (isset($min['max']) === true) { - $max = $min['max']; - } - - if (isset($min['min']) === true) { - $min = $min['min']; - } - - if (isset($min[0]) === true) { - if (count($min) === 2) { - $max = $min[1]; - $min = $min[0]; - } else { - $max = $min[0]; - $min = null; - } - } - } - - if (empty($max) === true) { - $max = $min; - $min = null; - } - - $this->setMin($min); - $this->setMax($max); - } - - /** - * Returns the minimum file count - * - * @return integer - */ - public function getMin() - { - $min = $this->_min; - - return $min; - } - - /** - * Sets the minimum file count - * - * @param integer $min The minimum file count - * @return Zend_Validate_File_Size Provides a fluent interface - * @throws Zend_Validate_Exception When min is greater than max - */ - public function setMin($min) - { - if ($min === null) { - $this->_min = null; - } else if (($this->_max !== null) and ($min > $this->_max)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('The minimum must be less than or equal to the maximum file count, but ' - . " {$min} > {$this->_max}"); - } else { - $this->_min = max(0, (integer) $min); - } - - return $this; - } - - /** - * Returns the maximum file count - * - * @return integer|null - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the maximum file count - * - * @param integer|null $max The maximum file count - * @throws Zend_Validate_Exception When max is smaller than min - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMax($max) - { - if ($max === null) { - $this->_max = null; - } else if (($this->_min !== null) and ($max < $this->_min)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum file count, but " - . "{$max} < {$this->_min}"); - } else { - $this->_max = (integer) $max; - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file count of all checked files is at least min and - * not bigger than max (when max is not null). Attention: When checking with set min you - * must give all files with the first call, otherwise you will get an false. - * - * @param string|array $value Filenames to check for count - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - if (is_string($value)) { - $value = array($value); - } - - foreach ($value as $file) { - if (!isset($this->_files[$file])) { - $this->_files[$file] = $file; - } - } - - if (($this->_max !== null) && (count($this->_files) > $this->_max)) { - $this->_value = $this->_max; - $this->_error(self::TOO_MUCH); - return false; - } - - if (($this->_min !== null) && (count($this->_files) < $this->_min)) { - $this->_value = $this->_min; - $this->_error(self::TOO_LESS); - return false; - } - - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/Exists.php b/phpQuery/phpQuery/Zend/Validate/File/Exists.php deleted file mode 100644 index 268090b..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/Exists.php +++ /dev/null @@ -1,192 +0,0 @@ - "The file '%value%' does not exist" - ); - - /** - * Internal list of directories - * @var string - */ - protected $_directory = ''; - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'directory' => '_directory' - ); - - /** - * Sets validator options - * - * @param string|array $directory - * @return void - */ - public function __construct($directory = array()) - { - $this->setDirectory($directory); - } - - /** - * Returns the set file directories which are checked - * - * @param boolean $asArray Returns the values as array, when false an concated string is returned - * @return string - */ - public function getDirectory($asArray = false) - { - $asArray = (bool) $asArray; - $directory = (string) $this->_directory; - if ($asArray) { - $directory = explode(',', $directory); - } - - return $directory; - } - - /** - * Sets the file directory which will be checked - * - * @param string|array $directory The directories to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setDirectory($directory) - { - $this->_directory = null; - $this->addDirectory($directory); - return $this; - } - - /** - * Adds the file directory which will be checked - * - * @param string|array $directory The directory to add for validation - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addDirectory($directory) - { - $directories = $this->getDirectory(true); - if (is_string($directory)) { - $directory = explode(',', $directory); - } - - foreach ($directory as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - - $directories[] = trim($content); - } - $directories = array_unique($directories); - - // Sanity check to ensure no empty values - foreach ($directories as $key => $dir) { - if (empty($dir)) { - unset($directories[$key]); - } - } - - $this->_directory = implode(',', $directories); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file already exists in the set directories - * - * @param string $value Real file to check for existance - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - $directories = $this->getDirectory(true); - if (($file !== null) and (!empty($file['destination']))) { - $directories[] = $file['destination']; - } else if (!isset($file['name'])) { - $file['name'] = $value; - } - - $check = false; - foreach ($directories as $directory) { - if (empty($directory)) { - continue; - } - - $check = true; - if (!file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { - $this->_throw($file, self::DOES_NOT_EXIST); - return false; - } - } - - if (!$check) { - $this->_throw($file, self::DOES_NOT_EXIST); - return false; - } - - return true; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/Extension.php b/phpQuery/phpQuery/Zend/Validate/File/Extension.php deleted file mode 100644 index 62577b3..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/Extension.php +++ /dev/null @@ -1,204 +0,0 @@ - "The file '%value%' has a false extension", - self::NOT_FOUND => "The file '%value%' was not found" - ); - - /** - * Internal list of extensions - * @var string - */ - protected $_extension = ''; - - /** - * Validate case sensitive - * - * @var boolean - */ - protected $_case = false; - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'extension' => '_extension' - ); - - /** - * Sets validator options - * - * @param string|array $extension - * @param boolean $case If true validation is done case sensitive - * @return void - */ - public function __construct($extension, $case = false) - { - $this->_case = (boolean) $case; - $this->setExtension($extension); - } - - /** - * Returns the set file extension - * - * @param boolean $asArray Returns the values as array, when false an concated string is returned - * @return string - */ - public function getExtension($asArray = false) - { - $asArray = (bool) $asArray; - $extension = (string) $this->_extension; - if ($asArray) { - $extension = explode(',', $extension); - } - - return $extension; - } - - /** - * Sets the file extensions - * - * @param string|array $extension The extensions to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setExtension($extension) - { - $this->_extension = null; - $this->addExtension($extension); - return $this; - } - - /** - * Adds the file extensions - * - * @param string|array $extension The extensions to add for validation - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addExtension($extension) - { - $extensions = $this->getExtension(true); - if (is_string($extension)) { - $extension = explode(',', $extension); - } - - foreach ($extension as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - - $extensions[] = trim($content); - } - $extensions = array_unique($extensions); - - // Sanity check to ensure no empty values - foreach ($extensions as $key => $ext) { - if (empty($ext)) { - unset($extensions[$key]); - } - } - - $this->_extension = implode(',', $extensions); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the fileextension of $value is included in the - * set extension list - * - * @param string $value Real file to check for extension - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - if (!@is_readable($value)) { - $this->_throw($file, self::NOT_FOUND); - return false; - } - - if ($file !== null) { - $info['extension'] = substr($file['name'], strpos($file['name'], '.') + 1); - } else { - $info = @pathinfo($value); - } - - $extensions = $this->getExtension(true); - - if ($this->_case and (in_array($info['extension'], $extensions))) { - return true; - } else if (!$this->_case) { - foreach ($extensions as $extension) { - if (strtolower($extension) == strtolower($info['extension'])) { - return true; - } - } - } - - $this->_throw($file, self::FALSE_EXTENSION); - return false; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/FilesSize.php b/phpQuery/phpQuery/Zend/Validate/File/FilesSize.php deleted file mode 100644 index e8b060d..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/FilesSize.php +++ /dev/null @@ -1,156 +0,0 @@ - "The files in sum exceed the maximum allowed size", - self::TOO_SMALL => "All files are in sum smaller than required", - self::NOT_READABLE => "One or more files can not be read" - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum filesize - * - * @var integer - */ - protected $_min; - - /** - * Maximum filesize - * - * @var integer|null - */ - protected $_max; - - /** - * Internal file array - * - * @var array - */ - protected $_files; - - /** - * Internal file size counter - * - * @var integer - */ - protected $_size; - - /** - * Sets validator options - * - * Min limits the used diskspace for all files, when used with max=null it is the maximum filesize - * It also accepts an array with the keys 'min' and 'max' - * - * @param integer|array $min Minimum diskspace for all files - * @param integer $max Maximum diskspace for all files - * @return void - */ - public function __construct($min, $max = null) - { - $this->_files = array(); - $this->_size = 0; - parent::__construct($min, $max); - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the disk usage of all files is at least min and - * not bigger than max (when max is not null). - * - * @param string|array $value Real file to check for size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - if (is_string($value)) { - $value = array($value); - } - - foreach ($value as $files) { - // Is file readable ? - if (!@is_readable($files)) { - $this->_throw($file, self::NOT_READABLE); - return false; - } - - if (!isset($this->_files[$files])) { - $this->_files[$files] = $files; - } else { - // file already counted... do not count twice - continue; - } - - // limited to 2GB files - $size = @filesize($files); - $this->_size += $size; - $this->_setValue($this->_size); - if (($this->_max !== null) && ($this->_max < $this->_size)) { - $this->_throw($file, self::TOO_BIG); - } - } - - // Check that aggregate files are >= minimum size - if (($this->_min !== null) && ($this->_size < $this->_min)) { - $this->_throw($file, self::TOO_SMALL); - } - - if (count($this->_messages) > 0) { - return false; - } else { - return true; - } - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/ImageSize.php b/phpQuery/phpQuery/Zend/Validate/File/ImageSize.php deleted file mode 100644 index 6c27ef6..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/ImageSize.php +++ /dev/null @@ -1,335 +0,0 @@ - "Width of the image '%value%' is bigger than allowed", - self::WIDTH_TOO_SMALL => "Width of the image '%value%' is smaller than allowed", - self::HEIGHT_TOO_BIG => "Height of the image '%value%' is bigger than allowed", - self::HEIGHT_TOO_SMALL => "Height of the image '%value%' is smaller than allowed", - self::NOT_DETECTED => "Size of the image '%value%' could not be detected", - self::NOT_READABLE => "The image '%value%' can not be read" - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'minwidth' => '_minwidth', - 'maxwidth' => '_maxwidth', - 'minheight' => '_minheight', - 'maxheight' => '_maxheight' - ); - - /** - * Minimum image width - * - * @var integer - */ - protected $_minwidth; - - /** - * Maximum image width - * - * @var integer - */ - protected $_maxwidth; - - /** - * Minimum image height - * - * @var integer - */ - protected $_minheight; - - /** - * Maximum image height - * - * @var integer - */ - protected $_maxheight; - - /** - * Sets validator options - * - * Min limits the filesize, when used with max=null if is the maximum filesize - * It also accepts an array with the keys 'min' and 'max' - * - * @param integer|array $max Maximum filesize - * @param integer $max Maximum filesize - * @return void - */ - public function __construct($minwidth = 0, $minheight = 0, $maxwidth = null, $maxheight = null) - { - if (is_array($minwidth) === true) { - if (isset($minwidth['maxheight']) === true) { - $maxheight = $minwidth['maxheight']; - } - - if (isset($minwidth['minheight']) === true) { - $minheight = $minwidth['minheight']; - } - - if (isset($minwidth['maxwidth']) === true) { - $maxwidth = $minwidth['maxwidth']; - } - - if (isset($minwidth['minwidth']) === true) { - $minwidth = $minwidth['minwidth']; - } - - if (isset($minwidth[0]) === true) { - $maxheight = $minwidth[3]; - $maxwidth = $minwidth[2]; - $minheight = $minwidth[1]; - $minwidth = $minwidth[0]; - } - } - - $this->setImageMin($minwidth, $minheight); - $this->setImageMax($maxwidth, $maxheight); - } - - /** - * Returns the set minimum image sizes - * - * @return array - */ - public function getImageMin() - { - return array($this->_minwidth, $this->_minheight); - } - - /** - * Returns the set maximum image sizes - * - * @return array - */ - public function getImageMax() - { - return array($this->_maxwidth, $this->_maxheight); - } - - /** - * Returns the set image width sizes - * - * @return array - */ - public function getImageWidth() - { - return array($this->_minwidth, $this->_maxwidth); - } - - /** - * Returns the set image height sizes - * - * @return array - */ - public function getImageHeight() - { - return array($this->_minheight, $this->_maxheight); - } - - /** - * Sets the minimum image size - * - * @param integer $minwidth The minimum image width - * @param integer $minheight The minimum image height - * @throws Zend_Validate_Exception When minwidth is greater than maxwidth - * @throws Zend_Validate_Exception When minheight is greater than maxheight - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageMin($minwidth, $minheight) - { - if (($this->_maxwidth !== null) and ($minwidth > $this->_maxwidth)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum image width must be less than or equal to the " - . " maximum image width, but {$minwidth} > {$this->_maxwidth}"); - } - - if (($this->_maxheight !== null) and ($minheight > $this->_maxheight)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum image height must be less than or equal to the " - . " maximum image height, but {$minheight} > {$this->_maxheight}"); - } - - $this->_minwidth = max(0, (integer) $minwidth); - $this->_minheight = max(0, (integer) $minheight); - return $this; - } - - /** - * Sets the maximum image size - * - * @param integer $maxwidth The maximum image width - * @param integer $maxheight The maximum image height - * @throws Zend_Validate_Exception When maxwidth is smaller than minwidth - * @throws Zend_Validate_Exception When maxheight is smaller than minheight - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setImageMax($maxwidth, $maxheight) - { - if ($maxwidth === null) { - $tempwidth = null; - } else if (($this->_minwidth !== null) and ($maxwidth < $this->_minwidth)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum image width must be greater than or equal to the " - . "minimum image width, but {$maxwidth} < {$this->_minwidth}"); - } else { - $tempwidth = (integer) $maxwidth; - } - - if ($maxheight === null) { - $tempheight = null; - } else if (($this->_minheight !== null) and ($maxheight < $this->_minheight)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum image height must be greater than or equal to the " - . "minimum image height, but {$maxheight} < {$this->_minwidth}"); - } else { - $tempheight = (integer) $maxheight; - } - - $this->_maxwidth = $tempwidth; - $this->_maxheight = $tempheight; - return $this; - } - - /** - * Sets the mimimum and maximum image width - * - * @param integer $minwidth The minimum image width - * @param integer $maxwidth The maximum image width - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageWidth($minwidth, $maxwidth) - { - $this->setImageMin($minwidth, $this->_minheight); - $this->setImageMax($maxwidth, $this->_maxheight); - return $this; - } - - /** - * Sets the mimimum and maximum image height - * - * @param integer $minheight The minimum image height - * @param integer $maxheight The maximum image height - * @return Zend_Validate_File_ImageSize Provides a fluent interface - */ - public function setImageHeight($minheight, $maxheight) - { - $this->setImageMin($this->_minwidth, $minheight); - $this->setImageMax($this->_maxwidth, $maxheight); - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the imagesize of $value is at least min and - * not bigger than max - * - * @param string $value Real file to check for image size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - if (@is_readable($value) === false) { - $this->_throw($file, self::NOT_READABLE); - return false; - } - - $size = @getimagesize($value); - $this->_setValue($file); - - if (empty($size) or ($size[0] === 0) or ($size[1] === 0)) { - $this->_throw($file, self::NOT_DETECTED); - return false; - } - - if ($size[0] < $this->_minwidth) { - $this->_throw($file, self::WIDTH_TOO_SMALL); - } - - if ($size[1] < $this->_minheight) { - $this->_throw($file, self::HEIGHT_TOO_SMALL); - } - - if (($this->_maxwidth !== null) and ($this->_maxwidth < $size[0])) { - $this->_throw($file, self::WIDTH_TOO_BIG); - } - - if (($this->_maxheight !== null) and ($this->_maxheight < $size[1])) { - $this->_throw($file, self::HEIGHT_TOO_BIG); - } - - if (count($this->_messages) > 0) { - return false; - } else { - return true; - } - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/MimeType.php b/phpQuery/phpQuery/Zend/Validate/File/MimeType.php deleted file mode 100644 index 8f7e9cd..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/MimeType.php +++ /dev/null @@ -1,200 +0,0 @@ - "The file '%value%' has a false mimetype", - self::NOT_DETECTED => "The mimetype of file '%value%' has not been detected", - self::NOT_READABLE => "The file '%value%' can not be read" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'mimetype' => '_mimetype' - ); - - /** - * Mimetypes - * - * If null, there is no mimetype - * - * @var string|null - */ - protected $_mimetype; - - /** - * Sets validator options - * - * Mimetype to accept - * - * @param string|array $mimetype MimeType - * @return void - */ - public function __construct($mimetype) - { - $this->setMimeType($mimetype); - } - - /** - * Returns the set mimetypes - * - * @param boolean $asArray Returns the values as array, when false an concated string is returned - * @return integer - */ - public function getMimeType($asArray = false) - { - $asArray = (bool) $asArray; - $mimetype = (string) $this->_mimetype; - if ($asArray) { - $mimetype = explode(',', $mimetype); - } - - return $mimetype; - } - - /** - * Sets the mimetypes - * - * @param string|array $mimetype The mimetypes to validate - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function setMimeType($mimetype) - { - $this->_mimetype = null; - $this->addMimeType($mimetype); - return $this; - } - - /** - * Adds the mimetypes - * - * @param string|array $mimetype The mimetypes to add for validation - * @return Zend_Validate_File_Extension Provides a fluent interface - */ - public function addMimeType($mimetype) - { - $mimetypes = $this->getMimeType(true); - if (is_string($mimetype)) { - $mimetype = explode(',', $mimetype); - } - - foreach ($mimetype as $content) { - if (empty($content) || !is_string($content)) { - continue; - } - $mimetypes[] = trim($content); - } - $mimetypes = array_unique($mimetypes); - - // Sanity check to ensure no empty values - foreach ($mimetypes as $key => $mt) { - if (empty($mt)) { - unset($mimetypes[$key]); - } - } - - $this->_mimetype = implode(',', $mimetypes); - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if the mimetype of the file matches the given ones. Also parts - * of mimetypes can be checked. If you give for example "image" all image - * mime types will be accepted like "image/gif", "image/jpeg" and so on. - * - * @param string $value Real file to check for mimetype - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - if (!@is_readable($value)) { - $this->_throw($file, self::NOT_READABLE); - return false; - } - - if ($file !== null) { - $info['type'] = $file['type']; - } else { - $this->_throw($file, self::NOT_DETECTED); - return false; - } - - $mimetype = $this->getMimeType(true); - if (in_array($info['type'], $mimetype)) { - return true; - } - - foreach($mimetype as $mime) { - $types = explode('/', $info['type']); - if (in_array($mime, $types)) { - return true; - } - } - - $this->_throw($file, self::FALSE_TYPE); - return false; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/NotExists.php b/phpQuery/phpQuery/Zend/Validate/File/NotExists.php deleted file mode 100644 index 2b812fc..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/NotExists.php +++ /dev/null @@ -1,86 +0,0 @@ - "The file '%value%' does exist" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file does not exist in the set destinations - * - * @param string $value Real file to check for - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - $directories = $this->getDirectory(true); - if (($file !== null) and (!empty($file['destination']))) { - $directories[] = $file['destination']; - } else if (!isset($file['name'])) { - $file['name'] = $value; - } - - foreach ($directories as $directory) { - if (empty($directory)) { - continue; - } - - $check = true; - if (file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) { - $this->_throw($file, self::DOES_EXIST); - return false; - } - } - - if (!isset($check)) { - $this->_throw($file, self::DOES_EXIST); - return false; - } - - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/Size.php b/phpQuery/phpQuery/Zend/Validate/File/Size.php deleted file mode 100644 index 2adaeb3..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/Size.php +++ /dev/null @@ -1,308 +0,0 @@ - "The file '%value%' is bigger than allowed", - self::TOO_SMALL => "The file '%value%' is smaller than allowed", - self::NOT_FOUND => "The file '%value%' could not be found" - ); - - /** - * @var array Error message template variables - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum filesize - * @var integer - */ - protected $_min; - - /** - * Maximum filesize - * - * If null, there is no maximum filesize - * - * @var integer|null - */ - protected $_max; - - /** - * Sets validator options - * - * Min limits the filesize, when used with max=null it is the maximum filesize - * It also accepts an array with the keys 'min' and 'max' - * - * @param integer|array $min Minimum filesize - * @param integer $max Maximum filesize - * @return void - */ - public function __construct($min, $max = null) - { - if (is_array($min)) { - $count = count($min); - if (array_key_exists('min', $min)) { - if (array_key_exists('max', $min)) { - $max = $min['max']; - } - - $min = $min['min']; - } elseif ($count === 2) { - $minValue = array_shift($min); - $max = array_shift($min); - $min = $minValue; - } elseif($count === 1) { - $min = array_shift($min); - $max = null; - } else { - $min = 0; - $max = null; - } - } - - if (empty($max)) { - $max = $min; - $min = 0; - } - - $this->setMin($min); - $this->setMax($max); - } - - /** - * Returns the minimum filesize - * - * @param boolean $unit Return the value with unit, when false the plan bytes will be returned - * @return integer - */ - public function getMin($unit = true) - { - $unit = (bool) $unit; - $min = $this->_min; - if ($unit) { - $min = $this->_toByteString($min); - } - return $min; - } - - /** - * Sets the minimum filesize - * - * @param integer $min The minimum filesize - * @return Zend_Validate_File_Size Provides a fluent interface - * @throws Zend_Validate_Exception When min is greater than max - */ - public function setMin($min) - { - $min = (integer) $this->_fromByteString($min); - if (($this->_max !== null) && ($min > $this->_max)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >" - . " {$this->_max}"); - } - - $this->_min = max(0, $min); - return $this; - } - - /** - * Returns the maximum filesize - * - * @param boolean $unit Return the value with unit, when false the plan bytes will be returned - * @return integer|null - */ - public function getMax($unit = true) - { - $unit = (bool) $unit; - $max = $this->_max; - if ($unit) { - $max = $this->_toByteString($max); - } - return $max; - } - - /** - * Sets the maximum filesize - * - * @param integer|null $max The maximum filesize - * @return Zend_Validate_StringLength Provides a fluent interface - * @throws Zend_Validate_Exception When max is smaller than min - */ - public function setMax($max) - { - $max = (integer) $this->_fromByteString($max); - if (($this->_min !== null) && ($max < $this->_min)) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but " - . "$max < {$this->_min}"); - } else { - $this->_max = $max; - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the filesize of $value is at least min and - * not bigger than max (when max is not null). - * - * @param string $value Real file to check for size - * @param array $file File data from Zend_File_Transfer - * @return boolean - */ - public function isValid($value, $file = null) - { - // Is file readable ? - if (!@is_readable($value)) { - $this->_throw($file, self::NOT_FOUND); - return false; - } - - // limited to 4GB files - $size = sprintf("%u",@filesize($value)); - $this->_setValue($size); - - // Check to see if it's smaller than min size - if (($this->_min !== null) && ($size < $this->_min)) { - $this->_throw($file, self::TOO_SMALL); - } - - // Check to see if it's larger than max size - if (($this->_max !== null) && ($this->_max < $size)) { - $this->_throw($file, self::TOO_BIG); - } - - if (count($this->_messages) > 0) { - return false; - } else { - return true; - } - } - - /** - * Returns the formatted size - * - * @param integer $size - * @return string - */ - protected function _toByteString($size) - { - $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); - for ($i=0; $size > 1024 && $i < 9; $i++) { - $size /= 1024; - } - return round($size, 2).$sizes[$i]; - } - - /** - * Returns the unformatted size - * - * @param string $size - * @return integer - */ - protected function _fromByteString($size) - { - if (is_numeric($size)) { - return (integer) $size; - } - - $type = trim(substr($size, -2)); - $value = substr($size, 0, -2); - switch (strtoupper($type)) { - case 'YB': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'ZB': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'EB': - $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'PB': - $value *= (1024 * 1024 * 1024 * 1024 * 1024); - break; - case 'TB': - $value *= (1024 * 1024 * 1024 * 1024); - break; - case 'GB': - $value *= (1024 * 1024 * 1024); - break; - case 'MB': - $value *= (1024 * 1024); - break; - case 'KB': - $value *= 1024; - break; - default: - break; - } - - return $value; - } - - /** - * Throws an error of the given type - * - * @param string $file - * @param string $errorType - * @return false - */ - protected function _throw($file, $errorType) - { - if ($file !== null) { - $this->_value = $file['name']; - } - - $this->_error($errorType); - return false; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/File/Upload.php b/phpQuery/phpQuery/Zend/Validate/File/Upload.php deleted file mode 100644 index a56cf14..0000000 --- a/phpQuery/phpQuery/Zend/Validate/File/Upload.php +++ /dev/null @@ -1,216 +0,0 @@ - "The file '%value%' exceeds the defined ini size", - self::FORM_SIZE => "The file '%value%' exceeds the defined form size", - self::PARTIAL => "The file '%value%' was only partially uploaded", - self::NO_FILE => "The file '%value%' was not uploaded", - self::NO_TMP_DIR => "No temporary directory was found for the file '%value%'", - self::CANT_WRITE => "The file '%value%' can't be written", - self::EXTENSION => "The extension returned an error while uploading the file '%value%'", - self::ATTACK => "The file '%value%' was illegal uploaded, possible attack", - self::FILE_NOT_FOUND => "The file '%value%' was not found", - self::UNKNOWN => "Unknown error while uploading the file '%value%'" - ); - - /** - * Internal array of files - * @var array - */ - protected $_files = array(); - - /** - * Sets validator options - * - * The array $files must be given in syntax of Zend_File_Transfer to be checked - * If no files are given the $_FILES array will be used automatically. - * NOTE: This validator will only work with HTTP POST uploads! - * - * @param array $files Array of files in syntax of Zend_File_Transfer - * @return void - */ - public function __construct($files = array()) - { - $this->setFiles($files); - } - - /** - * Returns the array of set files - * - * @param string $files (Optional) The file to return in detail - * @return array - * @throws Zend_Validate_Exception If file is not found - */ - public function getFiles($file = null) - { - if ($file !== null) { - $return = array(); - foreach ($this->_files as $name => $content) { - if ($name === $file) { - $return[$file] = $this->_files[$name]; - } - - if ($content['name'] === $file) { - $return[$name] = $this->_files[$name]; - } - } - - if (count($return) === 0) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The file '$file' was not found"); - } - - return $return; - } - - return $this->_files; - } - - /** - * Sets the minimum filesize - * - * @param array $files The files to check in syntax of Zend_File_Transfer - * @return Zend_Validate_File_Upload Provides a fluent interface - */ - public function setFiles($files = array()) - { - if (count($files) === 0) { - $this->_files = $_FILES; - } else { - $this->_files = $files; - } - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the file was uploaded without errors - * - * @param string $value Single file to check for upload errors, when giving null the $_FILES array - * from initialization will be used - * @return boolean - */ - public function isValid($value) - { - if (array_key_exists($value, $this->_files)) { - $files[$value] = $this->_files[$value]; - } else { - foreach ($this->_files as $file => $content) { - if ($content['name'] === $value) { - $files[$file] = $this->_files[$file]; - } - - if ($content['tmp_name'] === $value) { - $files[$file] = $this->_files[$file]; - } - } - } - - if (empty($files)) { - $this->_error(self::FILE_NOT_FOUND); - return false; - } - - foreach ($files as $file => $content) { - $this->_value = $file; - switch($content['error']) { - case 0: - if (!is_uploaded_file($content['tmp_name'])) { - $this->_error(self::ATTACK); - } - break; - - case 1: - $this->_error(self::INI_SIZE); - break; - - case 2: - $this->_error(self::FORM_SIZE); - break; - - case 3: - $this->_error(self::PARTIAL); - break; - - case 4: - $this->_error(self::NO_FILE); - break; - - case 6: - $this->_error(self::NO_TMP_DIR); - break; - - case 7: - $this->_error(self::CANT_WRITE); - break; - - case 8: - $this->_error(self::EXTENSION); - break; - - default: - $this->_error(self::UNKNOWN); - break; - } - } - - if (count($this->_messages) > 0) { - return false; - } else { - return true; - } - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/Float.php b/phpQuery/phpQuery/Zend/Validate/Float.php deleted file mode 100644 index 0405161..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Float.php +++ /dev/null @@ -1,75 +0,0 @@ - "'%value%' does not appear to be a float" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a floating-point value - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - $locale = localeconv(); - - $valueFiltered = str_replace($locale['thousands_sep'], '', $valueString); - $valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered); - - if (strval(floatval($valueFiltered)) != $valueFiltered) { - $this->_error(); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/GreaterThan.php b/phpQuery/phpQuery/Zend/Validate/GreaterThan.php deleted file mode 100644 index 35e658c..0000000 --- a/phpQuery/phpQuery/Zend/Validate/GreaterThan.php +++ /dev/null @@ -1,114 +0,0 @@ - "'%value%' is not greater than '%min%'" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min' - ); - - /** - * Minimum value - * - * @var mixed - */ - protected $_min; - - /** - * Sets validator options - * - * @param mixed $min - * @return void - */ - public function __construct($min) - { - $this->setMin($min); - } - - /** - * Returns the min option - * - * @return mixed - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param mixed $min - * @return Zend_Validate_GreaterThan Provides a fluent interface - */ - public function setMin($min) - { - $this->_min = $min; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is greater than min option - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - - if ($this->_min >= $value) { - $this->_error(); - return false; - } - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Hex.php b/phpQuery/phpQuery/Zend/Validate/Hex.php deleted file mode 100644 index 9512eda..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Hex.php +++ /dev/null @@ -1,74 +0,0 @@ - "'%value%' has not only hexadecimal digit characters" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value contains only hexadecimal digit characters - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if (!ctype_xdigit($valueString)) { - $this->_error(); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Hostname.php b/phpQuery/phpQuery/Zend/Validate/Hostname.php deleted file mode 100644 index ea79c24..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Hostname.php +++ /dev/null @@ -1,444 +0,0 @@ - "'%value%' appears to be an IP address, but IP addresses are not allowed", - self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list", - self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash (-) in an invalid position", - self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'", - self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part", - self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname", - self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name", - self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'tld' => '_tld' - ); - - /** - * Allows Internet domain names (e.g., example.com) - */ - const ALLOW_DNS = 1; - - /** - * Allows IP addresses - */ - const ALLOW_IP = 2; - - /** - * Allows local network names (e.g., localhost, www.localdomain) - */ - const ALLOW_LOCAL = 4; - - /** - * Allows all types of hostnames - */ - const ALLOW_ALL = 7; - - /** - * Whether IDN domains are validated - * - * @var boolean - */ - private $_validateIdn = true; - - /** - * Whether TLDs are validated against a known list - * - * @var boolean - */ - private $_validateTld = true; - - /** - * Bit field of ALLOW constants; determines which types of hostnames are allowed - * - * @var integer - */ - protected $_allow; - - /** - * Bit field of CHECK constants; determines what additional hostname checks to make - * - * @var unknown_type - */ - // protected $_check; - - /** - * Array of valid top-level-domains - * - * @var array - * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain - */ - protected $_validTlds = array( - 'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', - 'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb', - 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo', - 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd', - 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop', - 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do', - 'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj', - 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh', - 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', - 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', - 'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', - 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', - 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', - 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm', - 'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv', - 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng', - 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe', - 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt', - 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', - 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', - 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj', - 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw', - 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've', - 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm', - 'zw' - ); - - /** - * @var string - */ - protected $_tld; - - /** - * Sets validator options - * - * @param integer $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS) - * @param boolean $validateIdn OPTIONAL Set whether IDN domains are validated (default true) - * @param boolean $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true) - * @param Zend_Validate_Ip $ipValidator OPTIONAL - * @return void - * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs - */ - public function __construct($allow = self::ALLOW_DNS, $validateIdn = true, $validateTld = true, Zend_Validate_Ip $ipValidator = null) - { - // Set allow options - $this->setAllow($allow); - - // Set validation options - $this->_validateIdn = $validateIdn; - $this->_validateTld = $validateTld; - - $this->setIpValidator($ipValidator); - } - - /** - * @param Zend_Validate_Ip $ipValidator OPTIONAL - * @return void; - */ - public function setIpValidator(Zend_Validate_Ip $ipValidator = null) - { - if ($ipValidator === null) { - $ipValidator = new Zend_Validate_Ip(); - } - $this->_ipValidator = $ipValidator; - } - - /** - * Returns the allow option - * - * @return integer - */ - public function getAllow() - { - return $this->_allow; - } - - /** - * Sets the allow option - * - * @param integer $allow - * @return Zend_Validate_Hostname Provides a fluent interface - */ - public function setAllow($allow) - { - $this->_allow = $allow; - return $this; - } - - /** - * Set whether IDN domains are validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them - */ - public function setValidateIdn ($allowed) - { - $this->_validateIdn = (bool) $allowed; - } - - /** - * Set whether the TLD element of a hostname is validated - * - * This only applies when DNS hostnames are validated - * - * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them - */ - public function setValidateTld ($allowed) - { - $this->_validateTld = (bool) $allowed; - } - - /** - * Sets the check option - * - * @param integer $check - * @return Zend_Validate_Hostname Provides a fluent interface - */ - /* - public function setCheck($check) - { - $this->_check = $check; - return $this; - } - */ - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the $value is a valid hostname with respect to the current allow option - * - * @param string $value - * @throws Zend_Validate_Exception if a fatal error occurs for validation process - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - // Check input against IP address schema - if ($this->_ipValidator->setTranslator($this->getTranslator())->isValid($valueString)) { - if (!($this->_allow & self::ALLOW_IP)) { - $this->_error(self::IP_ADDRESS_NOT_ALLOWED); - return false; - } else{ - return true; - } - } - - // Check input against DNS hostname schema - $domainParts = explode('.', $valueString); - if ((count($domainParts) > 1) && (strlen($valueString) >= 4) && (strlen($valueString) <= 254)) { - $status = false; - - do { - // First check TLD - if (preg_match('/([a-z]{2,10})$/i', end($domainParts), $matches)) { - - reset($domainParts); - - // Hostname characters are: *(label dot)(label dot label); max 254 chars - // label: id-prefix [*ldh{61} id-prefix]; max 63 chars - // id-prefix: alpha / digit - // ldh: alpha / digit / dash - - // Match TLD against known list - $this->_tld = strtolower($matches[1]); - if ($this->_validateTld) { - if (!in_array($this->_tld, $this->_validTlds)) { - $this->_error(self::UNKNOWN_TLD); - $status = false; - break; - } - } - - /** - * Match against IDN hostnames - * @see Zend_Validate_Hostname_Interface - */ - $labelChars = 'a-z0-9'; - $utf8 = false; - $classFile = 'Zend/Validate/Hostname/' . ucfirst($this->_tld) . '.php'; - if ($this->_validateIdn) { - if (Zend_Loader::isReadable($classFile)) { - - // Load additional characters - $className = 'Zend_Validate_Hostname_' . ucfirst($this->_tld); - Zend_Loader::loadClass($className); - $labelChars .= call_user_func(array($className, 'getCharacters')); - $utf8 = true; - } - } - - // Keep label regex short to avoid issues with long patterns when matching IDN hostnames - $regexLabel = '/^[' . $labelChars . '\x2d]{1,63}$/i'; - if ($utf8) { - $regexLabel .= 'u'; - } - - // Check each hostname part - $valid = true; - foreach ($domainParts as $domainPart) { - - // Check dash (-) does not start, end or appear in 3rd and 4th positions - if (strpos($domainPart, '-') === 0 || - (strlen($domainPart) > 2 && strpos($domainPart, '-', 2) == 2 && strpos($domainPart, '-', 3) == 3) || - strrpos($domainPart, '-') === strlen($domainPart) - 1) { - - $this->_error(self::INVALID_DASH); - $status = false; - break 2; - } - - // Check each domain part - $status = @preg_match($regexLabel, $domainPart); - if ($status === false) { - /** - * Regex error - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Internal error: DNS validation failed'); - } elseif ($status === 0) { - $valid = false; - } - } - - // If all labels didn't match, the hostname is invalid - if (!$valid) { - $this->_error(self::INVALID_HOSTNAME_SCHEMA); - $status = false; - } - - } else { - // Hostname not long enough - $this->_error(self::UNDECIPHERABLE_TLD); - $status = false; - } - } while (false); - - // If the input passes as an Internet domain name, and domain names are allowed, then the hostname - // passes validation - if ($status && ($this->_allow & self::ALLOW_DNS)) { - return true; - } - } else { - $this->_error(self::INVALID_HOSTNAME); - } - - // Check input against local network name schema; last chance to pass validation - $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/'; - $status = @preg_match($regexLocal, $valueString); - if (false === $status) { - /** - * Regex error - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception('Internal error: local network name validation failed'); - } - - // If the input passes as a local network name, and local network names are allowed, then the - // hostname passes validation - $allowLocal = $this->_allow & self::ALLOW_LOCAL; - if ($status && $allowLocal) { - return true; - } - - // If the input does not pass as a local network name, add a message - if (!$status) { - $this->_error(self::INVALID_LOCAL_NAME); - } - - // If local network names are not allowed, add a message - if ($status && !$allowLocal) { - $this->_error(self::LOCAL_NAME_NOT_ALLOWED); - } - - return false; - } - - /** - * Throws an exception if a regex for $type does not exist - * - * @param string $type - * @throws Zend_Validate_Exception - * @return Zend_Validate_Hostname Provides a fluent interface - */ - /* - protected function _checkRegexType($type) - { - if (!isset($this->_regex[$type])) { - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("'$type' must be one of ('" . implode(', ', array_keys($this->_regex)) - . "')"); - } - return $this; - } - */ - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Hostname/At.php b/phpQuery/phpQuery/Zend/Validate/Hostname/At.php deleted file mode 100644 index fff6bf2..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Hostname/At.php +++ /dev/null @@ -1,50 +0,0 @@ - 'Tokens do not match', - self::MISSING_TOKEN => 'No token was provided to match against', - ); - - /** - * Original token against which to validate - * @var string - */ - protected $_token; - - /** - * Sets validator options - * - * @param string $token - * @return void - */ - public function __construct($token = null) - { - if (null !== $token) { - $this->setToken($token); - } - } - - /** - * Set token against which to compare - * - * @param string $token - * @return Zend_Validate_Identical - */ - public function setToken($token) - { - $this->_token = (string) $token; - return $this; - } - - /** - * Retrieve token - * - * @return string - */ - public function getToken() - { - return $this->_token; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if a token has been set and the provided value - * matches that token. - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - $token = $this->getToken(); - - if (empty($token)) { - $this->_error(self::MISSING_TOKEN); - return false; - } - - if ($value !== $token) { - $this->_error(self::NOT_SAME); - return false; - } - - return true; - } -} diff --git a/phpQuery/phpQuery/Zend/Validate/InArray.php b/phpQuery/phpQuery/Zend/Validate/InArray.php deleted file mode 100644 index 1c7725a..0000000 --- a/phpQuery/phpQuery/Zend/Validate/InArray.php +++ /dev/null @@ -1,138 +0,0 @@ - "'%value%' was not found in the haystack" - ); - - /** - * Haystack of possible values - * - * @var array - */ - protected $_haystack; - - /** - * Whether a strict in_array() invocation is used - * - * @var boolean - */ - protected $_strict; - - /** - * Sets validator options - * - * @param array $haystack - * @param boolean $strict - * @return void - */ - public function __construct(array $haystack, $strict = false) - { - $this->setHaystack($haystack) - ->setStrict($strict); - } - - /** - * Returns the haystack option - * - * @return mixed - */ - public function getHaystack() - { - return $this->_haystack; - } - - /** - * Sets the haystack option - * - * @param mixed $haystack - * @return Zend_Validate_InArray Provides a fluent interface - */ - public function setHaystack(array $haystack) - { - $this->_haystack = $haystack; - return $this; - } - - /** - * Returns the strict option - * - * @return boolean - */ - public function getStrict() - { - return $this->_strict; - } - - /** - * Sets the strict option - * - * @param boolean $strict - * @return Zend_Validate_InArray Provides a fluent interface - */ - public function setStrict($strict) - { - $this->_strict = $strict; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is contained in the haystack option. If the strict - * option is true, then the type of $value is also checked. - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - if (!in_array($value, $this->_haystack, $this->_strict)) { - $this->_error(); - return false; - } - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Int.php b/phpQuery/phpQuery/Zend/Validate/Int.php deleted file mode 100644 index 0bde2cb..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Int.php +++ /dev/null @@ -1,75 +0,0 @@ - "'%value%' does not appear to be an integer" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid integer - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - $locale = localeconv(); - - $valueFiltered = str_replace($locale['decimal_point'], '.', $valueString); - $valueFiltered = str_replace($locale['thousands_sep'], '', $valueFiltered); - - if (strval(intval($valueFiltered)) != $valueFiltered) { - $this->_error(); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Interface.php b/phpQuery/phpQuery/Zend/Validate/Interface.php deleted file mode 100644 index 4fcd525..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Interface.php +++ /dev/null @@ -1,71 +0,0 @@ - "'%value%' does not appear to be a valid IP address" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is a valid IP address - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - if (ip2long($valueString) === false) { - $this->_error(); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/LessThan.php b/phpQuery/phpQuery/Zend/Validate/LessThan.php deleted file mode 100644 index 9f7b72c..0000000 --- a/phpQuery/phpQuery/Zend/Validate/LessThan.php +++ /dev/null @@ -1,113 +0,0 @@ - "'%value%' is not less than '%max%'" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'max' => '_max' - ); - - /** - * Maximum value - * - * @var mixed - */ - protected $_max; - - /** - * Sets validator options - * - * @param mixed $max - * @return void - */ - public function __construct($max) - { - $this->setMax($max); - } - - /** - * Returns the max option - * - * @return mixed - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param mixed $max - * @return Zend_Validate_LessThan Provides a fluent interface - */ - public function setMax($max) - { - $this->_max = $max; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is less than max option - * - * @param mixed $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue($value); - if ($this->_max <= $value) { - $this->_error(); - return false; - } - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/NotEmpty.php b/phpQuery/phpQuery/Zend/Validate/NotEmpty.php deleted file mode 100644 index dcf3662..0000000 --- a/phpQuery/phpQuery/Zend/Validate/NotEmpty.php +++ /dev/null @@ -1,74 +0,0 @@ - "Value is empty, but a non-empty value is required" - ); - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value is not an empty value. - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $this->_setValue((string) $value); - - if (is_string($value) - && (('' === $value) - || preg_match('/^\s+$/s', $value)) - ) { - $this->_error(); - return false; - } elseif (!is_string($value) && empty($value)) { - $this->_error(); - return false; - } - - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/Regex.php b/phpQuery/phpQuery/Zend/Validate/Regex.php deleted file mode 100644 index 1566f07..0000000 --- a/phpQuery/phpQuery/Zend/Validate/Regex.php +++ /dev/null @@ -1,125 +0,0 @@ - "'%value%' does not match against pattern '%pattern%'" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'pattern' => '_pattern' - ); - - /** - * Regular expression pattern - * - * @var string - */ - protected $_pattern; - - /** - * Sets validator options - * - * @param string $pattern - * @return void - */ - public function __construct($pattern) - { - $this->setPattern($pattern); - } - - /** - * Returns the pattern option - * - * @return string - */ - public function getPattern() - { - return $this->_pattern; - } - - /** - * Sets the pattern option - * - * @param string $pattern - * @return Zend_Validate_Regex Provides a fluent interface - */ - public function setPattern($pattern) - { - $this->_pattern = (string) $pattern; - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if $value matches against the pattern option - * - * @param string $value - * @throws Zend_Validate_Exception if there is a fatal error in pattern matching - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - - $this->_setValue($valueString); - - $status = @preg_match($this->_pattern, $valueString); - if (false === $status) { - /** - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("Internal error matching pattern '$this->_pattern' against value '$valueString'"); - } - if (!$status) { - $this->_error(); - return false; - } - return true; - } - -} diff --git a/phpQuery/phpQuery/Zend/Validate/StringLength.php b/phpQuery/phpQuery/Zend/Validate/StringLength.php deleted file mode 100644 index c43f2ca..0000000 --- a/phpQuery/phpQuery/Zend/Validate/StringLength.php +++ /dev/null @@ -1,180 +0,0 @@ - "'%value%' is less than %min% characters long", - self::TOO_LONG => "'%value%' is greater than %max% characters long" - ); - - /** - * @var array - */ - protected $_messageVariables = array( - 'min' => '_min', - 'max' => '_max' - ); - - /** - * Minimum length - * - * @var integer - */ - protected $_min; - - /** - * Maximum length - * - * If null, there is no maximum length - * - * @var integer|null - */ - protected $_max; - - /** - * Sets validator options - * - * @param integer $min - * @param integer $max - * @return void - */ - public function __construct($min = 0, $max = null) - { - $this->setMin($min); - $this->setMax($max); - } - - /** - * Returns the min option - * - * @return integer - */ - public function getMin() - { - return $this->_min; - } - - /** - * Sets the min option - * - * @param integer $min - * @throws Zend_Validate_Exception - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMin($min) - { - if (null !== $this->_max && $min > $this->_max) { - /** - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum length, but $min >" - . " $this->_max"); - } - $this->_min = max(0, (integer) $min); - return $this; - } - - /** - * Returns the max option - * - * @return integer|null - */ - public function getMax() - { - return $this->_max; - } - - /** - * Sets the max option - * - * @param integer|null $max - * @throws Zend_Validate_Exception - * @return Zend_Validate_StringLength Provides a fluent interface - */ - public function setMax($max) - { - if (null === $max) { - $this->_max = null; - } else if ($max < $this->_min) { - /** - * @see Zend_Validate_Exception - */ - require_once 'Zend/Validate/Exception.php'; - throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum length, but " - . "$max < $this->_min"); - } else { - $this->_max = (integer) $max; - } - - return $this; - } - - /** - * Defined by Zend_Validate_Interface - * - * Returns true if and only if the string length of $value is at least the min option and - * no greater than the max option (when the max option is not null). - * - * @param string $value - * @return boolean - */ - public function isValid($value) - { - $valueString = (string) $value; - $this->_setValue($valueString); - $length = iconv_strlen($valueString); - if ($length < $this->_min) { - $this->_error(self::TOO_SHORT); - } - if (null !== $this->_max && $this->_max < $length) { - $this->_error(self::TOO_LONG); - } - if (count($this->_messages)) { - return false; - } else { - return true; - } - } - -} From bb912f645e3a4d88970eb2a1865b61304ad49156 Mon Sep 17 00:00:00 2001 From: Rafal Lindemann Date: Fri, 14 Dec 2012 09:12:02 +0100 Subject: [PATCH 03/59] composer.json --- composer.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..3de931b --- /dev/null +++ b/composer.json @@ -0,0 +1,16 @@ +{ + "name": "stamina/phpquery", + "type": "library", + "description": "phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library", + "keywords": [], + "homepage": "http://code.google.com/p/phpquery/", + "license": "MIT", + "authors": [ + { + "name": "Tobiasz Cudnik" + } + ], + "autoload": { + "classmap": ["phpQuery/"] + } +} From b2aa01967540c940f9175714cc1357a72d0f6abf Mon Sep 17 00:00:00 2001 From: Ralph Tice Date: Thu, 24 Jan 2013 16:51:19 -0600 Subject: [PATCH 04/59] added WebBrowser->browserDownload for retrieving response body directly, for example to retrieve a generated excel file --- phpQuery/phpQuery/plugins/WebBrowser.php | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/phpQuery/phpQuery/plugins/WebBrowser.php b/phpQuery/phpQuery/plugins/WebBrowser.php index 6688d3f..e5e83d0 100644 --- a/phpQuery/phpQuery/plugins/WebBrowser.php +++ b/phpQuery/phpQuery/plugins/WebBrowser.php @@ -84,6 +84,26 @@ public static function location($self, $url = null) { } return $return; } + + + public static function download($self, $url = null) { + $xhr = isset($self->document->xhr) + ? $self->document->xhr + : null; + $xhr = phpQuery::ajax(array( + 'url' => $url, + ), $xhr); + $return = false; + if ($xhr->getLastResponse()->isSuccessful()) { + $return = phpQueryPlugin_WebBrowser::browserDownload($xhr); + if (isset($self->document->WebBrowserCallback)) + phpQuery::callbackRun( + $self->document->WebBrowserCallback, + array($return) + ); + } + return $return; + } } class phpQueryPlugin_WebBrowser { /** @@ -246,6 +266,17 @@ public static function browserReceive($xhr) { } else return $pq; } + + /** + * @param Zend_Http_Client $xhr + */ + public static function browserDownload($xhr) { + phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true)); + // TODO handle meta redirects + $body = $xhr->getLastResponse()->getBody(); + + return $body; + } /** * * @param $e From ca72bd3cddd011ecd9f3a4fb8b23d141ab925825 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Feb 2013 15:45:24 +0000 Subject: [PATCH 05/59] Add an attrs() method. Returns attributes for all matched elements, not just the first one. E.g. the href attribute of all matching links. --- phpQuery/phpQuery/phpQueryObject.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index 9693cb9..99f1ac0 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -2631,6 +2631,21 @@ public function attr($attr = null, $value = null) { return is_null($value) ? '' : $this; } + + /** + * @return The same attribute of each matching element, like + * attr() but returns an array with one entry per matched element. + * Read only. + */ + public function attrs($attr = null) { + $results = array(); + foreach($this->stack(1) as $node) { + $results[] = $node->hasAttribute($attr) + ? $node->getAttribute($attr) + : null; + } + return $results; + } /** * @access private */ From 4e2e30fd593eec688205c3901db2aadb0990dbac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 19 Mar 2013 14:44:18 +0000 Subject: [PATCH 06/59] Add a .texts() method like .attrs(). --- phpQuery/phpQuery/phpQueryObject.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index 99f1ac0..f0dfa1d 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -2264,6 +2264,20 @@ public function text($text = null, $callback1 = null, $callback2 = null, $callba } return $return; } + + /** + * @return The text content of each matching element, like + * text() but returns an array with one entry per matched element. + * Read only. + */ + public function texts($attr = null) { + $results = array(); + foreach($this->elements as $node) { + $results[] = $node->textContent; + } + return $results; + } + /** * Enter description here... * @@ -2646,6 +2660,7 @@ public function attrs($attr = null) { } return $results; } + /** * @access private */ From 6cb8afcfe8cd4ce45f2f8c27d561383037c27a3a Mon Sep 17 00:00:00 2001 From: Didier Belot Date: Thu, 21 Mar 2013 13:39:33 +0100 Subject: [PATCH 07/59] initial package release, version bumped to 0.9.6 --- README | 0 README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ composer.json | 22 ++++++++++----- 3 files changed, 92 insertions(+), 7 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index e69de29..0000000 diff --git a/README.md b/README.md new file mode 100644 index 0000000..63b6870 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +## phpQuery, one more fork! + +My intent is to have it easily integrated in differents projects, so available on packagist. +I've gathered some fix and new features here and there, as will keep looking for new stuff on github about phpQuery + +### github repos i've integrated: + +* https://github.com/ralph-tice/phpquery (one commit: added WebBrowser->browserDownload) +* https://github.com/aptivate/phpquery (three commits) +* https://github.com/panrafal/phpquery (remove zend) + +### github repos i've looked at: + +* https://github.com/denis-isaev/phpquery +* https://github.com/fmorrow/pQuery--PHPQuery- (big project so far) +* https://github.com/r-sal/phpquery +* https://github.com/damien-list/phpquery-1 +* https://github.com/nev3rm0re/phpquery +* https://github.com/Aurielle/phpquery +* https://github.com/kevee/phpquery (include php-css-parser) +* https://github.com/lucassouza1/phpquery + +## Extracts from fmorrow README.md: + +### Whats phpQuery? +To quote the phpQuery *(orignally concieved and developed by Tobiasz Cudnik, available on Google Code and Github)* project documentation: + +>phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library. +> +>Library is written in PHP5 and provides additional Command Line Interface (CLI). + +### Example usage + +(copied from http://code.google.com/p/phpquery/wiki/Basics) + +Complete working example: + +```php +html(); + +// And output the result +echo '

Title:

'; +echo '

' . htmlentities( $title) . '

'; + +?> +``` + +==== + +Source for test.html: + +```html + + + + +Hello World! + + + + +``` + diff --git a/composer.json b/composer.json index 3de931b..2ea5d66 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,21 @@ { - "name": "stamina/phpquery", - "type": "library", - "description": "phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library", - "keywords": [], - "homepage": "http://code.google.com/p/phpquery/", - "license": "MIT", - "authors": [ + "name": "electrolinux/phpquery" + ,"type": "library" + ,"description": "phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library" + ,"version": "0.9.6" + ,"keywords": [] + ,"homepage": "http://code.google.com/p/phpquery/" + ,"license": "MIT" + ,"authors": [ { "name": "Tobiasz Cudnik" + ,"email": "tobiasz.cudnik@gmail.com" + ,"homepage": "https://github.com/TobiaszCudnik" + ,"role": "Developer" + } + ,{ + "name": "didier Belot" + ,"role": "Packager" } ], "autoload": { From 2f417c1e5d5a1062c2331d21bc4684af311347f3 Mon Sep 17 00:00:00 2001 From: lsowen Date: Sun, 6 Oct 2013 14:39:24 -0400 Subject: [PATCH 08/59] fix nth-child implementation The previous nth-child('an+b') implementation could only have a and b values that were single digit (eg 5n-7). Patterns like 13n+14 were not supported, and were interpreted as nth-child('13'). --- phpQuery/phpQuery/phpQueryObject.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index f0dfa1d..ece90b6 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -1052,18 +1052,20 @@ protected function pseudoClasses($class) { return null;'), new CallbackParam(), $param ); - else if (mb_strlen($param) > 1 && $param{1} == 'n') + else if (mb_strlen($param) > 1 && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1) // an+b $mapped = $this->map( create_function('$node, $param', '$prevs = pq($node)->prevAll()->size(); $index = 1+$prevs; - $b = mb_strlen($param) > 3 - ? $param{3} - : 0; - $a = $param{0}; - if ($b && $param{2} == "-") - $b = -$b; + + preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches); + $a = intval($matches[1]); + $b = intval($matches[3]); + if( $matches[2] === "-" ) { + $b = -$b; + } + if ($a > 0) { return ($index-$b)%$a == 0 ? $node From e60db4df9ed3c1ec19d35fdf2ca3b2751799c66d Mon Sep 17 00:00:00 2001 From: urmaul Date: Wed, 9 Jul 2014 17:16:55 +0300 Subject: [PATCH 09/59] syntax fix --- test-cases/document-types/document-utf8.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-cases/document-types/document-utf8.php b/test-cases/document-types/document-utf8.php index 35353c7..b6e2893 100644 --- a/test-cases/document-types/document-utf8.php +++ b/test-cases/document-types/document-utf8.php @@ -8,6 +8,6 @@ Hello World! ąśżźć - '>Attr test + '>Attr test From 84e2570191be0fa3078051eea82b88f5f2d1bc03 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Tue, 30 Dec 2014 16:37:08 +0300 Subject: [PATCH 10/59] Update README.md fmorrow's repo is no longer available --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 63b6870..f9c33f7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ I've gathered some fix and new features here and there, as will keep looking for ### github repos i've looked at: * https://github.com/denis-isaev/phpquery -* https://github.com/fmorrow/pQuery--PHPQuery- (big project so far) * https://github.com/r-sal/phpquery * https://github.com/damien-list/phpquery-1 * https://github.com/nev3rm0re/phpquery From 9304d8a0db27c605e06f3e847426037c4600d71e Mon Sep 17 00:00:00 2001 From: Haoran Date: Mon, 7 Dec 2015 10:06:53 +1100 Subject: [PATCH 11/59] Replace deprecated functions split() and join() with explode() and implode(). --- phpQuery/phpQuery/phpQueryObject.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index ece90b6..2308540 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -3101,7 +3101,7 @@ protected function getNodeXpath($oneNode = null, $namespace = null) { : "{$node->tagName}[{$i}]"; $node = $node->parentNode; } - $xpath = join('/', array_reverse($xpath)); + $xpath = implode('/', array_reverse($xpath)); $return[] = '/'.$xpath; } return $oneNode @@ -3123,7 +3123,7 @@ public function whois($oneNode = null) { .($node->getAttribute('id') ? '#'.$node->getAttribute('id'):'') .($node->getAttribute('class') - ? '.'.join('.', split(' ', $node->getAttribute('class'))):'') + ? '.'.implode('.', explode(' ', $node->getAttribute('class'))):'') .($node->getAttribute('name') ? '[name="'.$node->getAttribute('name').'"]':'') .($node->getAttribute('value') && strpos($node->getAttribute('value'), '<'.'?php') === false From c7380d73241fd8666b6425bacc79e2fe8d0f82d0 Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Sat, 2 Jan 2016 10:59:52 -0700 Subject: [PATCH 12/59] Converted google code wiki to markdown --- wiki/Ajax.md | 70 ++++++++++++++++++++++++++ wiki/Attributes.md | 33 ++++++++++++ wiki/Basics.md | 54 ++++++++++++++++++++ wiki/CSS.md | 1 + wiki/Callbacks.md | 91 ++++++++++++++++++++++++++++++++++ wiki/Chains.md | 1 + wiki/CommandLineInterface.md | 14 ++++++ wiki/Debugging.md | 16 ++++++ wiki/Dependencies.md | 14 ++++++ wiki/Events.md | 47 ++++++++++++++++++ wiki/LibrarySections.md | 1 + wiki/Manipulation.md | 45 +++++++++++++++++ wiki/Manual.md | 21 ++++++++ wiki/MultiDocumentSupport.md | 53 ++++++++++++++++++++ wiki/PHPSupport.md | 78 +++++++++++++++++++++++++++++ wiki/PluginsClientSidePorts.md | 7 +++ wiki/PluginsServerSide.md | 77 ++++++++++++++++++++++++++++ wiki/ReleasePackages.md | 11 ++++ wiki/ScriptsPlugin.md | 24 +++++++++ wiki/Selectors.md | 76 ++++++++++++++++++++++++++++ wiki/Traversing.md | 34 +++++++++++++ wiki/Utilities.md | 20 ++++++++ wiki/WebBrowser.md | 37 ++++++++++++++ wiki/jQueryDifferences.md | 1 + wiki/jQueryHelpers.md | 3 ++ wiki/jQueryPortingState.md | 29 +++++++++++ wiki/jQueryServer.md | 16 ++++++ wiki/jQueryServerSidePorts.md | 6 +++ wiki/test.md | 1 + 29 files changed, 881 insertions(+) create mode 100644 wiki/Ajax.md create mode 100644 wiki/Attributes.md create mode 100644 wiki/Basics.md create mode 100644 wiki/CSS.md create mode 100644 wiki/Callbacks.md create mode 100644 wiki/Chains.md create mode 100644 wiki/CommandLineInterface.md create mode 100644 wiki/Debugging.md create mode 100644 wiki/Dependencies.md create mode 100644 wiki/Events.md create mode 100644 wiki/LibrarySections.md create mode 100644 wiki/Manipulation.md create mode 100644 wiki/Manual.md create mode 100644 wiki/MultiDocumentSupport.md create mode 100644 wiki/PHPSupport.md create mode 100644 wiki/PluginsClientSidePorts.md create mode 100644 wiki/PluginsServerSide.md create mode 100644 wiki/ReleasePackages.md create mode 100644 wiki/ScriptsPlugin.md create mode 100644 wiki/Selectors.md create mode 100644 wiki/Traversing.md create mode 100644 wiki/Utilities.md create mode 100644 wiki/WebBrowser.md create mode 100644 wiki/jQueryDifferences.md create mode 100644 wiki/jQueryHelpers.md create mode 100644 wiki/jQueryPortingState.md create mode 100644 wiki/jQueryServer.md create mode 100644 wiki/jQueryServerSidePorts.md create mode 100644 wiki/test.md diff --git a/wiki/Ajax.md b/wiki/Ajax.md new file mode 100644 index 0000000..3da8e25 --- /dev/null +++ b/wiki/Ajax.md @@ -0,0 +1,70 @@ +## Example +``` +pq('#element')->load('http://somesite.com/page .inline-selector')->... +``` +# Table of Contents + * [Server Side Ajax](#Server_Side_Ajax.md) + * [Cross Domain Ajax](#Cross_Domain_Ajax.md) + * [Ajax Requests](#Ajax_Requests.md) + * [Ajax Events](#Ajax_Events.md) + * [Misc](#Misc.md) +## Server Side Ajax +Ajax, standing for _Asynchronous JavaScript and XML_ is combination of HTTP Client and XML parser which doesn't lock program's thread (doing request in asynchronous way). + +**phpQuery** also offers such functionality, making use of solid quality [Zend\_Http\_Client](http://framework.zend.com/manual/en/zend.http.html). Unfortunately requests aren't asynchronous, but nothing is impossible. For today, instead of [XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest) you always get Zend\_Http\_Client instance. API unification is [planned](http://code.google.com/p/phpquery/issues/detail?id=44). +## Cross Domain Ajax +For security reasons, by default **phpQuery** doesn't allow connections to hosts other than actual `$_SERVER['HTTP_HOST']`. Developer needs to grant rights to other hosts before making an [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. + +There are 2 methods for allowing other hosts + * phpQuery::**ajaxAllowURL**($url) + * phpQuery::**ajaxAllowHost**($host) + +``` +// connect to google.com +phpQuery::ajaxAllowHost('google.com'); +phpQuery::get('http://google.com/ig'); +// or using same string +$url = 'http://google.com/ig'; +phpQuery::ajaxAllowURL($url); +phpQuery::get($url); +``` +## Ajax Requests + * **[phpQuery::ajax](http://docs.jquery.com/Ajax/jQuery.ajax)**[($options)](http://docs.jquery.com/Ajax/jQuery.ajax) Load a remote page using an HTTP request. + * **[load](http://docs.jquery.com/Ajax/load)**[($url, $data, $callback)](http://docs.jquery.com/Ajax/load) Load HTML from a remote file and inject it into the DOM. + * **[phpQuery::get](http://docs.jquery.com/Ajax/jQuery.get)**[($url, $data, $callback)](http://docs.jquery.com/Ajax/jQuery.get) Load a remote page using an HTTP GET request. + * **[phpQuery::getJSON](http://docs.jquery.com/Ajax/jQuery.getJSON)**[($url, $data, $callback)](http://docs.jquery.com/Ajax/jQuery.getJSON) Load JSON data using an HTTP GET request. + * **[phpQuery::getScript](http://docs.jquery.com/Ajax/jQuery.getScript)**[($url, $callback)](http://docs.jquery.com/Ajax/jQuery.getScript) Loads, and executes, a local JavaScript file using an HTTP GET request. + * **[phpQuery::post](http://docs.jquery.com/Ajax/jQuery.post)**[($url, $data, $callback, $type)](http://docs.jquery.com/Ajax/jQuery.post) Load a remote page using an HTTP POST request. +## Ajax Events + * **[ajaxComplete](http://docs.jquery.com/Ajax/ajaxComplete)**[($callback)](http://docs.jquery.com/Ajax/ajaxComplete) Attach a function to be executed whenever an AJAX request completes. This is an Ajax Event. + * **[ajaxError](http://docs.jquery.com/Ajax/ajaxError)**[($callback)](http://docs.jquery.com/Ajax/ajaxError) Attach a function to be executed whenever an AJAX request fails. This is an Ajax Event. + * **[ajaxSend](http://docs.jquery.com/Ajax/ajaxSend)**[($callback)](http://docs.jquery.com/Ajax/ajaxSend) Attach a function to be executed before an AJAX request is sent. This is an Ajax Event. + * **[ajaxStart](http://docs.jquery.com/Ajax/ajaxStart)**[($callback)](http://docs.jquery.com/Ajax/ajaxStart) Attach a function to be executed whenever an AJAX request begins and there is none already active. This is an Ajax Event. + * **[ajaxStop](http://docs.jquery.com/Ajax/ajaxStop)**[($callback)](http://docs.jquery.com/Ajax/ajaxStop) Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event. + * **[ajaxSuccess](http://docs.jquery.com/Ajax/ajaxSuccess)**[($callback)](http://docs.jquery.com/Ajax/ajaxSuccess) Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event. +## Misc + * **[phpQuery::ajaxSetup](http://docs.jquery.com/Ajax/jQuery.ajaxSetup)**[($options)](http://docs.jquery.com/Ajax/jQuery.ajaxSetup) Setup global settings for AJAX requests. + * **[serialize](http://docs.jquery.com/Ajax/serialize)**[()](http://docs.jquery.com/Ajax/serialize) Serializes a set of input elements into a string of data. This will serialize all given elements. + * **[serializeArray](http://docs.jquery.com/Ajax/serializeArray)**[()](http://docs.jquery.com/Ajax/serializeArray) Serializes all forms and form elements (like the .serialize() method) but returns a JSON data structure for you to work with. +## Options +Detailed options description in available at [jQuery Documentation Site](http://docs.jquery.com/Ajax/jQuery.ajax#toptions). + * **`async`** `Boolean` + * **`beforeSend`** `Function` + * **`cache`** `Boolean` + * **`complete`** `Function` + * **`contentType`** `String` + * **`data`** `Object, String` + * **`dataType`** `String` + * **`error`** `Function` + * **`global`** `Boolean` + * **`ifModified`** `Boolean` + * **`jsonp`** `String` + * **`password`** `String` + * **`processData`** `Boolean` + * **`success`** `Function` + * **`timeout`** `Number` + * **`type`** `String` + * **`url`** `String` + * **`username`** `String` + +Read more at [Ajax](http://docs.jquery.com/Ajax) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/Attributes.md b/wiki/Attributes.md new file mode 100644 index 0000000..c4ca398 --- /dev/null +++ b/wiki/Attributes.md @@ -0,0 +1,33 @@ +## Example +``` +pq('a')->attr('href', 'newVal')->removeClass('className')->html('newHtml')->... +``` +# Table of Contents + * [Attr](#Attr.md) + * [Class](#Class.md) + * [HTML](#HTML.md) + * [Text](#Text.md) + * [Value](#Value.md) +## Attr + * **[attr](http://docs.jquery.com/Attributes/attr)**[($name)](http://docs.jquery.com/Attributes/attr) Access a property on the first matched element. This method makes it easy to retrieve a property value from the first matched element. If the element does not have an attribute with such a name, undefined is returned. + * **[attr](http://docs.jquery.com/Attributes/attr)**[($properties)](http://docs.jquery.com/Attributes/attr) Set a key/value object as properties to all matched elements. + * **[attr](http://docs.jquery.com/Attributes/attr)**[($key, $value)](http://docs.jquery.com/Attributes/attr) Set a single property to a value, on all matched elements. + * **[attr](http://docs.jquery.com/Attributes/attr)**[($key, $fn)](http://docs.jquery.com/Attributes/attr) Set a single property to a computed value, on all matched elements. + * **[removeAttr](http://docs.jquery.com/Attributes/removeAttr)**[($name)](http://docs.jquery.com/Attributes/removeAttr) Remove an attribute from each of the matched elements. +## Class + * **[addClass](http://docs.jquery.com/Attributes/addClass)**[($class)](http://docs.jquery.com/Attributes/addClass) Adds the specified class(es) to each of the set of matched elements. + * **[hasClass](http://docs.jquery.com/Attributes/hasClass)**[($class)](http://docs.jquery.com/Attributes/hasClass) Returns true if the specified class is present on at least one of the set of matched elements. + * **[removeClass](http://docs.jquery.com/Attributes/removeClass)**[($class)](http://docs.jquery.com/Attributes/removeClass) Removes all or the specified class(es) from the set of matched elements. + * **[toggleClass](http://docs.jquery.com/Attributes/toggleClass)**[($class)](http://docs.jquery.com/Attributes/toggleClass) Adds the specified class if it is not present, removes the specified class if it is present. +## HTML + * **[html](http://docs.jquery.com/Attributes/html)**[()](http://docs.jquery.com/Attributes/html) Get the html contents (innerHTML) of the first matched element. This property is not available on XML documents (although it will work for XHTML documents). + * **[html](http://docs.jquery.com/Attributes/html)**[($val)](http://docs.jquery.com/Attributes/html) Set the html contents of every matched element. This property is not available on XML documents (although it will work for XHTML documents). +## Text + * **[text](http://docs.jquery.com/Attributes/text)**[()](http://docs.jquery.com/Attributes/text) Get the combined text contents of all matched elements. + * **[text](http://docs.jquery.com/Attributes/text)**[($val)](http://docs.jquery.com/Attributes/text) Set the text contents of all matched elements. +## Value + * **[val](http://docs.jquery.com/Attributes/val)**[()](http://docs.jquery.com/Attributes/val) Get the content of the value attribute of the first matched element. + * **[val](http://docs.jquery.com/Attributes/val)**[($val)](http://docs.jquery.com/Attributes/val) Set the value attribute of every matched element. + * **[val](http://docs.jquery.com/Attributes/val)**[($val)](http://docs.jquery.com/Attributes/val) Checks, or selects, all the radio buttons, checkboxes, and select options that match the set of values. + +Read more at [Attributes](http://docs.jquery.com/Attributes) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/Basics.md b/wiki/Basics.md new file mode 100644 index 0000000..a942b59 --- /dev/null +++ b/wiki/Basics.md @@ -0,0 +1,54 @@ +## Example +``` +phpQuery::newDocumentFileXHTML('my-xhtml.html')->find('p'); +$ul = pq('ul'); +``` +# Table of Contents + * [Loading documents](#Loading_documents.md) + * [pq() function](#pq_function.md) + +## Loading documents + * phpQuery::**newDocument**($html, $contentType = null) Creates new document from markup. If no $contentType, autodetection is made (based on markup). If it fails, text/html in utf-8 is used. + * phpQuery::**newDocumentFile**($file, $contentType = null) Creates new document from file. Works like newDocument() + * phpQuery::**newDocumentHTML**($html, $charset = 'utf-8') + * phpQuery::**newDocumentXHTML**($html, $charset = 'utf-8') + * phpQuery::**newDocumentXML**($html, $charset = 'utf-8') + * phpQuery::**newDocumentPHP**($html, $contentType = null) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) + * phpQuery::**newDocumentFileHTML**($file, $charset = 'utf-8') + * phpQuery::**newDocumentFileXHTML**($file, $charset = 'utf-8') + * phpQuery::**newDocumentFileXML**($file, $charset = 'utf-8') + * phpQuery::**newDocumentFilePHP**($file, $contentType) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) +## pq function +**`pq($param, $context = null);`** + +**pq();** function is equivalent of jQuery's **$();**. It's used for 3 type of things: + 1. Importing markup +``` +// Import into selected document: +// doesn't accept text nodes at beginning of input string +pq('
') +// Import into document with ID from $pq->getDocumentID(): +pq('
', $pq->getDocumentID()) +// Import into same document as DOMNode belongs to: +pq('
', DOMNode) +// Import into document from phpQuery object: +pq('
', $pq) +``` + 1. Running queries +``` +// Run query on last selected document: +pq('div.myClass') +// Run query on document with ID from $pq->getDocumentID(): +pq('div.myClass', $pq->getDocumentID()) +// Run query on same document as DOMNode belongs to and use node(s)as root for query: +pq('div.myClass', DOMNode) +// Run query on document from phpQuery object +// and use object's stack as root node(s) for query: +pq('div.myClass', $pq) +``` + 1. Wrapping DOMNodes with phpQuery objects +``` +foreach(pq('li') as $li) + // $li is pure DOMNode, change it to phpQuery object + pq($li); +``` \ No newline at end of file diff --git a/wiki/CSS.md b/wiki/CSS.md new file mode 100644 index 0000000..e1a913a --- /dev/null +++ b/wiki/CSS.md @@ -0,0 +1 @@ +Work in progress. Scheduled before 1.0. \ No newline at end of file diff --git a/wiki/Callbacks.md b/wiki/Callbacks.md new file mode 100644 index 0000000..8c6645d --- /dev/null +++ b/wiki/Callbacks.md @@ -0,0 +1,91 @@ +# Table of Contents + * [What are callbacks](#What_are_callbacks.md) + * [phpQuery callback system](#phpQuery_callbacks.md) + * [Callback class](#Callback.md) + * [CallbackParam class](#CallbackParam.md) + * [CallbackReference class](#CallbackReference.md) + * [Scope Pseudo-Inheritance](#Scope_Pseudo_Inheritance.md) +## What are callbacks +Callbacks are functions _called back_ by other functions in proper moment (eg on [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request error). + +In **JavaScript** this pattern can be very flexible due to [Closures](http://en.wikipedia.org/wiki/Closure_(computer_science)) support, which can be inline (no code break) and inherits scope (no need to passing params). + +**PHP** has only simple [support for callbacks](http://pl2.php.net/manual/en/function.call-user-func-array.php) so the case is more complicated. That's why phpQuery extends callback support by it's own. +## phpQuery callback system +phpQuery uses it's own approach to callbacks. This task is achieved thou **Callback**, **CallbackParam** and **CallbackReference** classes. +### Callback +Callback class is used for wrapping valid callbacks with params. +#### Example 1 +``` +function myCallback($param1, $param2) { + var_dump($param1); + var_dump($param2); +} +phpQuery::get($url, + new Callback('myCallback', 'myParam1', new CallbackParam) +); +// now $param1 in myCallback will have value 'myParam1' +// and $param2 will be parameter passed by function calling callback +// which in this example would be ajax request result +``` +### CallbackParam +As we can see in [last example](#Example_1.md), new instance of CallbackParam class is used for defining places, where original callback parameter(s) will be placed. Such pattern can be used also without Callback class for some methods. +#### Example 2 +``` +phpQuery::each( + // first param is array which will be iterated + array(1,2,3), + // second param is callback (string or array to call objects method) + 'myCallback', + // rest of params are ParamStructure + // CallbackParam objects will be changed to $i and $v by phpQuery::each method + 'param1', new CallbackParam, new CallbackParam, 'param4' +); +function myCallback($param1, $i, $v, $param4) { + print "Index: $i; Value: $v"; +} +``` +Methods supporting CallbackParam **without** using Callback class: + * `phpQuery::each()` + * `phpQuery::map()` + * `pq()->each()` + * `pq()->map()` +### CallbackReference +Finally, CallbackReference can be used when we don't really want a callback, only parameter passed to it. CallbackReference takes first parameter's value and passes it to reference. Thanks to that, we can use **if statement** instead of **callback function**. +#### Example 3 +``` +$html; +phpQuery::get($url, new CallbackReference($html)); +if ($html) { + // callback triggered, value non-false + phpQuery::get($url, new CallbackReference($html)); + if ($html) { + // we just skipped 2 function declarations + } +} +``` +## Scope Pseudo Inheritance +There is an easy way to pseudo inherit scope in PHP. [Scope](http://en.wikipedia.org/wiki/Scope_(programming)) means _variables accessible in specified point of code_ (which in other words means _any variable you can use_). It's achieved using [compact()](http://php.net/compact) and [extract()](http://php.net/extract) functions. +#### Example 4 +Look at this modified [example 2](#Example_2.md). Previous comments were removed. +``` +$a = 'foo'; +$b = 'bar'; +phpQuery::each( + array(1,2,3), + 'myCallback', + // notice that 'param1' changed to compact('a', 'b') + // where 'a' and 'b' are variable names accessible in actual scope + compact('a', 'b'), new CallbackParam, new CallbackParam, 'param4' +); +function myCallback($scope, $i, $v, $param4) { + // this is the place where variables from $scope array + // are forwarded to actual function's scope + extract($scope); + print "Var a: $a"; // will print 'Var a: foo' + print "Var b: $b"; // will print 'Var a: bar' + print "Index: $i; Value: $v"; +} +``` +## Future +In the future this functionality will be extended and more methods will support it. Check [Issue Tracker entry #48](http://code.google.com/p/phpquery/issues/detail?id=48) if you're interested in any way. \ No newline at end of file diff --git a/wiki/Chains.md b/wiki/Chains.md new file mode 100644 index 0000000..2ff4028 --- /dev/null +++ b/wiki/Chains.md @@ -0,0 +1 @@ +TODO ;) \ No newline at end of file diff --git a/wiki/CommandLineInterface.md b/wiki/CommandLineInterface.md new file mode 100644 index 0000000..f3e4d9d --- /dev/null +++ b/wiki/CommandLineInterface.md @@ -0,0 +1,14 @@ +phpQuery features CommandLineInterface aka CLI. +``` +Usage: phpquery URL --method1 arg1 arg2 argN --method2 arg1 arg2 argN ... +Example: phpquery 'http://localhost' --find 'div > p' --contents +Pipe: cat index.html | phpquery --find 'div > p' --contents +Docs: http://code.google.com/p/phpquery/wiki/ +``` +## Example +Fetch number of downloads of all release packages. +``` +phpquery 'http://code.google.com/p/phpquery/downloads/list?can=1' \ + --find '.vt.col_4 a' --contents \ + --getString null array_sum +``` \ No newline at end of file diff --git a/wiki/Debugging.md b/wiki/Debugging.md new file mode 100644 index 0000000..b608806 --- /dev/null +++ b/wiki/Debugging.md @@ -0,0 +1,16 @@ +## Enabling debugging +``` +// enable debugging messages +phpQuery::$debug = 1; +// enable extensive debugging messages +// used to debug document loading errors from phpQuery::newDocument() +phpQuery::$debug = 2; +``` +## Debugging methods +``` +// debug inside chain +pq('.foo')->dump()->...; +pq('.foo')->dumpWhois()->...; +pq('.foo')->dumpTree()->...; +pq('.foo')->dumpDie()->...; +``` \ No newline at end of file diff --git a/wiki/Dependencies.md b/wiki/Dependencies.md new file mode 100644 index 0000000..4a4108d --- /dev/null +++ b/wiki/Dependencies.md @@ -0,0 +1,14 @@ +**phpQuery** depends on following code parts: + * [PHP5](#PHP5.md) + * [PHP5 DOM extension](#DOM_extension.md) + * [Zend Framework](#Zend_Framework.md) + +## PHP5 +Required version of PHP is [PHP5](http://www.php.net/), **5.2** recommended. + +## DOM extension +PHP5's build-in [DOM extension](http://php.net/manual/en/book.dom.php) is required. Users of +[windows XAMPP](http://www.apachefriends.org/en/xampp-windows.html) (and maybe other unofficial PHP distributions) need to disable depracated [DOM XML](http://php.net/manual/en/ref.domxml.php) extension. More information can be found in [this post on mrclay.org](http://mrclay.org/index.php/2008/10/08/getting-phpquery-running-under-xampp-for-windows/) + +## Zend Framework +[Zend Framework](http://framework.zend.com/) is used as HTTP Client and JSON encoder. Those who already have Zend Framework in their applications, can remove directory **/phpQuery/Zend**. Only condition is having proper include path set for own copy of the library. \ No newline at end of file diff --git a/wiki/Events.md b/wiki/Events.md new file mode 100644 index 0000000..65ef2b1 --- /dev/null +++ b/wiki/Events.md @@ -0,0 +1,47 @@ +# Table of Contents + * [Example](#Example.md) + * [Server Side Events](#Server_Side_Events.md) + * [Page Load](#Page_Load.md) + * [Event Handling](#Event_Handling.md) + * [Interaction Helpers](#Interaction_Helpers.md) + * [Event Helpers](#Event_Helpers.md) + +## Example +``` +pq('form')->bind('submit', 'submitHandler')->trigger('submit')->... +function submitHandler($e) { + print 'Target: '.$e->target->tagName; + print 'Bubbling ? '.$e->currentTarget->tagName; +} +``` + +## Server Side Events +phpQuery support **server-side** events, same as jQuery handle client-side ones. On server there isn't, of course, events such as _mouseover_ (but they can be triggered). + +By default, phpQuery automatically fires up only **change** event for form elements. If you load WebBrowser plugin, **submit** and **click** will be handled properly - eg submitting form with inputs' data to action URL via new [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. + +$this (`this` in JS) context for handler scope **isn't available**. You have to use one of following manually: + * $event->**target** + * $event->**currentTarget** + * $event->**relatedTarget** + +## Page Load +_none_ + +## Event Handling + * **[bind](http://docs.jquery.com/Events/bind)**[($type, $data, $fn)](http://docs.jquery.com/Events/bind) Binds a handler to one or more events (like click) for each matched element. Can also bind custom events. + * **[one](http://docs.jquery.com/Events/one)**[($type, $data, $fn)](http://docs.jquery.com/Events/one) Binds a handler to one or more events to be executed once for each matched element. + * **[trigger](http://docs.jquery.com/Events/trigger)**[($type , $data )](http://docs.jquery.com/Events/trigger) Trigger a type of event on every matched element. + * **[triggerHandler](http://docs.jquery.com/Events/triggerHandler)**[($type , $data )](http://docs.jquery.com/Events/triggerHandler) This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. + * **[unbind](http://docs.jquery.com/Events/unbind)**[($type , $data )](http://docs.jquery.com/Events/unbind) This does the opposite of bind, it removes bound events from each of the matched elements. + +## Interaction Helpers +_none_ + +## Event Helpers + * **[change](http://docs.jquery.com/Events/change)**[()](http://docs.jquery.com/Events/change) Triggers the change event of each matched element. + * **[change](http://docs.jquery.com/Events/change)**[($fn)](http://docs.jquery.com/Events/change) Binds a function to the change event of each matched element. + * **[submit](http://docs.jquery.com/Events/submit)**[()](http://docs.jquery.com/Events/submit) Trigger the submit event of each matched element. + * **[submit](http://docs.jquery.com/Events/submit)**[($fn)](http://docs.jquery.com/Events/submit) Bind a function to the submit event of each matched element. + +Read more at [Events](http://docs.jquery.com/Events) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/LibrarySections.md b/wiki/LibrarySections.md new file mode 100644 index 0000000..d6a3885 --- /dev/null +++ b/wiki/LibrarySections.md @@ -0,0 +1 @@ +Renamed to [Manual](http://code.google.com/p/phpquery/wiki/Manual). \ No newline at end of file diff --git a/wiki/Manipulation.md b/wiki/Manipulation.md new file mode 100644 index 0000000..255df6a --- /dev/null +++ b/wiki/Manipulation.md @@ -0,0 +1,45 @@ +## Example +``` +pq('div.old')->replaceWith( pq('div.new')->clone() )->appendTo('.trash')->prepend('Deleted')->... +``` +# Table of Contents + * [Changing Contents](#Changing_Contents.md) + * [Inserting Inside](#Inserting_Inside.md) + * [Inserting Outside](#Inserting_Outside.md) + * [Inserting Around](#Inserting_Around.md) + * [Replacing](#Replacing.md) + * [Removing](#Removing.md) + * [Copying](#Copying.md) +## Changing Contents + * **[html](http://docs.jquery.com/Manipulation/html)**[()](http://docs.jquery.com/Manipulation/html) Get the html contents (innerHTML) of the first matched element. This property is not available on XML documents (although it will work for XHTML documents). + * **[html](http://docs.jquery.com/Manipulation/html)**[($val)](http://docs.jquery.com/Manipulation/html) Set the html contents of every matched element. This property is not available on XML documents (although it will work for XHTML documents). + * **[text](http://docs.jquery.com/Manipulation/text)**[()](http://docs.jquery.com/Manipulation/text) Get the combined text contents of all matched elements. + * **[text](http://docs.jquery.com/Manipulation/text)**[($val)](http://docs.jquery.com/Manipulation/text) Set the text contents of all matched elements. +## Inserting Inside + * **[append](http://docs.jquery.com/Manipulation/append)**[($content)](http://docs.jquery.com/Manipulation/append) Append content to the inside of every matched element. + * **[appendTo](http://docs.jquery.com/Manipulation/appendTo)**[($content)](http://docs.jquery.com/Manipulation/appendTo) Append all of the matched elements to another, specified, set of elements. + * **[prepend](http://docs.jquery.com/Manipulation/prepend)**[($content)](http://docs.jquery.com/Manipulation/prepend) Prepend content to the inside of every matched element. + * **[prependTo](http://docs.jquery.com/Manipulation/prependTo)**[($content)](http://docs.jquery.com/Manipulation/prependTo) Prepend all of the matched elements to another, specified, set of elements. +## Inserting Outside + * **[after](http://docs.jquery.com/Manipulation/after)**[($content)](http://docs.jquery.com/Manipulation/after) Insert content after each of the matched elements. + * **[before](http://docs.jquery.com/Manipulation/before)**[($content)](http://docs.jquery.com/Manipulation/before) Insert content before each of the matched elements. + * **[insertAfter](http://docs.jquery.com/Manipulation/insertAfter)**[($content)](http://docs.jquery.com/Manipulation/insertAfter) Insert all of the matched elements after another, specified, set of elements. + * **[insertBefore](http://docs.jquery.com/Manipulation/insertBefore)**[($content)](http://docs.jquery.com/Manipulation/insertBefore) Insert all of the matched elements before another, specified, set of elements. +## Inserting Around + * **[wrap](http://docs.jquery.com/Manipulation/wrap)**[($html)](http://docs.jquery.com/Manipulation/wrap) Wrap each matched element with the specified HTML content. + * **[wrap](http://docs.jquery.com/Manipulation/wrap)**[($elem)](http://docs.jquery.com/Manipulation/wrap) Wrap each matched element with the specified element. + * **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[($html)](http://docs.jquery.com/Manipulation/wrapAll) Wrap all the elements in the matched set into a single wrapper element. + * **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[($elem)](http://docs.jquery.com/Manipulation/wrapAll) Wrap all the elements in the matched set into a single wrapper element. + * **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[($html)](http://docs.jquery.com/Manipulation/wrapInner) Wrap the inner child contents of each matched element (including text nodes) with an HTML structure. + * **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[($elem)](http://docs.jquery.com/Manipulation/wrapInner) Wrap the inner child contents of each matched element (including text nodes) with a DOM element. +## Replacing + * **[replaceWith](http://docs.jquery.com/Manipulation/replaceWith)**[($content)](http://docs.jquery.com/Manipulation/replaceWith) Replaces all matched elements with the specified HTML or DOM elements. + * **[replaceAll](http://docs.jquery.com/Manipulation/replaceAll)**[($selector)](http://docs.jquery.com/Manipulation/replaceAll) Replaces the elements matched by the specified selector with the matched elements. +## Removing + * **[empty](http://docs.jquery.com/Manipulation/empty)**[()](http://docs.jquery.com/Manipulation/empty) Remove all child nodes from the set of matched elements. + * **[remove](http://docs.jquery.com/Manipulation/remove)**[($expr)](http://docs.jquery.com/Manipulation/remove) Removes all matched elements from the DOM. +## Copying + * **[clone](http://docs.jquery.com/Manipulation/clone)**[()](http://docs.jquery.com/Manipulation/clone) Clone matched DOM Elements and select the clones. + * **[clone](http://docs.jquery.com/Manipulation/clone)**[($true)](http://docs.jquery.com/Manipulation/clone) Clone matched DOM Elements, and all their event handlers, and select the clones. + +Read more at [Manipulation](http://docs.jquery.com/Manipulation) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/Manual.md b/wiki/Manual.md new file mode 100644 index 0000000..8eb8868 --- /dev/null +++ b/wiki/Manual.md @@ -0,0 +1,21 @@ + 1. [Basics](http://code.google.com/p/phpquery/wiki/Basics) + 1. [Ported jQuery sections](http://code.google.com/p/phpquery/wiki/jQueryPortingState) + 1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) + 1. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) + 1. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) + 1. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) + 1. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) + 1. [Events](http://code.google.com/p/phpquery/wiki/Events) + 1. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) + 1. [Plugin ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) + 1. [PHP Support](http://code.google.com/p/phpquery/wiki/PHPSupport) + 1. [Command Line Interface](http://code.google.com/p/phpquery/wiki/CommandLineInterface) + 1. [Multi document support](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) + 1. [Plugins](http://code.google.com/p/phpquery/wiki/PluginsServerSide) + 1. [WebBrowser](http://code.google.com/p/phpquery/wiki/WebBrowser) + 1. [Scripts](http://code.google.com/p/phpquery/wiki/ScriptsPlugin) + 1. [jQueryServer](http://code.google.com/p/phpquery/wiki/jQueryServer) + 1. [Debugging](http://code.google.com/p/phpquery/wiki/Debugging) + 1. Bootstrap file + +**[API Reference](http://meta20.net/phpquery-api/)** is also available. \ No newline at end of file diff --git a/wiki/MultiDocumentSupport.md b/wiki/MultiDocumentSupport.md new file mode 100644 index 0000000..6febb38 --- /dev/null +++ b/wiki/MultiDocumentSupport.md @@ -0,0 +1,53 @@ +## What MultiDocumentSupport is + * support for working on several documents in same time + * easy importing of nodes from one document to another + * pointing document thought + * phpQuery object + * [DOMNode](http://www.php.net/manual/en/class.domnode.php) object + * [DOMDocument](http://www.php.net/manual/en/class.domdocument.php) object + * internal document ID + * last created (or selected) document is assumed to be default in pq(); +## What MultiDocumentSupport is NOT + * it's **not possible** to fetch nodes from several document in one query + * it's **not possible** to operate on nodes from several document in one phpQuery object + +## Example +``` +// first three documents are wrapped inside phpQuery +$doc1 = phpQuery::newDocumentFile('my-file.html'); +$doc2 = phpQuery::newDocumentFile('my-file.html'); +$doc3 = phpQuery::newDocumentFile('my-other-file.html'); +// $doc4 is plain DOMDocument +$doc4 = new DOMDocument; +$doc4->loadHTMLFile('my-file.html'); +// find first UL list in $doc1 +$doc1->find('ul:first') + // append all LIs from $doc2 (node import) + ->append( $doc2->find('li') ) + // append UL (with new LIs) into $doc3 BODY (node import) + ->appendTo( $doc3->find('body') ); +// this will find all LIs from $doc3 +// thats because it was created as last one +pq('li'); +// this will find all LIs inside first UL in $doc2 (context query) +pq('li', $doc2->find('ul:first')->get()); +// this will find all LIs in whole $doc2 (not a context query) +pq('li', $doc2->find('ul:first')->getDocumentID()); +// this will transparently load $doc4 into phpQuery::$documents +// and then all LIs will be found +// TODO this example must be verified +pq('li', $doc4); +``` +## Static Methods + * phpQuery::**newDocument**($html) Creates new document from markup + * phpQuery::**newDocumentFile**($file) Creates new document from file + * phpQuery::**getDocument**($id = null) Returns phpQueryObject containing document with id $id or default document (last created/selected) + * phpQuery::**selectDocument**($id) Sets default document to $id + * phpQuery::**unloadDocuments**($id = null) Unloades all or specified document from memory + * phpQuery::**getDocumentID**($source) Returns $source's document ID + * phpQuery::**getDOMDocument**($source) Get DOMDocument object related to $source +## Object Methods + * $pq->**getDocument**() Returns object with stack set to document root + * $pq->**getDocumentID**() Get object's Document ID + * $pq->**getDocumentIDRef**(&$documentID) Saves object's DocumentID to $var by reference + * $pq->**unloadDocument**() Unloads whole document from memory \ No newline at end of file diff --git a/wiki/PHPSupport.md b/wiki/PHPSupport.md new file mode 100644 index 0000000..95d00a0 --- /dev/null +++ b/wiki/PHPSupport.md @@ -0,0 +1,78 @@ +Although **phpQuery** is a [jQuery port](http://code.google.com/p/phpquery/wiki/jQueryPortingState), there is extensive PHP-specific support. + +# Table of Contents + * [Class Interfaces](#Class_Interfaces.md) + * [Iterator Interface](#Iterator.md) + * [ArrayAccess](#Array_Access.md) + * [Countable Interface](#Countable.md) + * [Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) + * [PHP Code Support](#PHP_Code_Support.md) + * [Opening PHP files as DOM](#Opening_PHP_files_as_DOM.md) + * [Inputting PHP code](#Inputting_PHP_code.md) + * [Outputting PHP code](#Outputting_PHP_code.md) + +## Class Interfaces +phpQuery implements some of [Standard PHP Library (SPL)](http://pl.php.net/spl) interfaces. +#### Iterator +Iterator interface allows looping objects thou native PHP **foreach loop**. Example: +``` +// get all direct LI elements from UL list of class 'im-the-list' +$LIs = pq('ul.im-the-list > li'); +foreach($LIs as $li) { + pq($li)->addClass('foreached'); +} +``` +Now there is a catch above. Foreach loop **doesn't return phpQuery object**. Instead it returns pure DOMNode. That's how jQuery does, because not always you need **phpQuery** when you found interesting nodes. +#### Array Access +If you like writing arrays, with phpQuery you can still do it, thanks to the ArrayAccess interface. +``` +$pq = phpQuery::newDocumentFile('somefile.html'); +// print first list outer HTML +print $pq['ul:first']; +// change INNER HTML of second LI directly in first UL +$pq['ul:first > li:eq(1)'] = 'new inner html of second LI directly in first UL'; +// now look at the difference (outer vs inner) +print $pq['ul:first > li:eq(1)']; +// will print
  • new inner html of second LI directly in first UL
  • +``` +#### Countable +If used to do `count($something)` you can still do this that way, instead of eg `pq('p')->size()`. +``` +// count all direct LIs in first list +print count(pq('ul:first > li')); +``` +## Callbacks +There is a special [Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) wiki section, to which you should refer to. +## PHP Code Support +#### Opening PHP files as DOM +PHP files can be opened using **phpQuery::newDocumentPHP($markup)** or **phpQuery::newDocumentFilePHP($file)**. Such files are visible as DOM, where: + * PHP tags beetween DOM elements are available (queryable) as ` ...code... ` + * PHP tags inside attributes are HTML entities + * PHP tags between DOM element's attributes are **not yet supported** +#### Inputting PHP code +Additional methods allows placing PHP code inside DOM. Below each method visible is it's logic equivalent. + * **attrPHP**($attr, $code) + * [attr](http://docs.jquery.com/Attributes/attr)($attr, "") + * **addClassPHP**($code) + * [addClass](http://docs.jquery.com/Attributes/addClass)("") + * **beforePHP**($code) + * [before](http://docs.jquery.com/Manipulation/before)("") + * **afterPHP**($code) + * [after](http://docs.jquery.com/Manipulation/after)("") + * **prependPHP**($code) + * [prepend](http://docs.jquery.com/Manipulation/prepend)("") + * **appendPHP**($code) + * [append](http://docs.jquery.com/Manipulation/append)("") + * **php**($code) + * [html](http://docs.jquery.com/Manipulation/html)("") + * **wrapAllPHP**($codeBefore, $codeAfter) + * [wrapAll](http://docs.jquery.com/Manipulation/wrapAll)("") + * **wrapPHP**($codeBefore, $codeAfter) + * [wrap](http://docs.jquery.com/Manipulation/wrap)("") + * **wrapInnerPHP**($codeBefore, $codeAfter) + * [wrapInner](http://docs.jquery.com/Manipulation/wrapInner)("") + * **replaceWithPHP**($code) + * [replaceWith](http://docs.jquery.com/Manipulation/replaceWith)("") +#### Outputting PHP code +Code inserted with methods above won't be returned as valid (runnable) using classic output methods such as **html()**. To make it work, **php()** method without parameter have to be used. Optionaly **phpQuery::markupToPHP($markup)** can activate tags in string outputed before. +**REMEMBER** Outputing runnable code and placing it on webserver is always dangerous ! \ No newline at end of file diff --git a/wiki/PluginsClientSidePorts.md b/wiki/PluginsClientSidePorts.md new file mode 100644 index 0000000..d7a2e28 --- /dev/null +++ b/wiki/PluginsClientSidePorts.md @@ -0,0 +1,7 @@ +In [Issue Tracker](http://code.google.com/p/phpquery/issues/list) there is a list of [plugins which are planned to be ported](http://code.google.com/p/phpquery/issues/list?can=2&q=label%3APort). +## JSON +Port of [JSON](http://jollytoad.googlepages.com/json.js) plugin. +``` +$jsonString = phpQuery::toJSON( pq('form')->serializeArray() ); +$array = phpQuery::parseJSON('{"foo": "bar"}'); +``` \ No newline at end of file diff --git a/wiki/PluginsServerSide.md b/wiki/PluginsServerSide.md new file mode 100644 index 0000000..641e34f --- /dev/null +++ b/wiki/PluginsServerSide.md @@ -0,0 +1,77 @@ +If you need to write plugin only for simple task, write a **script** using ScriptsPlugin. + +## Using plugins +Plugins are loaded using **plugin** method from phpQueryObject or phpQuery static namespace. +``` +// all calls to plugin below are equal +phpQuery::plugin('example') +phpQuery::plugin('example', 'example.php') +pq('ul')->plugin('example') +pq('ul')->plugin('example', 'example.php') +``` +## Writing plugins +Plugin consist from 2 classes - first extending **phpQueryObjects** (result of pq(); function) and second, extending static **phpQuery::$plugins** namespace. Plugin classes are never intialized, just method calls are forwarded in static way from phpQuery. + +#### Extending phpQueryObject +``` +/** + * phpQuery plugin class extending phpQuery object. + * Methods from this class are callable on every phpQuery object. + * + * Class name prefix 'phpQueryObjectPlugin_' must be preserved. + */ +abstract class phpQueryObjectPlugin_example { + /** + * Limit binded methods. + * + * null means all public. + * array means only specified ones. + * + * @var array|null + */ + public static $phpQueryMethods = null; + /** + * Enter description here... + * + * @param phpQueryObject $self + */ + public static function example($self, $arg1) { + // this method can be called on any phpQuery object, like this: + // pq('div')->example('$arg1 Value') + + // do something + $self->append('Im just an example !'); + // change stack of result object + return $self->find('div'); + } + protected static function helperFunction() { + // this method WONT be avaible as phpQuery method, + // because it isn't publicly callable + } +} +``` +#### Extending phpQuery +``` +/** + * phpQuery plugin class extending phpQuery static namespace. + * Methods from this class are callable as follows: + * phpQuery::$plugins->staticMethod() + * + * Class name prefix 'phpQueryPlugin_' must be preserved. + */ +abstract class phpQueryPlugin_example { + /** + * Limit binded methods. + * + * null means all public. + * array means only specified ones. + * + * @var array|null + */ + public static $phpQueryMethods = null; + public static function staticMethod() { + // this method can be called within phpQuery class namespace, like this: + // phpQuery::$plugins->staticMethod() + } +} +``` \ No newline at end of file diff --git a/wiki/ReleasePackages.md b/wiki/ReleasePackages.md new file mode 100644 index 0000000..c5929ca --- /dev/null +++ b/wiki/ReleasePackages.md @@ -0,0 +1,11 @@ +# This page is TODO + +## Formats + * RPM + * ZIP + +## Forms + * Standard + * OneFile + * Broken plugins support ? + * ZendFramework not included \ No newline at end of file diff --git a/wiki/ScriptsPlugin.md b/wiki/ScriptsPlugin.md new file mode 100644 index 0000000..f8e5921 --- /dev/null +++ b/wiki/ScriptsPlugin.md @@ -0,0 +1,24 @@ +ScriptsPlugin simplifies writing short code scripts which can be easily reused (chained). It removes plugin overhead allowing script to be one-line command. + +## Using scripts +Before using any script, you need to load **Scripts** plugin, like so: +``` +phpQuery::plugin('Scripts'); +// or inside a chain +pq('li')->plugin('Scripts'); +``` +After that, any available script can be used thou **script** method. +``` +print pq('div')->script('safe_print'); +``` +## Writing scripts +Scripts are placed in **/phpQuery/plugins/Scripts**. Each script has it's own file. Each file has access to 4 variables: + * **$self** Represents $this + * **$params** Represents parameters passed to script() method (without script name) + * **$return** If not null, will be used as method result + * **$config** Content of config.php file +By default each script returns $self aka $this. +##### Example script +``` +$return = $self->find($params[0]); +``` \ No newline at end of file diff --git a/wiki/Selectors.md b/wiki/Selectors.md new file mode 100644 index 0000000..0d737bc --- /dev/null +++ b/wiki/Selectors.md @@ -0,0 +1,76 @@ +Selectors are the heart of jQuery-like interface. Most of [CSS Level 3](http://www.w3.org/TR/2005/WD-css3-selectors-20051215/) syntax is implemented (in state same as in jQuery). +## Example +``` +pq(".class ul > li[rel='foo']:first:has(a)")->appendTo('.append-target-wrapper div')->... +``` +# Table of Contents + * [Basics](#Basics.md) + * [Hierarchy](#Hierarchy.md) + * [Basic Filters](#Basic_Filters.md) + * [Content Filters](#Content_Filters.md) + * [Visibility Filters](#Visibility_Filters.md) + * [Attribute Filters](#Attribute_Filters.md) + * [Child Filters](#Child_Filters.md) + * [Forms](#Forms.md) + * [Form Filters](#Form_Filters.md) +## Basics + * **[#id](http://docs.jquery.com/Selectors/id)** Matches a single element with the given id attribute. + * **[element](http://docs.jquery.com/Selectors/element)** Matches all elements with the given name. + * **[.class](http://docs.jquery.com/Selectors/class)** Matches all elements with the given class. + * **[\*](http://docs.jquery.com/Selectors/all)** Matches all elements. + * **[selector1, selector2, selectorN](http://docs.jquery.com/Selectors/multiple)** Matches the combined results of all the specified selectors. +## Hierarchy + * **[ancestor descendant](http://docs.jquery.com/Selectors/descendant)** Matches all descendant elements specified by "descendant" of elements specified by "ancestor". + * **[parent > child](http://docs.jquery.com/Selectors/child)** Matches all child elements specified by "child" of elements specified by "parent". + * **[prev + next](http://docs.jquery.com/Selectors/next)** Matches all next elements specified by "next" that are next to elements specified by "prev". + * **[prev ~ siblings](http://docs.jquery.com/Selectors/siblings)** Matches all sibling elements after the "prev" element that match the filtering "siblings" selector. +## Basic Filters + * **[:first](http://docs.jquery.com/Selectors/first)** Matches the first selected element. + * **[:last](http://docs.jquery.com/Selectors/last)** Matches the last selected element. + * **[:not(selector)](http://docs.jquery.com/Selectors/not)** Filters out all elements matching the given selector. + * **[:even](http://docs.jquery.com/Selectors/even)** Matches even elements, zero-indexed. + * **[:odd](http://docs.jquery.com/Selectors/odd)** Matches odd elements, zero-indexed. + * **[:eq(index)](http://docs.jquery.com/Selectors/eq)** Matches a single element by its index. + * **[:gt(index)](http://docs.jquery.com/Selectors/gt)** Matches all elements with an index above the given one. + * **[:lt(index)](http://docs.jquery.com/Selectors/lt)** Matches all elements with an index below the given one. + * **[:header](http://docs.jquery.com/Selectors/header)** Matches all elements that are headers, like h1, h2, h3 and so on. + * **[:animated](http://docs.jquery.com/Selectors/animated)** Matches all elements that are currently being animated. +## Content Filters + * **[:contains(text)](http://docs.jquery.com/Selectors/contains)** Matches elements which contain the given text. + * **[:empty](http://docs.jquery.com/Selectors/empty)** Matches all elements that have no children (including text nodes). + * **[:has(selector)](http://docs.jquery.com/Selectors/has)** Matches elements which contain at least one element that matches the specified selector. + * **[:parent](http://docs.jquery.com/Selectors/parent)** Matches all elements that are parents - they have child elements, including text. +## Visibility Filters +_none_ +## Attribute Filters + * **[[attribute](http://docs.jquery.com/Selectors/attributeHas)]** Matches elements that have the specified attribute. + * **[[attribute=value](http://docs.jquery.com/Selectors/attributeEquals)]** Matches elements that have the specified attribute with a certain value. + * **[[attribute!=value](http://docs.jquery.com/Selectors/attributeNotEqual)]** Matches elements that don't have the specified attribute with a certain value. + * **[[attribute^=value](http://docs.jquery.com/Selectors/attributeStartsWith)]** Matches elements that have the specified attribute and it starts with a certain value. + * **[[attribute$=value](http://docs.jquery.com/Selectors/attributeEndsWith)]** Matches elements that have the specified attribute and it ends with a certain value. + * **[[attribute\*=value](http://docs.jquery.com/Selectors/attributeContains)]** Matches elements that have the specified attribute and it contains a certain value. + * **[[selector1](http://docs.jquery.com/Selectors/attributeMultiple)[selector2](selector2.md)[selectorN](selectorN.md)]** Matches elements that have the specified attribute and it contains a certain value. +## Child Filters + * **[:nth-child(index/even/odd/equation)](http://docs.jquery.com/Selectors/nthChild)** Matches all elements that are the nth-child of their parent or that are the parent's even or odd children. + * **[:first-child](http://docs.jquery.com/Selectors/firstChild)** Matches all elements that are the first child of their parent. + * **[:last-child](http://docs.jquery.com/Selectors/lastChild)** Matches all elements that are the last child of their parent. + * **[:only-child](http://docs.jquery.com/Selectors/onlyChild)** Matches all elements that are the only child of their parent. +## Forms + * **[:input](http://docs.jquery.com/Selectors/input)** Matches all input, textarea, select and button elements. + * **[:text](http://docs.jquery.com/Selectors/text)** Matches all input elements of type text. + * **[:password](http://docs.jquery.com/Selectors/password)** Matches all input elements of type password. + * **[:radio](http://docs.jquery.com/Selectors/radio)** Matches all input elements of type radio. + * **[:checkbox](http://docs.jquery.com/Selectors/checkbox)** Matches all input elements of type checkbox. + * **[:submit](http://docs.jquery.com/Selectors/submit)** Matches all input elements of type submit. + * **[:image](http://docs.jquery.com/Selectors/image)** Matches all input elements of type image. + * **[:reset](http://docs.jquery.com/Selectors/reset)** Matches all input elements of type reset. + * **[:button](http://docs.jquery.com/Selectors/button)** Matches all button elements and input elements of type button. + * **[:file](http://docs.jquery.com/Selectors/file)** Matches all input elements of type file. + * **[:hidden](http://docs.jquery.com/Selectors/hidden)** Matches all elements that are hidden, or input elements of type "hidden". +## Form Filters + * **[:enabled](http://docs.jquery.com/Selectors/enabled)** Matches all elements that are enabled. + * **[:disabled](http://docs.jquery.com/Selectors/disabled)** Matches all elements that are disabled. + * **[:checked](http://docs.jquery.com/Selectors/checked)** Matches all elements that are checked. + * **[:selected](http://docs.jquery.com/Selectors/selected)** Matches all elements that are selected. + +Read more at [Selectors](http://docs.jquery.com/Selectors) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/Traversing.md b/wiki/Traversing.md new file mode 100644 index 0000000..cc89f5b --- /dev/null +++ b/wiki/Traversing.md @@ -0,0 +1,34 @@ +## Example +``` +pq('div > p')->add('div > ul')->filter(':has(a)')->find('p:first')->nextAll()->andSelf()->... +``` +# Table of Contents + * [Filtering](#Filtering.md) + * [Finding](#Finding.md) + * [Chaining](#Chaining.md) +## Filtering + * **[eq](http://docs.jquery.com/Traversing/eq)**[($index)](http://docs.jquery.com/Traversing/eq) Reduce the set of matched elements to a single element. + * **[hasClass](http://docs.jquery.com/Traversing/hasClass)**[($class)](http://docs.jquery.com/Traversing/hasClass) Checks the current selection against a class and returns true, if at least one element of the selection has the given class. + * **[filter](http://docs.jquery.com/Traversing/filter)**[($expr)](http://docs.jquery.com/Traversing/filter) Removes all elements from the set of matched elements that do not match the specified expression(s). + * **[filter](http://docs.jquery.com/Traversing/filter)**[($fn)](http://docs.jquery.com/Traversing/filter) Removes all elements from the set of matched elements that does not match the specified function. + * **[is](http://docs.jquery.com/Traversing/is)**[($expr)](http://docs.jquery.com/Traversing/is) Checks the current selection against an expression and returns true, if at least one element of the selection fits the given expression. + * **[map](http://docs.jquery.com/Traversing/map)**[($callback)](http://docs.jquery.com/Traversing/map) Translate a set of elements in the jQuery object into another set of values in an array (which may, or may not, be elements). + * **[not](http://docs.jquery.com/Traversing/not)**[($expr)](http://docs.jquery.com/Traversing/not) Removes elements matching the specified expression from the set of matched elements. + * **[slice](http://docs.jquery.com/Traversing/slice)**[($start, $end)](http://docs.jquery.com/Traversing/slice) Selects a subset of the matched elements. +## Finding + * **[add](http://docs.jquery.com/Traversing/add)**[($expr)](http://docs.jquery.com/Traversing/add) Adds more elements, matched by the given expression, to the set of matched elements. + * **[children](http://docs.jquery.com/Traversing/children)**[($expr)](http://docs.jquery.com/Traversing/children) Get a set of elements containing all of the unique immediate children of each of the matched set of elements. + * **[contents](http://docs.jquery.com/Traversing/contents)**[()](http://docs.jquery.com/Traversing/contents) Find all the child nodes inside the matched elements (including text nodes), or the content document, if the element is an iframe. + * **[find](http://docs.jquery.com/Traversing/find)**[($expr)](http://docs.jquery.com/Traversing/find) Searches for all elements that match the specified expression. This method is a good way to find additional descendant elements with which to process. + * **[next](http://docs.jquery.com/Traversing/next)**[($expr)](http://docs.jquery.com/Traversing/next) Get a set of elements containing the unique next siblings of each of the given set of elements. + * **[nextAll](http://docs.jquery.com/Traversing/nextAll)**[($expr)](http://docs.jquery.com/Traversing/nextAll) Find all sibling elements after the current element. + * **[parent](http://docs.jquery.com/Traversing/parent)**[($expr)](http://docs.jquery.com/Traversing/parent) Get a set of elements containing the unique parents of the matched set of elements. + * **[parents](http://docs.jquery.com/Traversing/parents)**[($expr)](http://docs.jquery.com/Traversing/parents) Get a set of elements containing the unique ancestors of the matched set of elements (except for the root element). The matched elements can be filtered with an optional expression. + * **[prev](http://docs.jquery.com/Traversing/prev)**[($expr)](http://docs.jquery.com/Traversing/prev) Get a set of elements containing the unique previous siblings of each of the matched set of elements. + * **[prevAll](http://docs.jquery.com/Traversing/prevAll)**[($expr)](http://docs.jquery.com/Traversing/prevAll) Find all sibling elements before the current element. + * **[siblings](http://docs.jquery.com/Traversing/siblings)**[($expr)](http://docs.jquery.com/Traversing/siblings) Get a set of elements containing all of the unique siblings of each of the matched set of elements. Can be filtered with an optional expressions. +## Chaining + * **[andSelf](http://docs.jquery.com/Traversing/andSelf)**[()](http://docs.jquery.com/Traversing/andSelf) Add the previous selection to the current selection. + * **[end](http://docs.jquery.com/Traversing/end)**[()](http://docs.jquery.com/Traversing/end) Revert the most recent 'destructive' operation, changing the set of matched elements to its previous state (right before the destructive operation). + +Read more at [Traversing](http://docs.jquery.com/Traversing) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/Utilities.md b/wiki/Utilities.md new file mode 100644 index 0000000..b42720a --- /dev/null +++ b/wiki/Utilities.md @@ -0,0 +1,20 @@ +# Table of Contents + * [User Agent](#User_Agent.md) + * [Array and Object operations](#Array_and_Object_operations.md) + * [Test operations](#Test_operations.md) + * [String operations](#String_operations.md) +## User Agent +_none_ +## Array and Object operations + * **[phpQuery::each](http://docs.jquery.com/Utilities/jQuery.each)**[($object, $callback)](http://docs.jquery.com/Utilities/jQuery.each) A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. + * **[phpQuery::grep](http://docs.jquery.com/Utilities/jQuery.grep)**[($array, $callback, $invert)](http://docs.jquery.com/Utilities/jQuery.grep) Filter items out of an array, by using a filter function. + * **[phpQuery::makeArray](http://docs.jquery.com/Utilities/jQuery.makeArray)**[($obj)](http://docs.jquery.com/Utilities/jQuery.makeArray) Turns an array-like object into a true array. + * **[phpQuery::map](http://docs.jquery.com/Utilities/jQuery.map)**[($array, $callback)](http://docs.jquery.com/Utilities/jQuery.map) Translate all items in an array to another array of items. + * **[phpQuery::inArray](http://docs.jquery.com/Utilities/jQuery.inArray)**[($value, $array)](http://docs.jquery.com/Utilities/jQuery.inArray) Determine the index of the first parameter in the Array (-1 if not found). + * **[phpQuery::unique](http://docs.jquery.com/Utilities/jQuery.unique)**[($array)](http://docs.jquery.com/Utilities/jQuery.unique) Remove all duplicate elements from an array of elements. +## Test operations + * **[phpQuery::isFunction](http://docs.jquery.com/Utilities/jQuery.isFunction)**[($obj)](http://docs.jquery.com/Utilities/jQuery.isFunction) Determine if the parameter passed is a function. +## String operations + * **[phpQuery::trim](http://docs.jquery.com/Utilities/jQuery.trim)**[($str)](http://docs.jquery.com/Utilities/jQuery.trim) Remove the whitespace from the beginning and end of a string. + +Read more at [Utilities](http://docs.jquery.com/Utilities) section on [jQuery Documentation Site](http://docs.jquery.com/). \ No newline at end of file diff --git a/wiki/WebBrowser.md b/wiki/WebBrowser.md new file mode 100644 index 0000000..a4d4071 --- /dev/null +++ b/wiki/WebBrowser.md @@ -0,0 +1,37 @@ +**WebBrowser** is a phpQuery [plugin](http://code.google.com/p/phpquery/wiki/PluginsServerSide) that mimics behaviors of web browser. Thanks to that developer can simulate user's behavior inside a PHP script. + +## Supported + * Link navigation (click event) + * Form navigation (submit event) + * Cookies (thought [Zend\_Http\_CookieJar](http://framework.zend.com/manual/en/zend.http.cookies.html)) + * Relative links + * document.location (not an object, yet) + +## Use cases + * Fill forms and submit them easly + * Login to secure pages and collect content + * Write test cases reproducing browsing proccess + +## Example 1 +Adding web browser functionality to existing phpQuery object and submiting the form. +``` +->WebBrowser('callback')->find('form')->submit()->... +``` + +## Example 2 +Querying Google against "search phrase": +``` +require_once('phpQuery/phpQuery.php'); +phpQuery::browserGet('http://www.google.com/', 'success1'); +function success1($browser) { + $browser + ->WebBrowser('success2') + ->find('input[name=q]') + ->val('search phrase') + ->parents('form') + ->submit(); +} +function success2($browser) { + print $browser; +} +``` \ No newline at end of file diff --git a/wiki/jQueryDifferences.md b/wiki/jQueryDifferences.md new file mode 100644 index 0000000..4cc32f2 --- /dev/null +++ b/wiki/jQueryDifferences.md @@ -0,0 +1 @@ +Renamed to [jQueryPortingState](http://code.google.com/p/phpquery/wiki/jQueryPortingState). \ No newline at end of file diff --git a/wiki/jQueryHelpers.md b/wiki/jQueryHelpers.md new file mode 100644 index 0000000..2df052a --- /dev/null +++ b/wiki/jQueryHelpers.md @@ -0,0 +1,3 @@ +jQuery helper libraries written in PHP + * [jquery-php](http://code.google.com/p/jquery-php/) + * [PQuery](http://www.ngcoders.com/php/pquery-php-and-jquery) \ No newline at end of file diff --git a/wiki/jQueryPortingState.md b/wiki/jQueryPortingState.md new file mode 100644 index 0000000..e3e3cfc --- /dev/null +++ b/wiki/jQueryPortingState.md @@ -0,0 +1,29 @@ +phpQuery is almost a full port of the [jQuery JavaScript Library](http://jquery.com/). + +## Ported Sections + 1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) + 1. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) + 1. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) + 1. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) + 1. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) + 1. [Events](http://code.google.com/p/phpquery/wiki/Events) + 1. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) + 1. [Plugin ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) + +## Additional methods +phpQuery features many additional methods comparing to jQuery: + * htmlOuter() + * xml() + * xmlOuter() + * markup() + * markupOuter() + * getString() + * reverse() + * contentsUnwrap() + * switchWith() + * all from [PHPSupport](http://code.google.com/p/phpquery/wiki/PHPSupport) + * all from [Basic](http://code.google.com/p/phpquery/wiki/Basic) + * all from [MultiDocumentSupport](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) + +## Other Differences + * [Server Side Events](http://code.google.com/p/phpquery/wiki/Events?ts=1225458859&updated=Events#Server_Side_Events) \ No newline at end of file diff --git a/wiki/jQueryServer.md b/wiki/jQueryServer.md new file mode 100644 index 0000000..3bbec90 --- /dev/null +++ b/wiki/jQueryServer.md @@ -0,0 +1,16 @@ +**jQueryServer** is a jQuery plugin giving unobstrusive, client-side bindings to server-side implementation of jQuery. + +## Example scenario + 1. Connect to server and make an [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request to somewhere ([crossdomain allowed](http://code.google.com/p/phpquery/wiki/CrossDomainAjax)) + 1. Do some manipulations, you can even trigger a [server-side event](http://code.google.com/p/phpquery/wiki/Events#Server_Side_Events) + 1. Get processed date back to the browser + +## Example code +``` +$.server({url: 'http://somesite.com'}) + .find('.my-class') + .client(function(response){ + $('.destination').html(response); +}); +``` +Since version **0.5.1** (this is **not** phpQuery release version number) there is a support for config file which **authorizes** [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) hosts and referers. \ No newline at end of file diff --git a/wiki/jQueryServerSidePorts.md b/wiki/jQueryServerSidePorts.md new file mode 100644 index 0000000..5a6eeb5 --- /dev/null +++ b/wiki/jQueryServerSidePorts.md @@ -0,0 +1,6 @@ +jQuery ports to server-side languages: + * **PHP** - [phpQuery](http://code.google.com/p/phpquery/) + * **ActionScript** - [as3query](http://tech.nitoyon.com/blog/2008/01/as3query_alpha.html) + * **Ruby** - [hpricot](http://code.whytheluckystiff.net/hpricot/) + * **Perl** - [pQuery](http://search.cpan.org/~ingy/pQuery/lib/pQuery.pm) + * **Python** - [PyQuery](http://pypi.python.org/pypi/pyquery) \ No newline at end of file diff --git a/wiki/test.md b/wiki/test.md new file mode 100644 index 0000000..34c92c2 --- /dev/null +++ b/wiki/test.md @@ -0,0 +1 @@ +lorem ipsum \ No newline at end of file From 13a34f656d061a4fdcae2603a95591178123a8dd Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Sat, 2 Jan 2016 11:02:01 -0700 Subject: [PATCH 13/59] renamed Manual to README, removed test --- wiki/{Manual.md => README.md} | 0 wiki/test.md | 1 - 2 files changed, 1 deletion(-) rename wiki/{Manual.md => README.md} (100%) delete mode 100644 wiki/test.md diff --git a/wiki/Manual.md b/wiki/README.md similarity index 100% rename from wiki/Manual.md rename to wiki/README.md diff --git a/wiki/test.md b/wiki/test.md deleted file mode 100644 index 34c92c2..0000000 --- a/wiki/test.md +++ /dev/null @@ -1 +0,0 @@ -lorem ipsum \ No newline at end of file From 7aa44be9f319e7a0abb720b4f116c9d63ecbb130 Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Sat, 2 Jan 2016 11:09:22 -0700 Subject: [PATCH 14/59] fixed links back to old google code wiki --- wiki/Ajax.md | 2 +- wiki/Basics.md | 4 ++-- wiki/Callbacks.md | 2 +- wiki/Events.md | 2 +- wiki/LibrarySections.md | 2 +- wiki/PHPSupport.md | 6 +++--- wiki/README.md | 37 ++++++++++++++++++------------------- wiki/WebBrowser.md | 2 +- wiki/jQueryDifferences.md | 2 +- wiki/jQueryPortingState.md | 22 +++++++++++----------- wiki/jQueryServer.md | 4 ++-- 11 files changed, 42 insertions(+), 43 deletions(-) diff --git a/wiki/Ajax.md b/wiki/Ajax.md index 3da8e25..fe9a24e 100644 --- a/wiki/Ajax.md +++ b/wiki/Ajax.md @@ -13,7 +13,7 @@ Ajax, standing for _Asynchronous JavaScript and XML_ is combination of HTTP Clie **phpQuery** also offers such functionality, making use of solid quality [Zend\_Http\_Client](http://framework.zend.com/manual/en/zend.http.html). Unfortunately requests aren't asynchronous, but nothing is impossible. For today, instead of [XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest) you always get Zend\_Http\_Client instance. API unification is [planned](http://code.google.com/p/phpquery/issues/detail?id=44). ## Cross Domain Ajax -For security reasons, by default **phpQuery** doesn't allow connections to hosts other than actual `$_SERVER['HTTP_HOST']`. Developer needs to grant rights to other hosts before making an [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. +For security reasons, by default **phpQuery** doesn't allow connections to hosts other than actual `$_SERVER['HTTP_HOST']`. Developer needs to grant rights to other hosts before making an [Ajax](Ajax.md) request. There are 2 methods for allowing other hosts * phpQuery::**ajaxAllowURL**($url) diff --git a/wiki/Basics.md b/wiki/Basics.md index a942b59..dedd006 100644 --- a/wiki/Basics.md +++ b/wiki/Basics.md @@ -13,11 +13,11 @@ $ul = pq('ul'); * phpQuery::**newDocumentHTML**($html, $charset = 'utf-8') * phpQuery::**newDocumentXHTML**($html, $charset = 'utf-8') * phpQuery::**newDocumentXML**($html, $charset = 'utf-8') - * phpQuery::**newDocumentPHP**($html, $contentType = null) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) + * phpQuery::**newDocumentPHP**($html, $contentType = null) Read more about it on [PHPSupport page](PHPSupport.md) * phpQuery::**newDocumentFileHTML**($file, $charset = 'utf-8') * phpQuery::**newDocumentFileXHTML**($file, $charset = 'utf-8') * phpQuery::**newDocumentFileXML**($file, $charset = 'utf-8') - * phpQuery::**newDocumentFilePHP**($file, $contentType) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) + * phpQuery::**newDocumentFilePHP**($file, $contentType) Read more about it on [PHPSupport page](PHPSupport.md) ## pq function **`pq($param, $context = null);`** diff --git a/wiki/Callbacks.md b/wiki/Callbacks.md index 8c6645d..856bccf 100644 --- a/wiki/Callbacks.md +++ b/wiki/Callbacks.md @@ -6,7 +6,7 @@ * [CallbackReference class](#CallbackReference.md) * [Scope Pseudo-Inheritance](#Scope_Pseudo_Inheritance.md) ## What are callbacks -Callbacks are functions _called back_ by other functions in proper moment (eg on [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request error). +Callbacks are functions _called back_ by other functions in proper moment (eg on [Ajax](Ajax.md) request error). In **JavaScript** this pattern can be very flexible due to [Closures](http://en.wikipedia.org/wiki/Closure_(computer_science)) support, which can be inline (no code break) and inherits scope (no need to passing params). diff --git a/wiki/Events.md b/wiki/Events.md index 65ef2b1..0fd4f4d 100644 --- a/wiki/Events.md +++ b/wiki/Events.md @@ -18,7 +18,7 @@ function submitHandler($e) { ## Server Side Events phpQuery support **server-side** events, same as jQuery handle client-side ones. On server there isn't, of course, events such as _mouseover_ (but they can be triggered). -By default, phpQuery automatically fires up only **change** event for form elements. If you load WebBrowser plugin, **submit** and **click** will be handled properly - eg submitting form with inputs' data to action URL via new [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. +By default, phpQuery automatically fires up only **change** event for form elements. If you load WebBrowser plugin, **submit** and **click** will be handled properly - eg submitting form with inputs' data to action URL via new [Ajax](Ajax.md) request. $this (`this` in JS) context for handler scope **isn't available**. You have to use one of following manually: * $event->**target** diff --git a/wiki/LibrarySections.md b/wiki/LibrarySections.md index d6a3885..3d323e3 100644 --- a/wiki/LibrarySections.md +++ b/wiki/LibrarySections.md @@ -1 +1 @@ -Renamed to [Manual](http://code.google.com/p/phpquery/wiki/Manual). \ No newline at end of file +Renamed to [Manual](Manual.md). \ No newline at end of file diff --git a/wiki/PHPSupport.md b/wiki/PHPSupport.md index 95d00a0..f5e9987 100644 --- a/wiki/PHPSupport.md +++ b/wiki/PHPSupport.md @@ -1,11 +1,11 @@ -Although **phpQuery** is a [jQuery port](http://code.google.com/p/phpquery/wiki/jQueryPortingState), there is extensive PHP-specific support. +Although **phpQuery** is a [jQuery port](jQueryPortingState.md), there is extensive PHP-specific support. # Table of Contents * [Class Interfaces](#Class_Interfaces.md) * [Iterator Interface](#Iterator.md) * [ArrayAccess](#Array_Access.md) * [Countable Interface](#Countable.md) - * [Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) + * [Callbacks](Callbacks.md) * [PHP Code Support](#PHP_Code_Support.md) * [Opening PHP files as DOM](#Opening_PHP_files_as_DOM.md) * [Inputting PHP code](#Inputting_PHP_code.md) @@ -42,7 +42,7 @@ If used to do `count($something)` you can still do this that way, instead of eg print count(pq('ul:first > li')); ``` ## Callbacks -There is a special [Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) wiki section, to which you should refer to. +There is a special [Callbacks](Callbacks.md) wiki section, to which you should refer to. ## PHP Code Support #### Opening PHP files as DOM PHP files can be opened using **phpQuery::newDocumentPHP($markup)** or **phpQuery::newDocumentFilePHP($file)**. Such files are visible as DOM, where: diff --git a/wiki/README.md b/wiki/README.md index 8eb8868..10f5684 100644 --- a/wiki/README.md +++ b/wiki/README.md @@ -1,21 +1,20 @@ - 1. [Basics](http://code.google.com/p/phpquery/wiki/Basics) - 1. [Ported jQuery sections](http://code.google.com/p/phpquery/wiki/jQueryPortingState) - 1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) - 1. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) - 1. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) - 1. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) - 1. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) - 1. [Events](http://code.google.com/p/phpquery/wiki/Events) - 1. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) - 1. [Plugin ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) - 1. [PHP Support](http://code.google.com/p/phpquery/wiki/PHPSupport) - 1. [Command Line Interface](http://code.google.com/p/phpquery/wiki/CommandLineInterface) - 1. [Multi document support](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) - 1. [Plugins](http://code.google.com/p/phpquery/wiki/PluginsServerSide) - 1. [WebBrowser](http://code.google.com/p/phpquery/wiki/WebBrowser) - 1. [Scripts](http://code.google.com/p/phpquery/wiki/ScriptsPlugin) - 1. [jQueryServer](http://code.google.com/p/phpquery/wiki/jQueryServer) - 1. [Debugging](http://code.google.com/p/phpquery/wiki/Debugging) + 1. [Basics](Basics.md) + 1. [Ported jQuery sections](jQueryPortingState.md) + 1. [Selectors](Selectors.md) + 1. [Attributes](Attributes.md) + 1. [Traversing](Traversing.md) + 1. [Manipulation](Manipulation.md) + 1. [Ajax](Ajax.md) + 1. [Events](Events.md) + 1. [Utilities](Utilities.md) + 1. [Plugin ports](PluginsClientSidePorts.md) + 1. [PHP Support](PHPSupport.md) + 1. [Command Line Interface](CommandLineInterface.md) + 1. [Multi document support](MultiDocumentSupport.md) + 1. [Plugins](PluginsServerSide.md) + 1. [WebBrowser](WebBrowser.md) + 1. [Scripts](ScriptsPlugin.md) + 1. [jQueryServer](jQueryServer.md) + 1. [Debugging](Debugging.md) 1. Bootstrap file -**[API Reference](http://meta20.net/phpquery-api/)** is also available. \ No newline at end of file diff --git a/wiki/WebBrowser.md b/wiki/WebBrowser.md index a4d4071..6b189c1 100644 --- a/wiki/WebBrowser.md +++ b/wiki/WebBrowser.md @@ -1,4 +1,4 @@ -**WebBrowser** is a phpQuery [plugin](http://code.google.com/p/phpquery/wiki/PluginsServerSide) that mimics behaviors of web browser. Thanks to that developer can simulate user's behavior inside a PHP script. +**WebBrowser** is a phpQuery [plugin](PluginsServerSide.md) that mimics behaviors of web browser. Thanks to that developer can simulate user's behavior inside a PHP script. ## Supported * Link navigation (click event) diff --git a/wiki/jQueryDifferences.md b/wiki/jQueryDifferences.md index 4cc32f2..2d87ca9 100644 --- a/wiki/jQueryDifferences.md +++ b/wiki/jQueryDifferences.md @@ -1 +1 @@ -Renamed to [jQueryPortingState](http://code.google.com/p/phpquery/wiki/jQueryPortingState). \ No newline at end of file +Renamed to [jQueryPortingState](jQueryPortingState.md). \ No newline at end of file diff --git a/wiki/jQueryPortingState.md b/wiki/jQueryPortingState.md index e3e3cfc..d4d75b5 100644 --- a/wiki/jQueryPortingState.md +++ b/wiki/jQueryPortingState.md @@ -1,14 +1,14 @@ phpQuery is almost a full port of the [jQuery JavaScript Library](http://jquery.com/). ## Ported Sections - 1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) - 1. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) - 1. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) - 1. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) - 1. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) - 1. [Events](http://code.google.com/p/phpquery/wiki/Events) - 1. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) - 1. [Plugin ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) + 1. [Selectors](Selectors.md) + 1. [Attributes](Attributes.md) + 1. [Traversing](Traversing.md) + 1. [Manipulation](Manipulation.md) + 1. [Ajax](Ajax.md) + 1. [Events](Events.md) + 1. [Utilities](Utilities.md) + 1. [Plugin ports](PluginsClientSidePorts.md) ## Additional methods phpQuery features many additional methods comparing to jQuery: @@ -21,9 +21,9 @@ phpQuery features many additional methods comparing to jQuery: * reverse() * contentsUnwrap() * switchWith() - * all from [PHPSupport](http://code.google.com/p/phpquery/wiki/PHPSupport) - * all from [Basic](http://code.google.com/p/phpquery/wiki/Basic) - * all from [MultiDocumentSupport](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) + * all from [PHPSupport](PHPSupport.md) + * all from [Basic](Basic.md) + * all from [MultiDocumentSupport](MultiDocumentSupport.md) ## Other Differences * [Server Side Events](http://code.google.com/p/phpquery/wiki/Events?ts=1225458859&updated=Events#Server_Side_Events) \ No newline at end of file diff --git a/wiki/jQueryServer.md b/wiki/jQueryServer.md index 3bbec90..3be1b27 100644 --- a/wiki/jQueryServer.md +++ b/wiki/jQueryServer.md @@ -1,7 +1,7 @@ **jQueryServer** is a jQuery plugin giving unobstrusive, client-side bindings to server-side implementation of jQuery. ## Example scenario - 1. Connect to server and make an [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request to somewhere ([crossdomain allowed](http://code.google.com/p/phpquery/wiki/CrossDomainAjax)) + 1. Connect to server and make an [Ajax](Ajax.md) request to somewhere ([crossdomain allowed](CrossDomainAjax.md)) 1. Do some manipulations, you can even trigger a [server-side event](http://code.google.com/p/phpquery/wiki/Events#Server_Side_Events) 1. Get processed date back to the browser @@ -13,4 +13,4 @@ $.server({url: 'http://somesite.com'}) $('.destination').html(response); }); ``` -Since version **0.5.1** (this is **not** phpQuery release version number) there is a support for config file which **authorizes** [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) hosts and referers. \ No newline at end of file +Since version **0.5.1** (this is **not** phpQuery release version number) there is a support for config file which **authorizes** [Ajax](Ajax.md) hosts and referers. \ No newline at end of file From 3fd928e9b153b3fe0104e7be4ca0356f5c580533 Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Sat, 2 Jan 2016 11:19:16 -0700 Subject: [PATCH 15/59] added link to manual from main README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f9c33f7..6287d32 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ I've gathered some fix and new features here and there, as will keep looking for * https://github.com/kevee/phpquery (include php-css-parser) * https://github.com/lucassouza1/phpquery +## Manual + +* [Manual](wiki/README.md) imported from http://code.google.com/p/phpquery/wiki + ## Extracts from fmorrow README.md: ### Whats phpQuery? From 88995d85179f45ce84f3655b7b06d8cfacb9dc37 Mon Sep 17 00:00:00 2001 From: Steve Meyers Date: Sat, 2 Jan 2016 11:19:33 -0700 Subject: [PATCH 16/59] added license information to wiki README.md --- wiki/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wiki/README.md b/wiki/README.md index 10f5684..79c4866 100644 --- a/wiki/README.md +++ b/wiki/README.md @@ -18,3 +18,7 @@ 1. [Debugging](Debugging.md) 1. Bootstrap file + +This manual is copied from http://code.google.com/p/phpquery/wiki/Manual + +The wiki was downloaded from the [Google Code source repository for phpQuery](https://code.google.com/p/phpquery/source/browse/#svn%2Fwiki), which is under the MIT License. From 6c13c01b121dc14b1d3bf170ebe793127e83b18d Mon Sep 17 00:00:00 2001 From: lauripiisang Date: Wed, 27 Jan 2016 17:46:49 +0200 Subject: [PATCH 17/59] Fixed getString(0) and getStrings(0) null check --- phpQuery/phpQuery/phpQueryObject.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index 2308540..febb53a 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -502,7 +502,7 @@ public function get($index = null, $callback1 = null, $callback2 = null, $callba * @todo maybe other name... */ public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index) + if ($index != null && is_int($index)) $return = $this->eq($index)->text(); else { $return = array(); @@ -529,7 +529,7 @@ public function getString($index = null, $callback1 = null, $callback2 = null, $ * @todo maybe other name... */ public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index) + if ($index != null && is_int($index)) $return = $this->eq($index)->text(); else { $return = array(); From 4e27b079112b08ad75198fb3df5a3438d5a0c209 Mon Sep 17 00:00:00 2001 From: lauripiisang Date: Thu, 28 Jan 2016 10:33:01 +0200 Subject: [PATCH 18/59] fixed null check - implicit conversion made 0 == null - now checking for exact null instead --- phpQuery/phpQuery/phpQueryObject.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index febb53a..51087a4 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -502,7 +502,7 @@ public function get($index = null, $callback1 = null, $callback2 = null, $callba * @todo maybe other name... */ public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index != null && is_int($index)) + if (!is_null($index) && is_int($index)) $return = $this->eq($index)->text(); else { $return = array(); @@ -529,7 +529,7 @@ public function getString($index = null, $callback1 = null, $callback2 = null, $ * @todo maybe other name... */ public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index != null && is_int($index)) + if (!is_null($index) && is_int($index)) $return = $this->eq($index)->text(); else { $return = array(); From 71a64a3064c38a193e085f790dc7133a352abe68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A5=BF=E9=9B=86?= Date: Thu, 24 Mar 2016 10:45:21 +0800 Subject: [PATCH 19/59] fixed makeArray() --- phpQuery/phpQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpQuery/phpQuery.php b/phpQuery/phpQuery.php index 08f22fc..be094d7 100644 --- a/phpQuery/phpQuery.php +++ b/phpQuery/phpQuery.php @@ -998,7 +998,7 @@ public static function getDOMDocument($source) { * @return unknown_type * @link http://docs.jquery.com/Utilities/jQuery.makeArray */ - public static function makeArray($obj) { + public static function makeArray($object) { $array = array(); if (is_object($object) && $object instanceof DOMNODELIST) { foreach($object as $value) From ec73fc88a7eef9da7361d0a58f17978d320f5e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A5=BF=E9=9B=86?= Date: Thu, 24 Mar 2016 12:33:56 +0800 Subject: [PATCH 20/59] fixed bugs --- phpQuery/phpQuery/DOMDocumentWrapper.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phpQuery/phpQuery/DOMDocumentWrapper.php b/phpQuery/phpQuery/DOMDocumentWrapper.php index a58b1f3..aae5ee0 100644 --- a/phpQuery/phpQuery/DOMDocumentWrapper.php +++ b/phpQuery/phpQuery/DOMDocumentWrapper.php @@ -314,8 +314,6 @@ protected function isXML($markup) { } protected function contentTypeToArray($contentType) { - $test = null; - $test = $matches = explode(';', trim(strtolower($contentType))); if (isset($matches[1])) { $matches[1] = explode('=', $matches[1]); @@ -351,7 +349,7 @@ protected function charsetFromHTML($markup) { return $contentType[1]; } protected function charsetFromXML($markup) { - $matches; + $matches = array(); // find declaration preg_match('@<'.'?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches From 41ecce64209e19a78e7e72c7338f37d55fec966b Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 07:41:58 -0600 Subject: [PATCH 21/59] Closes #1. Merged https://github.com/kevee/phpquery/tree/phpquery-css. --- phpQuery/CSSParser/CSSParser.php | 465 +++++++++++++ phpQuery/CSSParser/README.md | 376 ++++++++++ phpQuery/CSSParser/lib/CSSList.php | 236 +++++++ phpQuery/CSSParser/lib/CSSProperties.php | 124 ++++ phpQuery/CSSParser/lib/CSSRule.php | 135 ++++ phpQuery/CSSParser/lib/CSSRuleSet.php | 653 ++++++++++++++++++ phpQuery/CSSParser/lib/CSSValue.php | 110 +++ phpQuery/CSSParser/lib/CSSValueList.php | 92 +++ .../tests/CSSDeclarationBlockTest.php | 223 ++++++ phpQuery/CSSParser/tests/CSSParserTests.php | 277 ++++++++ phpQuery/CSSParser/tests/files/-tobedone.css | 7 + phpQuery/CSSParser/tests/files/atrules.css | 10 + phpQuery/CSSParser/tests/files/colortest.css | 10 + .../tests/files/create-shorthands.css | 7 + .../tests/files/expand-shorthands.css | 7 + phpQuery/CSSParser/tests/files/functions.css | 22 + phpQuery/CSSParser/tests/files/ie.css | 6 + phpQuery/CSSParser/tests/files/important.css | 8 + phpQuery/CSSParser/tests/files/nested.css | 17 + phpQuery/CSSParser/tests/files/slashed.css | 4 + .../CSSParser/tests/files/specificity.css | 7 + phpQuery/CSSParser/tests/files/unicode.css | 12 + phpQuery/CSSParser/tests/files/values.css | 11 + phpQuery/CSSParser/tests/files/whitespace.css | 3 + phpQuery/CSSParser/tests/quickdump.php | 15 + phpQuery/phpQuery.php | 1 + phpQuery/phpQuery/phpQueryObject.php | 144 +++- 27 files changed, 2975 insertions(+), 7 deletions(-) create mode 100755 phpQuery/CSSParser/CSSParser.php create mode 100755 phpQuery/CSSParser/README.md create mode 100755 phpQuery/CSSParser/lib/CSSList.php create mode 100755 phpQuery/CSSParser/lib/CSSProperties.php create mode 100755 phpQuery/CSSParser/lib/CSSRule.php create mode 100755 phpQuery/CSSParser/lib/CSSRuleSet.php create mode 100755 phpQuery/CSSParser/lib/CSSValue.php create mode 100755 phpQuery/CSSParser/lib/CSSValueList.php create mode 100755 phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php create mode 100755 phpQuery/CSSParser/tests/CSSParserTests.php create mode 100755 phpQuery/CSSParser/tests/files/-tobedone.css create mode 100755 phpQuery/CSSParser/tests/files/atrules.css create mode 100755 phpQuery/CSSParser/tests/files/colortest.css create mode 100755 phpQuery/CSSParser/tests/files/create-shorthands.css create mode 100755 phpQuery/CSSParser/tests/files/expand-shorthands.css create mode 100755 phpQuery/CSSParser/tests/files/functions.css create mode 100755 phpQuery/CSSParser/tests/files/ie.css create mode 100755 phpQuery/CSSParser/tests/files/important.css create mode 100755 phpQuery/CSSParser/tests/files/nested.css create mode 100755 phpQuery/CSSParser/tests/files/slashed.css create mode 100755 phpQuery/CSSParser/tests/files/specificity.css create mode 100755 phpQuery/CSSParser/tests/files/unicode.css create mode 100755 phpQuery/CSSParser/tests/files/values.css create mode 100755 phpQuery/CSSParser/tests/files/whitespace.css create mode 100755 phpQuery/CSSParser/tests/quickdump.php diff --git a/phpQuery/CSSParser/CSSParser.php b/phpQuery/CSSParser/CSSParser.php new file mode 100755 index 0000000..5477927 --- /dev/null +++ b/phpQuery/CSSParser/CSSParser.php @@ -0,0 +1,465 @@ +sText = $sText; + $this->iCurrentPosition = 0; + $this->setCharset($sDefaultCharset); + } + + public function setCharset($sCharset) { + $this->sCharset = $sCharset; + $this->iLength = mb_strlen($this->sText, $this->sCharset); + } + + public function getCharset() { + return $this->sCharset; + } + + public function parse() { + $oResult = new CSSDocument(); + $this->parseDocument($oResult); + return $oResult; + } + + private function parseDocument(CSSDocument $oDocument) { + $this->consumeWhiteSpace(); + $this->parseList($oDocument, true); + } + + private function parseList(CSSList $oList, $bIsRoot = false) { + while(!$this->isEnd()) { + if($this->comes('@')) { + $oList->append($this->parseAtRule()); + } else if($this->comes('}')) { + $this->consume('}'); + if($bIsRoot) { + throw new Exception("Unopened {"); + } else { + return; + } + } else { + $oList->append($this->parseSelector()); + } + $this->consumeWhiteSpace(); + } + if(!$bIsRoot) { + throw new Exception("Unexpected end of document"); + } + } + + private function parseAtRule() { + $this->consume('@'); + $sIdentifier = $this->parseIdentifier(); + $this->consumeWhiteSpace(); + if($sIdentifier === 'media') { + $oResult = new CSSMediaQuery(); + $oResult->setQuery(trim($this->consumeUntil('{'))); + $this->consume('{'); + $this->consumeWhiteSpace(); + $this->parseList($oResult); + return $oResult; + } else if($sIdentifier === 'import') { + $oLocation = $this->parseURLValue(); + $this->consumeWhiteSpace(); + $sMediaQuery = null; + if(!$this->comes(';')) { + $sMediaQuery = $this->consumeUntil(';'); + } + $this->consume(';'); + return new CSSImport($oLocation, $sMediaQuery); + } else if($sIdentifier === 'charset') { + $sCharset = $this->parseStringValue(); + $this->consumeWhiteSpace(); + $this->consume(';'); + $this->setCharset($sCharset->getString()); + return new CSSCharset($sCharset); + } else { + //Unknown other at rule (font-face or such) + $this->consume('{'); + $this->consumeWhiteSpace(); + $oAtRule = new CSSAtRule($sIdentifier); + $this->parseRuleSet($oAtRule); + return $oAtRule; + } + } + + private function parseIdentifier($bAllowFunctions = true) { + $sResult = $this->parseCharacter(true); + if($sResult === null) { + throw new Exception("Identifier expected, got {$this->peek(5)}"); + } + $sCharacter; + while(($sCharacter = $this->parseCharacter(true)) !== null) { + $sResult .= $sCharacter; + } + if($bAllowFunctions && $this->comes('(')) { + $this->consume('('); + $sResult = new CSSFunction($sResult, $this->parseValue(array('=', ','))); + $this->consume(')'); + } + return $sResult; + } + + private function parseStringValue() { + $sBegin = $this->peek(); + $sQuote = null; + if($sBegin === "'") { + $sQuote = "'"; + } else if($sBegin === '"') { + $sQuote = '"'; + } + if($sQuote !== null) { + $this->consume($sQuote); + } + $sResult = ""; + $sContent = null; + if($sQuote === null) { + //Unquoted strings end in whitespace or with braces, brackets, parentheses + while(!preg_match('/[\\s{}()<>\\[\\]]/isu', $this->peek())) { + $sResult .= $this->parseCharacter(false); + } + } else { + while(!$this->comes($sQuote)) { + $sContent = $this->parseCharacter(false); + if($sContent === null) { + throw new Exception("Non-well-formed quoted string {$this->peek(3)}"); + } + $sResult .= $sContent; + } + $this->consume($sQuote); + } + return new CSSString($sResult); + } + + private function parseCharacter($bIsForIdentifier) { + if($this->peek() === '\\') { + $this->consume('\\'); + if($this->comes('\n') || $this->comes('\r')) { + return ''; + } + $aMatches; + if(preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) { + return $this->consume(1); + } + $sUnicode = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u'); + if(mb_strlen($sUnicode, $this->sCharset) < 6) { + //Consume whitespace after incomplete unicode escape + if(preg_match('/\\s/isSu', $this->peek())) { + if($this->comes('\r\n')) { + $this->consume(2); + } else { + $this->consume(1); + } + } + } + $iUnicode = intval($sUnicode, 16); + $sUtf32 = ""; + for($i=0;$i<4;$i++) { + $sUtf32 .= chr($iUnicode & 0xff); + $iUnicode = $iUnicode >> 8; + } + return iconv('utf-32le', $this->sCharset, $sUtf32); + } + if($bIsForIdentifier) { + if(preg_match('/[a-zA-Z0-9]|-|_/u', $this->peek()) === 1) { + return $this->consume(1); + } else if(ord($this->peek()) > 0xa1) { + return $this->consume(1); + } else { + return null; + } + } else { + return $this->consume(1); + } + // Does not reach here + return null; + } + + private function parseSelector() { + $oResult = new CSSDeclarationBlock(); + $oResult->setSelector($this->consumeUntil('{')); + $this->consume('{'); + $this->consumeWhiteSpace(); + $this->parseRuleSet($oResult); + return $oResult; + } + + private function parseRuleSet($oRuleSet) { + while(!$this->comes('}')) { + $oRuleSet->addRule($this->parseRule()); + $this->consumeWhiteSpace(); + } + $this->consume('}'); + } + + private function parseRule() { + $oRule = new CSSRule($this->parseIdentifier()); + $this->consumeWhiteSpace(); + $this->consume(':'); + $oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule())); + $oRule->setValue($oValue); + if($this->comes('!')) { + $this->consume('!'); + $this->consumeWhiteSpace(); + $sImportantMarker = $this->consume(strlen('important')); + if(mb_convert_case($sImportantMarker, MB_CASE_LOWER) !== 'important') { + throw new Exception("! was followed by “".$sImportantMarker."”. Expected “important”"); + } + $oRule->setIsImportant(true); + } + if($this->comes(';')) { + $this->consume(';'); + } + return $oRule; + } + + private function parseValue($aListDelimiters) { + $aStack = array(); + $this->consumeWhiteSpace(); + while(!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')'))) { + if(count($aStack) > 0) { + $bFoundDelimiter = false; + foreach($aListDelimiters as $sDelimiter) { + if($this->comes($sDelimiter)) { + array_push($aStack, $this->consume($sDelimiter)); + $this->consumeWhiteSpace(); + $bFoundDelimiter = true; + break; + } + } + if(!$bFoundDelimiter) { + //Whitespace was the list delimiter + array_push($aStack, ' '); + } + } + array_push($aStack, $this->parsePrimitiveValue()); + $this->consumeWhiteSpace(); + } + foreach($aListDelimiters as $sDelimiter) { + if(count($aStack) === 1) { + return $aStack[0]; + } + $iStartPosition = null; + while(($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) { + $iLength = 2; //Number of elements to be joined + for($i=$iStartPosition+2;$iaddListComponent($aStack[$i]); + } + array_splice($aStack, $iStartPosition-1, $iLength*2-1, array($oList)); + } + } + return $aStack[0]; + } + + private static function listDelimiterForRule($sRule) { + if(preg_match('/^font($|-)/', $sRule)) { + return array(',', '/', ' '); + } + return array(',', ' ', '/'); + } + + private function parsePrimitiveValue() { + $oValue = null; + $this->consumeWhiteSpace(); + if(is_numeric($this->peek()) || (($this->comes('-') || $this->comes('.')) && is_numeric($this->peek(1, 1)))) { + $oValue = $this->parseNumericValue(); + } else if($this->comes('#') || $this->comes('rgb') || $this->comes('hsl')) { + $oValue = $this->parseColorValue(); + } else if($this->comes('url')){ + $oValue = $this->parseURLValue(); + } else if($this->comes("'") || $this->comes('"')){ + $oValue = $this->parseStringValue(); + } else { + $oValue = $this->parseIdentifier(); + } + $this->consumeWhiteSpace(); + return $oValue; + } + + private function parseNumericValue($bForColor = false) { + $sSize = ''; + if($this->comes('-')) { + $sSize .= $this->consume('-'); + } + while(is_numeric($this->peek()) || $this->comes('.')) { + if($this->comes('.')) { + $sSize .= $this->consume('.'); + } else { + $sSize .= $this->consume(1); + } + } + $fSize = floatval($sSize); + $sUnit = null; + if($this->comes('%')) { + $sUnit = $this->consume('%'); + } else if($this->comes('em')) { + $sUnit = $this->consume('em'); + } else if($this->comes('ex')) { + $sUnit = $this->consume('ex'); + } else if($this->comes('px')) { + $sUnit = $this->consume('px'); + } else if($this->comes('deg')) { + $sUnit = $this->consume('deg'); + } else if($this->comes('s')) { + $sUnit = $this->consume('s'); + } else if($this->comes('cm')) { + $sUnit = $this->consume('cm'); + } else if($this->comes('pt')) { + $sUnit = $this->consume('pt'); + } else if($this->comes('in')) { + $sUnit = $this->consume('in'); + } else if($this->comes('pc')) { + $sUnit = $this->consume('pc'); + } else if($this->comes('cm')) { + $sUnit = $this->consume('cm'); + } else if($this->comes('mm')) { + $sUnit = $this->consume('mm'); + } + return new CSSSize($fSize, $sUnit, $bForColor); + } + + private function parseColorValue() { + $aColor = array(); + if($this->comes('#')) { + $this->consume('#'); + $sValue = $this->parseIdentifier(false); + if(mb_strlen($sValue, $this->sCharset) === 3) { + $sValue = $sValue[0].$sValue[0].$sValue[1].$sValue[1].$sValue[2].$sValue[2]; + } + $aColor = array('r' => new CSSSize(intval($sValue[0].$sValue[1], 16), null, true), 'g' => new CSSSize(intval($sValue[2].$sValue[3], 16), null, true), 'b' => new CSSSize(intval($sValue[4].$sValue[5], 16), null, true)); + } else { + $sColorMode = $this->parseIdentifier(false); + $this->consumeWhiteSpace(); + $this->consume('('); + $iLength = mb_strlen($sColorMode, $this->sCharset); + for($i=0;$i<$iLength;$i++) { + $this->consumeWhiteSpace(); + $aColor[$sColorMode[$i]] = $this->parseNumericValue(true); + $this->consumeWhiteSpace(); + if($i < ($iLength-1)) { + $this->consume(','); + } + } + $this->consume(')'); + } + return new CSSColor($aColor); + } + + private function parseURLValue() { + $bUseUrl = $this->comes('url'); + if($bUseUrl) { + $this->consume('url'); + $this->consumeWhiteSpace(); + $this->consume('('); + } + $this->consumeWhiteSpace(); + $oResult = new CSSURL($this->parseStringValue()); + if($bUseUrl) { + $this->consumeWhiteSpace(); + $this->consume(')'); + } + return $oResult; + } + + private function comes($sString, $iOffset = 0) { + if($this->isEnd()) { + return false; + } + return $this->peek($sString, $iOffset) == $sString; + } + + private function peek($iLength = 1, $iOffset = 0) { + if($this->isEnd()) { + return ''; + } + if(is_string($iLength)) { + $iLength = mb_strlen($iLength, $this->sCharset); + } + if(is_string($iOffset)) { + $iOffset = mb_strlen($iOffset, $this->sCharset); + } + return mb_substr($this->sText, $this->iCurrentPosition+$iOffset, $iLength, $this->sCharset); + } + + private function consume($mValue = 1) { + if(is_string($mValue)) { + $iLength = mb_strlen($mValue, $this->sCharset); + if(mb_substr($this->sText, $this->iCurrentPosition, $iLength, $this->sCharset) !== $mValue) { + throw new Exception("Expected $mValue, got ".$this->peek(5)); + } + $this->iCurrentPosition += mb_strlen($mValue, $this->sCharset); + return $mValue; + } else { + if($this->iCurrentPosition+$mValue > $this->iLength) { + throw new Exception("Tried to consume $mValue chars, exceeded file end"); + } + $sResult = mb_substr($this->sText, $this->iCurrentPosition, $mValue, $this->sCharset); + $this->iCurrentPosition += $mValue; + return $sResult; + } + } + + private function consumeExpression($mExpression) { + $aMatches; + if(preg_match($mExpression, $this->inputLeft(), $aMatches, PREG_OFFSET_CAPTURE) === 1) { + return $this->consume($aMatches[0][0]); + } + throw new Exception("Expected pattern $mExpression not found, got: {$this->peek(5)}"); + } + + private function consumeWhiteSpace() { + do { + while(preg_match('/\\s/isSu', $this->peek()) === 1) { + $this->consume(1); + } + } while($this->consumeComment()); + } + + private function consumeComment() { + if($this->comes('/*')) { + $this->consumeUntil('*/'); + $this->consume('*/'); + return true; + } + return false; + } + + private function isEnd() { + return $this->iCurrentPosition >= $this->iLength; + } + + private function consumeUntil($sEnd) { + $iEndPos = mb_strpos($this->sText, $sEnd, $this->iCurrentPosition, $this->sCharset); + if($iEndPos === false) { + throw new Exception("Required $sEnd not found, got {$this->peek(5)}"); + } + return $this->consume($iEndPos-$this->iCurrentPosition); + } + + private function inputLeft() { + return mb_substr($this->sText, $this->iCurrentPosition, -1, $this->sCharset); + } +} + diff --git a/phpQuery/CSSParser/README.md b/phpQuery/CSSParser/README.md new file mode 100755 index 0000000..594574f --- /dev/null +++ b/phpQuery/CSSParser/README.md @@ -0,0 +1,376 @@ +PHP CSS Parser +-------------- + +A Parser for CSS Files written in PHP. Allows extraction of CSS files into a data structure, manipulation of said structure and output as (optimized) CSS. + +## Usage + +### Installation + +Include the `CSSParser.php` file somewhere in your code using `require_once` (or `include_once`, if you prefer), the given `lib` folder needs to exist next to the file. + +### Extraction + +To use the CSS Parser, create a new instance. The constructor takes the following form: + + new CSSParser($sCssContents, $sCharset = 'utf-8'); + +The charset is used only if no @charset declaration is found in the CSS file. + +To read a file, for example, you’d do the following: + + $oCssParser = new CSSParser(file_get_contents('somefile.css')); + $oCssDocument = $oCssParser->parse(); + +The resulting CSS document structure can be manipulated prior to being output. + +### Manipulation + +The resulting data structure consists mainly of five basic types: `CSSList`, `CSSRuleSet`, `CSSRule`, `CSSSelector` and `CSSValue`. There are two additional types used: `CSSImport` and `CSSCharset` which you won’t use often. + +#### CSSList + +`CSSList` represents a generic CSS container, most likely containing declaration blocks (rule sets with a selector) but it may also contain at-rules, charset declarations, etc. `CSSList` has the following concrete subtypes: + +* `CSSDocument` – representing the root of a CSS file. +* `CSSMediaQuery` – represents a subsection of a CSSList that only applies to a output device matching the contained media query. + +#### CSSRuleSet + +`CSSRuleSet` is a container for individual rules. The most common form of a rule set is one constrained by a selector. The following concrete subtypes exist: + +* `CSSAtRule` – for generic at-rules which do not match the ones specifically mentioned like @import, @charset or @media. A common example for this is @font-face. +* `CSSDeclarationBlock` – a RuleSet constrained by a `CSSSelector; contains an array of selector objects (comma-separated in the CSS) as well as the rules to be applied to the matching elements. + +Note: A `CSSList` can contain other `CSSList`s (and `CSSImport`s as well as a `CSSCharset`) while a `CSSRuleSet` can only contain `CSSRule`s. + +#### CSSRule + +`CSSRule`s just have a key (the rule) and multiple values (the part after the colon in the CSS file). This means the `values` attribute is an array consisting of arrays. The inner level of arrays is comma-separated in the CSS file while the outer level is whitespace-separated. + +#### CSSValue + +`CSSValue` is an abstract class that only defines the `__toString` method. The concrete subclasses are: + +* `CSSSize` – consists of a numeric `size` value and a unit. +* `CSSColor` – colors can be input in the form #rrggbb, #rgb or schema(val1, val2, …) but are alwas stored as an array of ('s' => val1, 'c' => val2, 'h' => val3, …) and output in the second form. +* `CSSString` – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes. +* `CSSURL` – URLs in CSS; always output in URL("") notation. + +To access the items stored in a `CSSList` – like the document you got back when calling `$oCssParser->parse()` –, use `getContents()`, then iterate over that collection and use instanceof to check whether you’re dealing with another `CSSList`, a `CSSRuleSet`, a `CSSImport` or a `CSSCharset`. + +To append a new item (selector, media query, etc.) to an existing `CSSList`, construct it using the constructor for this class and use the `append($oItem)` method. + +If you want to manipulate a `CSSRuleSet`, use the methods `addRule(CSSRule $oRule)`, `getRules()` and `removeRule($mRule)` (which accepts either a CSSRule instance or a rule name; optionally suffixed by a dash to remove all related rules). + +#### Convenience methods + +There are a few convenience methods on CSSDocument to ease finding, manipulating and deleting rules: + +* `getAllDeclarationBlocks()` – does what it says; no matter how deeply nested your selectors are. Aliased as `getAllSelectors()`. +* `getAllRuleSets()` – does what it says; no matter how deeply nested your rule sets are. +* `getAllValues()` – finds all `CSSValue` objects inside `CSSRule`s. + +### Use cases + +#### Use `CSSParser` to prepend an id to all selectors + + $sMyId = "#my_id"; + $oParser = new CSSParser($sCssContents); + $oCss = $oParser->parse(); + foreach($oCss->getAllDeclarationBlocks() as $oBlock) { + foreach($oBlock->getSelectors() as $oSelector) { + //Loop over all selector parts (the comma-separated strings in a selector) and prepend the id + $oSelector->setSelector($sMyId.' '.$oSelector->getSelector()); + } + } + +#### Shrink all absolute sizes to half + + $oParser = new CSSParser($sCssContents); + $oCss = $oParser->parse(); + foreach($oCss->getAllValues() as $mValue) { + if($mValue instanceof CSSSize && !$mValue->isRelative()) { + $mValue->setSize($mValue->getSize()/2); + } + } + +#### Remove unwanted rules + + $oParser = new CSSParser($sCssContents); + $oCss = $oParser->parse(); + foreach($oCss->getAllRuleSets() as $oRuleSet) { + $oRuleSet->removeRule('font-'); //Note that the added dash will make this remove all rules starting with font- (like font-size, font-weight, etc.) as well as a potential font-rule + $oRuleSet->removeRule('cursor'); + } + +### Output + +To output the entire CSS document into a variable, just use `->__toString()`: + + $oCssParser = new CSSParser(file_get_contents('somefile.css')); + $oCssDocument = $oCssParser->parse(); + print $oCssDocument->__toString(); + +## Examples + +### Example 1 (At-Rules) + +#### Input + + @charset "utf-8"; + + @font-face { + font-family: "CrassRoots"; + src: url("../media/cr.ttf") + } + + html, body { + font-size: 1.6em + } + +#### Structure (`var_dump()`) + + object(CSSDocument)#2 (1) { + ["aContents":"CSSList":private]=> + array(3) { + [0]=> + object(CSSCharset)#4 (1) { + ["sCharset":"CSSCharset":private]=> + object(CSSString)#3 (1) { + ["sString":"CSSString":private]=> + string(5) "utf-8" + } + } + [1]=> + object(CSSAtRule)#5 (2) { + ["sType":"CSSAtRule":private]=> + string(9) "font-face" + ["aRules":"CSSRuleSet":private]=> + array(2) { + ["font-family"]=> + object(CSSRule)#6 (3) { + ["sRule":"CSSRule":private]=> + string(11) "font-family" + ["mValue":"CSSRule":private]=> + object(CSSString)#7 (1) { + ["sString":"CSSString":private]=> + string(10) "CrassRoots" + } + ["bIsImportant":"CSSRule":private]=> + bool(false) + } + ["src"]=> + object(CSSRule)#8 (3) { + ["sRule":"CSSRule":private]=> + string(3) "src" + ["mValue":"CSSRule":private]=> + object(CSSURL)#9 (1) { + ["oURL":"CSSURL":private]=> + object(CSSString)#10 (1) { + ["sString":"CSSString":private]=> + string(15) "../media/cr.ttf" + } + } + ["bIsImportant":"CSSRule":private]=> + bool(false) + } + } + } + [2]=> + object(CSSDeclarationBlock)#11 (2) { + ["aSelectors":"CSSDeclarationBlock":private]=> + array(2) { + [0]=> + object(CSSSelector)#12 (2) { + ["sSelector":"CSSSelector":private]=> + string(4) "html" + ["iSpecificity":"CSSSelector":private]=> + NULL + } + [1]=> + object(CSSSelector)#13 (2) { + ["sSelector":"CSSSelector":private]=> + string(4) "body" + ["iSpecificity":"CSSSelector":private]=> + NULL + } + } + ["aRules":"CSSRuleSet":private]=> + array(1) { + ["font-size"]=> + object(CSSRule)#14 (3) { + ["sRule":"CSSRule":private]=> + string(9) "font-size" + ["mValue":"CSSRule":private]=> + object(CSSSize)#15 (3) { + ["fSize":"CSSSize":private]=> + float(1.6) + ["sUnit":"CSSSize":private]=> + string(2) "em" + ["bIsColorComponent":"CSSSize":private]=> + bool(false) + } + ["bIsImportant":"CSSRule":private]=> + bool(false) + } + } + } + } + } + +#### Output (`__toString()`) + + @charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}html, body {font-size: 1.6em;} + +### Example 2 (Values) + +#### Input + + #header { + margin: 10px 2em 1cm 2%; + font-family: Verdana, Helvetica, "Gill Sans", sans-serif; + color: red !important; + } + +#### Structure (`var_dump()`) + + object(CSSDocument)#2 (1) { + ["aContents":"CSSList":private]=> + array(1) { + [0]=> + object(CSSDeclarationBlock)#3 (2) { + ["aSelectors":"CSSDeclarationBlock":private]=> + array(1) { + [0]=> + object(CSSSelector)#4 (2) { + ["sSelector":"CSSSelector":private]=> + string(7) "#header" + ["iSpecificity":"CSSSelector":private]=> + NULL + } + } + ["aRules":"CSSRuleSet":private]=> + array(3) { + ["margin"]=> + object(CSSRule)#5 (3) { + ["sRule":"CSSRule":private]=> + string(6) "margin" + ["mValue":"CSSRule":private]=> + object(CSSRuleValueList)#10 (2) { + ["aComponents":protected]=> + array(4) { + [0]=> + object(CSSSize)#6 (3) { + ["fSize":"CSSSize":private]=> + float(10) + ["sUnit":"CSSSize":private]=> + string(2) "px" + ["bIsColorComponent":"CSSSize":private]=> + bool(false) + } + [1]=> + object(CSSSize)#7 (3) { + ["fSize":"CSSSize":private]=> + float(2) + ["sUnit":"CSSSize":private]=> + string(2) "em" + ["bIsColorComponent":"CSSSize":private]=> + bool(false) + } + [2]=> + object(CSSSize)#8 (3) { + ["fSize":"CSSSize":private]=> + float(1) + ["sUnit":"CSSSize":private]=> + string(2) "cm" + ["bIsColorComponent":"CSSSize":private]=> + bool(false) + } + [3]=> + object(CSSSize)#9 (3) { + ["fSize":"CSSSize":private]=> + float(2) + ["sUnit":"CSSSize":private]=> + string(1) "%" + ["bIsColorComponent":"CSSSize":private]=> + bool(false) + } + } + ["sSeparator":protected]=> + string(1) " " + } + ["bIsImportant":"CSSRule":private]=> + bool(false) + } + ["font-family"]=> + object(CSSRule)#11 (3) { + ["sRule":"CSSRule":private]=> + string(11) "font-family" + ["mValue":"CSSRule":private]=> + object(CSSRuleValueList)#13 (2) { + ["aComponents":protected]=> + array(4) { + [0]=> + string(7) "Verdana" + [1]=> + string(9) "Helvetica" + [2]=> + object(CSSString)#12 (1) { + ["sString":"CSSString":private]=> + string(9) "Gill Sans" + } + [3]=> + string(10) "sans-serif" + } + ["sSeparator":protected]=> + string(1) "," + } + ["bIsImportant":"CSSRule":private]=> + bool(false) + } + ["color"]=> + object(CSSRule)#14 (3) { + ["sRule":"CSSRule":private]=> + string(5) "color" + ["mValue":"CSSRule":private]=> + string(3) "red" + ["bIsImportant":"CSSRule":private]=> + bool(true) + } + } + } + } + } + +#### Output (`__toString()`) + + #header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans", sans-serif;color: red !important;} + +## To-Do + +* More convenience methods [like `selectorsWithElement($sId/Class/TagName)`, `removeSelector($oSelector)`, `attributesOfType($sType)`, `removeAttributesOfType($sType)`] +* Options for output (compact, verbose, etc.) +* Support for @namespace +* Named color support (using `CSSColor` instead of an anonymous string literal) +* Test suite +* Adopt lenient parsing rules +* Support for @-rules (other than @media) that are CSSLists (to support @-webkit-keyframes) + +## Contributors/Thanks to + +* [ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties. +* [GaryJones](https://github.com/GaryJones) for lots of input and [http://css-specificity.info/](http://css-specificity.info/). +* [docteurklein](https://github.com/docteurklein) for output formatting and `CSSList->remove()` inspiration. + +## License + +PHP-CSS-Parser is freely distributable under the terms of an MIT-style license. + +Copyright (c) 2011 Raphael Schweikert, http://sabberworm.com/ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/phpQuery/CSSParser/lib/CSSList.php b/phpQuery/CSSParser/lib/CSSList.php new file mode 100755 index 0000000..b2a4b23 --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSList.php @@ -0,0 +1,236 @@ +aContents = array(); + } + + public function append($oItem) { + $this->aContents[] = $oItem; + } + + /** + * Removes an item from the CSS list. + * @param CSSRuleSet|CSSImport|CSSCharset|CSSList $oItemToRemove May be a CSSRuleSet (most likely a CSSDeclarationBlock), a CSSImport, a CSSCharset or another CSSList (most likely a CSSMediaQuery) + */ + public function remove($oItemToRemove) { + $iKey = array_search($oItemToRemove, $this->aContents, true); + if($iKey !== false) { + unset($this->aContents[$iKey]); + } + } + + public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false) { + if($mSelector instanceof CSSDeclarationBlock) { + $mSelector = $mSelector->getSelectors(); + } + if(!is_array($mSelector)) { + $mSelector = explode(',', $mSelector); + } + foreach($mSelector as $iKey => &$mSel) { + if(!($mSel instanceof CSSSelector)) { + $mSel = new CSSSelector($mSel); + } + } + foreach($this->aContents as $iKey => $mItem) { + if(!($mItem instanceof CSSDeclarationBlock)) { + continue; + } + if($mItem->getSelectors() == $mSelector) { + unset($this->aContents[$iKey]); + if(!$bRemoveAll) { + return; + } + } + } + } + + public function __toString() { + $sResult = ''; + foreach($this->aContents as $oContent) { + $sResult .= $oContent->__toString(); + } + return $sResult; + } + + public function getContents() { + return $this->aContents; + } + + protected function allDeclarationBlocks(&$aResult) { + foreach($this->aContents as $mContent) { + if($mContent instanceof CSSDeclarationBlock) { + $aResult[] = $mContent; + } else if($mContent instanceof CSSList) { + $mContent->allDeclarationBlocks($aResult); + } + } + } + + protected function allRuleSets(&$aResult) { + foreach($this->aContents as $mContent) { + if($mContent instanceof CSSRuleSet) { + $aResult[] = $mContent; + } else if($mContent instanceof CSSList) { + $mContent->allRuleSets($aResult); + } + } + } + + protected function allValues($oElement, &$aResult, $sSearchString = null, $bSearchInFunctionArguments = false) { + if($oElement instanceof CSSList) { + foreach($oElement->getContents() as $oContent) { + $this->allValues($oContent, $aResult, $sSearchString, $bSearchInFunctionArguments); + } + } else if($oElement instanceof CSSRuleSet) { + foreach($oElement->getRules($sSearchString) as $oRule) { + $this->allValues($oRule, $aResult, $sSearchString, $bSearchInFunctionArguments); + } + } else if($oElement instanceof CSSRule) { + $this->allValues($oElement->getValue(), $aResult, $sSearchString, $bSearchInFunctionArguments); + } else if($oElement instanceof CSSValueList) { + if($bSearchInFunctionArguments || !($oElement instanceof CSSFunction)) { + foreach($oElement->getListComponents() as $mComponent) { + $this->allValues($mComponent, $aResult, $sSearchString, $bSearchInFunctionArguments); + } + } + } else { + //Non-List CSSValue or String (CSS identifier) + $aResult[] = $oElement; + } + } + + protected function allSelectors(&$aResult, $sSpecificitySearch = null) { + foreach($this->getAllDeclarationBlocks() as $oBlock) { + foreach($oBlock->getSelectors() as $oSelector) { + if($sSpecificitySearch === null) { + $aResult[] = $oSelector; + } else { + $sComparison = "\$bRes = {$oSelector->getSpecificity()} $sSpecificitySearch;"; + eval($sComparison); + if($bRes) { + $aResult[] = $oSelector; + } + } + } + } + } +} + +/** +* The root CSSList of a parsed file. Contains all top-level css contents, mostly declaration blocks, but also any @-rules encountered. +*/ +class CSSDocument extends CSSList { + /** + * Gets all CSSDeclarationBlock objects recursively. + */ + public function getAllDeclarationBlocks() { + $aResult = array(); + $this->allDeclarationBlocks($aResult); + return $aResult; + } + + /** + * @deprecated use getAllDeclarationBlocks() + */ + public function getAllSelectors() { + return $this->getAllDeclarationBlocks(); + } + + /** + * Returns all CSSRuleSet objects found recursively in the tree. + */ + public function getAllRuleSets() { + $aResult = array(); + $this->allRuleSets($aResult); + return $aResult; + } + + /** + * Returns all CSSValue objects found recursively in the tree. + * @param (object|string) $mElement the CSSList or CSSRuleSet to start the search from (defaults to the whole document). If a string is given, it is used as rule name filter (@see{CSSRuleSet->getRules()}). + * @param (bool) $bSearchInFunctionArguments whether to also return CSSValue objects used as CSSFunction arguments. + */ + public function getAllValues($mElement = null, $bSearchInFunctionArguments = false) { + $sSearchString = null; + if($mElement === null) { + $mElement = $this; + } else if(is_string($mElement)) { + $sSearchString = $mElement; + $mElement = $this; + } + $aResult = array(); + $this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments); + return $aResult; + } + + /** + * Returns all CSSSelector objects found recursively in the tree. + * Note that this does not yield the full CSSDeclarationBlock that the selector belongs to (and, currently, there is no way to get to that). + * @param $sSpecificitySearch An optional filter by specificity. May contain a comparison operator and a number or just a number (defaults to "=="). + * @example getSelectorsBySpecificity('>= 100') + */ + public function getSelectorsBySpecificity($sSpecificitySearch = null) { + if(is_numeric($sSpecificitySearch) || is_numeric($sSpecificitySearch[0])) { + $sSpecificitySearch = "== $sSpecificitySearch"; + } + $aResult = array(); + $this->allSelectors($aResult, $sSpecificitySearch); + return $aResult; + } + + /** + * Expands all shorthand properties to their long value + */ + public function expandShorthands() + { + foreach($this->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->expandShorthands(); + } + } + + /* + * Create shorthands properties whenever possible + */ + public function createShorthands() + { + foreach($this->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->createShorthands(); + } + } +} + +/** +* A CSSList consisting of the CSSList and CSSList objects found in a @media query. +*/ +class CSSMediaQuery extends CSSList { + private $sQuery; + + public function __construct() { + parent::__construct(); + $this->sQuery = null; + } + + public function setQuery($sQuery) { + $this->sQuery = $sQuery; + } + + public function getQuery() { + return $this->sQuery; + } + + public function __toString() { + $sResult = "@media {$this->sQuery} {"; + $sResult .= parent::__toString(); + $sResult .= '}'; + return $sResult; + } +} diff --git a/phpQuery/CSSParser/lib/CSSProperties.php b/phpQuery/CSSParser/lib/CSSProperties.php new file mode 100755 index 0000000..15c9edb --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSProperties.php @@ -0,0 +1,124 @@ +oLocation = $oLocation; + $this->sMediaQuery = $sMediaQuery; + } + + public function setLocation($oLocation) { + $this->oLocation = $oLocation; + } + + public function getLocation() { + return $this->oLocation; + } + + public function __toString() { + return "@import ".$this->oLocation->__toString().($this->sMediaQuery === null ? '' : ' '.$this->sMediaQuery).';'; + } +} + +/** +* Class representing an @charset rule. +* The following restrictions apply: +* • May not be found in any CSSList other than the CSSDocument. +* • May only appear at the very top of a CSSDocument’s contents. +* • Must not appear more than once. +*/ +class CSSCharset { + private $sCharset; + + public function __construct($sCharset) { + $this->sCharset = $sCharset; + } + + public function setCharset($sCharset) { + $this->sCharset = $sCharset; + } + + public function getCharset() { + return $this->sCharset; + } + + public function __toString() { + return "@charset {$this->sCharset->__toString()};"; + } +} + +/** +* Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this class. +*/ +class CSSSelector { + const + NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX = '/ + (\.[\w]+) # classes + | + \[(\w+) # attributes + | + (\:( # pseudo classes + link|visited|active + |hover|focus + |lang + |target + |enabled|disabled|checked|indeterminate + |root + |nth-child|nth-last-child|nth-of-type|nth-last-of-type + |first-child|last-child|first-of-type|last-of-type + |only-child|only-of-type + |empty|contains + )) + /ix', + ELEMENTS_AND_PSEUDO_ELEMENTS_RX = '/ + ((^|[\s\+\>\~]+)[\w]+ # elements + | + \:{1,2}( # pseudo-elements + after|before + |first-letter|first-line + |selection + ) + )/ix'; + + private $sSelector; + private $iSpecificity; + + public function __construct($sSelector, $bCalculateSpecificity = false) { + $this->setSelector($sSelector); + if($bCalculateSpecificity) { + $this->getSpecificity(); + } + } + + public function getSelector() { + return $this->sSelector; + } + + public function setSelector($sSelector) { + $this->sSelector = trim($sSelector); + $this->iSpecificity = null; + } + + public function __toString() { + return $this->getSelector(); + } + + public function getSpecificity() { + if($this->iSpecificity === null) { + $a = 0; + /// @todo should exclude \# as well as "#" + $aMatches; + $b = substr_count($this->sSelector, '#'); + $c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches); + $d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches); + $this->iSpecificity = ($a*1000) + ($b*100) + ($c*10) + $d; + } + return $this->iSpecificity; + } +} + diff --git a/phpQuery/CSSParser/lib/CSSRule.php b/phpQuery/CSSParser/lib/CSSRule.php new file mode 100755 index 0000000..d6ab6ac --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSRule.php @@ -0,0 +1,135 @@ +sRule = $sRule; + $this->mValue = null; + $this->bIsImportant = false; + } + + public function setRule($sRule) { + $this->sRule = $sRule; + } + + public function getRule() { + return $this->sRule; + } + + public function getValue() { + return $this->mValue; + } + + public function setValue($mValue) { + $this->mValue = $mValue; + } + + /** + * @deprecated Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility. Use setValue() instead and wrapp the value inside a CSSRuleValueList if necessary. + */ + public function setValues($aSpaceSeparatedValues) { + $oSpaceSeparatedList = null; + if(count($aSpaceSeparatedValues) > 1) { + $oSpaceSeparatedList = new CSSRuleValueList(' '); + } + foreach($aSpaceSeparatedValues as $aCommaSeparatedValues) { + $oCommaSeparatedList = null; + if(count($aCommaSeparatedValues) > 1) { + $oCommaSeparatedList = new CSSRuleValueList(','); + } + foreach($aCommaSeparatedValues as $mValue) { + if(!$oSpaceSeparatedList && !$oCommaSeparatedList) { + $this->mValue = $mValue; + return $mValue; + } + if($oCommaSeparatedList) { + $oCommaSeparatedList->addListComponent($mValue); + } else { + $oSpaceSeparatedList->addListComponent($mValue); + } + } + if(!$oSpaceSeparatedList) { + $this->mValue = $oCommaSeparatedList; + return $oCommaSeparatedList; + } else { + $oSpaceSeparatedList->addListComponent($oCommaSeparatedList); + } + } + $this->mValue = $oSpaceSeparatedList; + return $oSpaceSeparatedList; + } + + /** + * @deprecated Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility. Use getValue() instead and check for the existance of a (nested set of) CSSValueList object(s). + */ + public function getValues() { + if(!$this->mValue instanceof CSSRuleValueList) { + return array(array($this->mValue)); + } + if($this->mValue->getListSeparator() === ',') { + return array($this->mValue->getListComponents()); + } + $aResult = array(); + foreach($this->mValue->getListComponents() as $mValue) { + if(!$mValue instanceof CSSRuleValueList || $mValue->getListSeparator() !== ',') { + $aResult[] = array($mValue); + continue; + } + if($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) { + $aResult[] = array(); + } + foreach($mValue->getListComponents() as $mValue) { + $aResult[count($aResult)-1][] = $mValue; + } + } + return $aResult; + } + + /** + * Adds a value to the existing value. Value will be appended if a CSSRuleValueList exists of the given type. Otherwise, the existing value will be wrapped by one. + */ + public function addValue($mValue, $sType = ' ') { + if(!is_array($mValue)) { + $mValue = array($mValue); + } + if(!$this->mValue instanceof CSSRuleValueList || $this->mValue->getListSeparator() !== $sType) { + $mCurrentValue = $this->mValue; + $this->mValue = new CSSRuleValueList($sType); + if($mCurrentValue) { + $this->mValue->addListComponent($mCurrentValue); + } + } + foreach($mValue as $mValueItem) { + $this->mValue->addListComponent($mValueItem); + } + } + + public function setIsImportant($bIsImportant) { + $this->bIsImportant = $bIsImportant; + } + + public function getIsImportant() { + return $this->bIsImportant; + } + + public function __toString() { + $sResult = "{$this->sRule}: "; + if($this->mValue instanceof CSSValue) { //Can also be a CSSValueList + $sResult .= $this->mValue->__toString(); + } else { + $sResult .= $this->mValue; + } + if($this->bIsImportant) { + $sResult .= ' !important'; + } + $sResult .= ';'; + return $sResult; + } +} diff --git a/phpQuery/CSSParser/lib/CSSRuleSet.php b/phpQuery/CSSParser/lib/CSSRuleSet.php new file mode 100755 index 0000000..2788f2f --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSRuleSet.php @@ -0,0 +1,653 @@ +aRules = array(); + } + + public function addRule(CSSRule $oRule) { + $this->aRules[$oRule->getRule()] = $oRule; + } + + /** + * Returns all rules matching the given pattern + * @param (null|string|CSSRule) $mRule pattern to search for. If null, returns all rules. if the pattern ends with a dash, all rules starting with the pattern are returned as well as one matching the pattern with the dash excluded. passing a CSSRule behaves like calling getRules($mRule->getRule()). + * @example $oRuleSet->getRules('font-') //returns an array of all rules either beginning with font- or matching font. + * @example $oRuleSet->getRules('font') //returns array('font' => $oRule) or array(). + */ + public function getRules($mRule = null) { + if($mRule === null) { + return $this->aRules; + } + $aResult = array(); + if($mRule instanceof CSSRule) { + $mRule = $mRule->getRule(); + } + if(strrpos($mRule, '-')===strlen($mRule)-strlen('-')) { + $sStart = substr($mRule, 0, -1); + foreach($this->aRules as $oRule) { + if($oRule->getRule() === $sStart || strpos($oRule->getRule(), $mRule) === 0) { + $aResult[$oRule->getRule()] = $this->aRules[$oRule->getRule()]; + } + } + } else if(isset($this->aRules[$mRule])) { + $aResult[$mRule] = $this->aRules[$mRule]; + } + return $aResult; + } + + public function removeRule($mRule) { + if($mRule instanceof CSSRule) { + $mRule = $mRule->getRule(); + } + if(strrpos($mRule, '-')===strlen($mRule)-strlen('-')) { + $sStart = substr($mRule, 0, -1); + foreach($this->aRules as $oRule) { + if($oRule->getRule() === $sStart || strpos($oRule->getRule(), $mRule) === 0) { + unset($this->aRules[$oRule->getRule()]); + } + } + } else if(isset($this->aRules[$mRule])) { + unset($this->aRules[$mRule]); + } + } + + public function __toString() { + $sResult = ''; + foreach($this->aRules as $oRule) { + $sResult .= $oRule->__toString(); + } + return $sResult; + } +} + +/** +* A CSSRuleSet constructed by an unknown @-rule. @font-face rules are rendered into CSSAtRule objects. +*/ +class CSSAtRule extends CSSRuleSet { + private $sType; + + public function __construct($sType) { + parent::__construct(); + $this->sType = $sType; + } + + public function __toString() { + $sResult = "@{$this->sType} {"; + $sResult .= parent::__toString(); + $sResult .= '}'; + return $sResult; + } +} + +/** +* Declaration blocks are the parts of a css file which denote the rules belonging to a selector. +* Declaration blocks usually appear directly inside a CSSDocument or another CSSList (mostly a CSSMediaQuery). +*/ +class CSSDeclarationBlock extends CSSRuleSet { + + private $aSelectors; + + public function __construct() { + parent::__construct(); + $this->aSelectors = array(); + } + + public function setSelectors($mSelector) { + if(is_array($mSelector)) { + $this->aSelectors = $mSelector; + } else { + $this->aSelectors = explode(',', $mSelector); + } + foreach($this->aSelectors as $iKey => $mSelector) { + if(!($mSelector instanceof CSSSelector)) { + $this->aSelectors[$iKey] = new CSSSelector($mSelector); + } + } + } + + /** + * @deprecated use getSelectors() + */ + public function getSelector() { + return $this->getSelectors(); + } + + /** + * @deprecated use setSelectors() + */ + public function setSelector($mSelector) { + $this->setSelectors($mSelector); + } + + public function getSelectors() { + return $this->aSelectors; + } + + /** + * Split shorthand declarations (e.g. +margin+ or +font+) into their constituent parts. + **/ + public function expandShorthands() { + // border must be expanded before dimensions + $this->expandBorderShorthand(); + $this->expandDimensionsShorthand(); + $this->expandFontShorthand(); + $this->expandBackgroundShorthand(); + $this->expandListStyleShorthand(); + } + + /** + * Create shorthand declarations (e.g. +margin+ or +font+) whenever possible. + **/ + public function createShorthands() { + $this->createBackgroundShorthand(); + $this->createDimensionsShorthand(); + // border must be shortened after dimensions + $this->createBorderShorthand(); + $this->createFontShorthand(); + $this->createListStyleShorthand(); + } + + /** + * Split shorthand border declarations (e.g. border: 1px red;) + * Additional splitting happens in expandDimensionsShorthand + * Multiple borders are not yet supported as of CSS3 + **/ + public function expandBorderShorthand() { + $aBorderRules = array( + 'border', 'border-left', 'border-right', 'border-top', 'border-bottom' + ); + $aBorderSizes = array( + 'thin', 'medium', 'thick' + ); + $aRules = $this->getRules(); + foreach ($aBorderRules as $sBorderRule) { + if(!isset($aRules[$sBorderRule])) continue; + $oRule = $aRules[$sBorderRule]; + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + foreach ($aValues as $mValue) { + if($mValue instanceof CSSValue) { + $mNewValue = clone $mValue; + } else { + $mNewValue = $mValue; + } + if($mValue instanceof CSSSize) { + $sNewRuleName = $sBorderRule."-width"; + } else if($mValue instanceof CSSColor) { + $sNewRuleName = $sBorderRule."-color"; + } else { + if(in_array($mValue, $aBorderSizes)) { + $sNewRuleName = $sBorderRule."-width"; + } else/* if(in_array($mValue, $aBorderStyles))*/ { + $sNewRuleName = $sBorderRule."-style"; + } + } + $oNewRule = new CSSRule($sNewRuleName); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $oNewRule->addValue(array($mNewValue)); + $this->addRule($oNewRule); + } + $this->removeRule($sBorderRule); + } + } + + /** + * Split shorthand dimensional declarations (e.g. margin: 0px auto;) + * into their constituent parts. + * Handles margin, padding, border-color, border-style and border-width. + **/ + public function expandDimensionsShorthand() { + $aExpansions = array( + 'margin' => 'margin-%s', + 'padding' => 'padding-%s', + 'border-color' => 'border-%s-color', + 'border-style' => 'border-%s-style', + 'border-width' => 'border-%s-width' + ); + $aRules = $this->getRules(); + foreach ($aExpansions as $sProperty => $sExpanded) { + if(!isset($aRules[$sProperty])) continue; + $oRule = $aRules[$sProperty]; + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + $top = $right = $bottom = $left = null; + switch(count($aValues)) { + case 1: + $top = $right = $bottom = $left = $aValues[0]; + break; + case 2: + $top = $bottom = $aValues[0]; + $left = $right = $aValues[1]; + break; + case 3: + $top = $aValues[0]; + $left = $right = $aValues[1]; + $bottom = $aValues[2]; + break; + case 4: + $top = $aValues[0]; + $right = $aValues[1]; + $bottom = $aValues[2]; + $left = $aValues[3]; + break; + } + foreach(array('top', 'right', 'bottom', 'left') as $sPosition) { + $oNewRule = new CSSRule(sprintf($sExpanded, $sPosition)); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $oNewRule->addValue(${$sPosition}); + $this->addRule($oNewRule); + } + $this->removeRule($sProperty); + } + } + + /** + * Convert shorthand font declarations + * (e.g. font: 300 italic 11px/14px verdana, helvetica, sans-serif;) + * into their constituent parts. + **/ + public function expandFontShorthand() { + $aRules = $this->getRules(); + if(!isset($aRules['font'])) return; + $oRule = $aRules['font']; + // reset properties to 'normal' per http://www.w3.org/TR/CSS21/fonts.html#font-shorthand + $aFontProperties = array( + 'font-style' => 'normal', + 'font-variant' => 'normal', + 'font-weight' => 'normal', + 'font-size' => 'normal', + 'line-height' => 'normal' + ); + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + foreach($aValues as $mValue) { + if(!$mValue instanceof CSSValue) { + $mValue = mb_strtolower($mValue); + } + if(in_array($mValue, array('normal', 'inherit'))) { + foreach (array('font-style', 'font-weight', 'font-variant') as $sProperty) { + if(!isset($aFontProperties[$sProperty])) { + $aFontProperties[$sProperty] = $mValue; + } + } + } else if(in_array($mValue, array('italic', 'oblique'))) { + $aFontProperties['font-style'] = $mValue; + } else if($mValue == 'small-caps') { + $aFontProperties['font-variant'] = $mValue; + } else if( + in_array($mValue, array('bold', 'bolder', 'lighter')) + || ($mValue instanceof CSSSize + && in_array($mValue->getSize(), range(100, 900, 100))) + ) { + $aFontProperties['font-weight'] = $mValue; + } else if($mValue instanceof CSSRuleValueList && $mValue->getListSeparator() == '/') { + list($oSize, $oHeight) = $mValue->getListComponents(); + $aFontProperties['font-size'] = $oSize; + $aFontProperties['line-height'] = $oHeight; + } else if($mValue instanceof CSSSize && $mValue->getUnit() !== null) { + $aFontProperties['font-size'] = $mValue; + } else { + $aFontProperties['font-family'] = $mValue; + } + } + foreach ($aFontProperties as $sProperty => $mValue) { + $oNewRule = new CSSRule($sProperty); + $oNewRule->addValue($mValue); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $this->addRule($oNewRule); + } + $this->removeRule('font'); + } + + /* + * Convert shorthand background declarations + * (e.g. background: url("chess.png") gray 50% repeat fixed;) + * into their constituent parts. + * @see http://www.w3.org/TR/CSS21/colors.html#propdef-background + **/ + public function expandBackgroundShorthand() { + $aRules = $this->getRules(); + if(!isset($aRules['background'])) return; + $oRule = $aRules['background']; + $aBgProperties = array( + 'background-color' => array('transparent'), 'background-image' => array('none'), + 'background-repeat' => array('repeat'), 'background-attachment' => array('scroll'), + 'background-position' => array(new CSSSize(0, '%'), new CSSSize(0, '%')) + ); + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + if(count($aValues) == 1 && $aValues[0] == 'inherit') { + foreach ($aBgProperties as $sProperty => $mValue) { + $oNewRule = new CSSRule($sProperty); + $oNewRule->addValue('inherit'); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $this->addRule($oNewRule); + } + $this->removeRule('background'); + return; + } + $iNumBgPos = 0; + foreach($aValues as $mValue) { + if(!$mValue instanceof CSSValue) { + $mValue = mb_strtolower($mValue); + } + if ($mValue instanceof CSSURL) { + $aBgProperties['background-image'] = $mValue; + } else if($mValue instanceof CSSColor) { + $aBgProperties['background-color'] = $mValue; + } else if(in_array($mValue, array('scroll', 'fixed'))) { + $aBgProperties['background-attachment'] = $mValue; + } else if(in_array($mValue, array('repeat','no-repeat', 'repeat-x', 'repeat-y'))) { + $aBgProperties['background-repeat'] = $mValue; + } else if(in_array($mValue, array('left','center','right','top','bottom')) + || $mValue instanceof CSSSize + ){ + if($iNumBgPos == 0) { + $aBgProperties['background-position'][0] = $mValue; + $aBgProperties['background-position'][1] = 'center'; + } else { + $aBgProperties['background-position'][$iNumBgPos] = $mValue; + } + $iNumBgPos++; + } + } + foreach ($aBgProperties as $sProperty => $mValue) { + $oNewRule = new CSSRule($sProperty); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $oNewRule->addValue($mValue); + $this->addRule($oNewRule); + } + $this->removeRule('background'); + } + + public function expandListStyleShorthand() { + $aListProperties = array( + 'list-style-type' => 'disc', + 'list-style-position' => 'outside', + 'list-style-image' => 'none' + ); + $aListStyleTypes = array( + 'none', 'disc', 'circle', 'square', 'decimal-leading-zero', 'decimal', + 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', 'lower-latin', + 'upper-alpha', 'upper-latin', 'hebrew', 'armenian', 'georgian', 'cjk-ideographic', + 'hiragana', 'hira-gana-iroha', 'katakana-iroha', 'katakana' + ); + $aListStylePositions = array( + 'inside', 'outside' + ); + $aRules = $this->getRules(); + if(!isset($aRules['list-style'])) return; + $oRule = $aRules['list-style']; + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + if(count($aValues) == 1 && $aValues[0] == 'inherit') { + foreach ($aListProperties as $sProperty => $mValue) { + $oNewRule = new CSSRule($sProperty); + $oNewRule->addValue('inherit'); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $this->addRule($oNewRule); + } + $this->removeRule('list-style'); + return; + } + foreach($aValues as $mValue) { + if(!$mValue instanceof CSSValue) { + $mValue = mb_strtolower($mValue); + } + if($mValue instanceof CSSUrl) { + $aListProperties['list-style-image'] = $mValue; + } else if(in_array($mValue, $aListStyleTypes)) { + $aListProperties['list-style-types'] = $mValue; + } else if(in_array($mValue, $aListStylePositions)) { + $aListProperties['list-style-position'] = $mValue; + } + } + foreach ($aListProperties as $sProperty => $mValue) { + $oNewRule = new CSSRule($sProperty); + $oNewRule->setIsImportant($oRule->getIsImportant()); + $oNewRule->addValue($mValue); + $this->addRule($oNewRule); + } + $this->removeRule('list-style'); + } + + public function createShorthandProperties(array $aProperties, $sShorthand) { + $aRules = $this->getRules(); + $aNewValues = array(); + foreach($aProperties as $sProperty) { + if(!isset($aRules[$sProperty])) continue; + $oRule = $aRules[$sProperty]; + if(!$oRule->getIsImportant()) { + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + foreach($aValues as $mValue) { + $aNewValues[] = $mValue; + } + $this->removeRule($sProperty); + } + } + if(count($aNewValues)) { + $oNewRule = new CSSRule($sShorthand); + foreach($aNewValues as $mValue) { + $oNewRule->addValue($mValue); + } + $this->addRule($oNewRule); + } + } + + public function createBackgroundShorthand() { + $aProperties = array( + 'background-color', 'background-image', 'background-repeat', + 'background-position', 'background-attachment' + ); + $this->createShorthandProperties($aProperties, 'background'); + } + + public function createListStyleShorthand() { + $aProperties = array( + 'list-style-type', 'list-style-position', 'list-style-image' + ); + $this->createShorthandProperties($aProperties, 'list-style'); + } + + /** + * Combine border-color, border-style and border-width into border + * Should be run after create_dimensions_shorthand! + **/ + public function createBorderShorthand() { + $aProperties = array( + 'border-width', 'border-style', 'border-color' + ); + $this->createShorthandProperties($aProperties, 'border'); + } + + /* + * Looks for long format CSS dimensional properties + * (margin, padding, border-color, border-style and border-width) + * and converts them into shorthand CSS properties. + **/ + public function createDimensionsShorthand() { + $aPositions = array('top', 'right', 'bottom', 'left'); + $aExpansions = array( + 'margin' => 'margin-%s', + 'padding' => 'padding-%s', + 'border-color' => 'border-%s-color', + 'border-style' => 'border-%s-style', + 'border-width' => 'border-%s-width' + ); + $aRules = $this->getRules(); + foreach ($aExpansions as $sProperty => $sExpanded) { + $aFoldable = array(); + foreach($aRules as $sRuleName => $oRule) { + foreach ($aPositions as $sPosition) { + if($sRuleName == sprintf($sExpanded, $sPosition)) { + $aFoldable[$sRuleName] = $oRule; + } + } + } + // All four dimensions must be present + if(count($aFoldable) == 4) { + $aValues = array(); + foreach ($aPositions as $sPosition) { + $oRule = $aRules[sprintf($sExpanded, $sPosition)]; + $mRuleValue = $oRule->getValue(); + $aRuleValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aRuleValues[] = $mRuleValue; + } else { + $aRuleValues = $mRuleValue->getListComponents(); + } + $aValues[$sPosition] = $aRuleValues; + } + $oNewRule = new CSSRule($sProperty); + if((string)$aValues['left'][0] == (string)$aValues['right'][0]) { + if((string)$aValues['top'][0] == (string)$aValues['bottom'][0]) { + if((string)$aValues['top'][0] == (string)$aValues['left'][0]) { + // All 4 sides are equal + $oNewRule->addValue($aValues['top']); + } else { + // Top and bottom are equal, left and right are equal + $oNewRule->addValue($aValues['top']); + $oNewRule->addValue($aValues['left']); + } + } else { + // Only left and right are equal + $oNewRule->addValue($aValues['top']); + $oNewRule->addValue($aValues['left']); + $oNewRule->addValue($aValues['bottom']); + } + } else { + // No sides are equal + $oNewRule->addValue($aValues['top']); + $oNewRule->addValue($aValues['left']); + $oNewRule->addValue($aValues['bottom']); + $oNewRule->addValue($aValues['right']); + } + $this->addRule($oNewRule); + foreach ($aPositions as $sPosition) + { + $this->removeRule(sprintf($sExpanded, $sPosition)); + } + } + } + } + + /** + * Looks for long format CSS font properties (e.g. font-weight) and + * tries to convert them into a shorthand CSS font property. + * At least font-size AND font-family must be present in order to create a shorthand declaration. + **/ + public function createFontShorthand() { + $aFontProperties = array( + 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family' + ); + $aRules = $this->getRules(); + if(!isset($aRules['font-size']) || !isset($aRules['font-family'])) { + return; + } + $oNewRule = new CSSRule('font'); + foreach(array('font-style', 'font-variant', 'font-weight') as $sProperty) { + if(isset($aRules[$sProperty])) { + $oRule = $aRules[$sProperty]; + $mRuleValue = $oRule->getValue(); + $aValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aValues[] = $mRuleValue; + } else { + $aValues = $mRuleValue->getListComponents(); + } + if($aValues[0] !== 'normal') { + $oNewRule->addValue($aValues[0]); + } + } + } + // Get the font-size value + $oRule = $aRules['font-size']; + $mRuleValue = $oRule->getValue(); + $aFSValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aFSValues[] = $mRuleValue; + } else { + $aFSValues = $mRuleValue->getListComponents(); + } + // But wait to know if we have line-height to add it + if(isset($aRules['line-height'])) { + $oRule = $aRules['line-height']; + $mRuleValue = $oRule->getValue(); + $aLHValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aLHValues[] = $mRuleValue; + } else { + $aLHValues = $mRuleValue->getListComponents(); + } + if($aLHValues[0] !== 'normal') { + $val = new CSSRuleValueList('/'); + $val->addListComponent($aFSValues[0]); + $val->addListComponent($aLHValues[0]); + $oNewRule->addValue($val); + } + } else { + $oNewRule->addValue($aFSValues[0]); + } + $oRule = $aRules['font-family']; + $mRuleValue = $oRule->getValue(); + $aFFValues = array(); + if(!$mRuleValue instanceof CSSRuleValueList) { + $aFFValues[] = $mRuleValue; + } else { + $aFFValues = $mRuleValue->getListComponents(); + } + $oFFValue = new CSSRuleValueList(','); + $oFFValue->setListComponents($aFFValues); + $oNewRule->addValue($oFFValue); + + $this->addRule($oNewRule); + foreach ($aFontProperties as $sProperty) { + $this->removeRule($sProperty); + } + } + + public function __toString() { + $sResult = implode(', ', $this->aSelectors).' {'; + $sResult .= parent::__toString(); + $sResult .= '}'."\n"; + return $sResult; + } +} diff --git a/phpQuery/CSSParser/lib/CSSValue.php b/phpQuery/CSSParser/lib/CSSValue.php new file mode 100755 index 0000000..6dc3fb9 --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSValue.php @@ -0,0 +1,110 @@ +fSize = floatval($fSize); + $this->sUnit = $sUnit; + $this->bIsColorComponent = $bIsColorComponent; + } + + public function setUnit($sUnit) { + $this->sUnit = $sUnit; + } + + public function getUnit() { + return $this->sUnit; + } + + public function setSize($fSize) { + $this->fSize = floatval($fSize); + } + + public function getSize() { + return $this->fSize; + } + + public function isColorComponent() { + return $this->bIsColorComponent; + } + + /** + * Returns whether the number stored in this CSSSize really represents a size (as in a length of something on screen). + * @return false if the unit an angle, a duration, a frequency or the number is a component in a CSSColor object. + */ + public function isSize() { + $aNonSizeUnits = array('deg', 'grad', 'rad', 'turns', 's', 'ms', 'Hz', 'kHz'); + if(in_array($this->sUnit, $aNonSizeUnits)) { + return false; + } + return !$this->isColorComponent(); + } + + public function isRelative() { + if($this->sUnit === '%' || $this->sUnit === 'em' || $this->sUnit === 'ex') { + return true; + } + if($this->sUnit === null && $this->fSize != 0) { + return true; + } + return false; + } + + public function __toString() { + return $this->fSize.($this->sUnit === null ? '' : $this->sUnit); + } +} + +class CSSString extends CSSPrimitiveValue { + private $sString; + + public function __construct($sString) { + $this->sString = $sString; + } + + public function setString($sString) { + $this->sString = $sString; + } + + public function getString() { + return $this->sString; + } + + public function __toString() { + $sString = addslashes($this->sString); + $sString = str_replace("\n", '\A', $sString); + return '"'.$sString.'"'; + } +} + +class CSSURL extends CSSPrimitiveValue { + private $oURL; + + public function __construct(CSSString $oURL) { + $this->oURL = $oURL; + } + + public function setURL(CSSString $oURL) { + $this->oURL = $oURL; + } + + public function getURL() { + return $this->oURL; + } + + public function __toString() { + return "url({$this->oURL->__toString()})"; + } +} + diff --git a/phpQuery/CSSParser/lib/CSSValueList.php b/phpQuery/CSSParser/lib/CSSValueList.php new file mode 100755 index 0000000..35269e2 --- /dev/null +++ b/phpQuery/CSSParser/lib/CSSValueList.php @@ -0,0 +1,92 @@ +getListSeparator() === $sSeparator) { + $aComponents = $aComponents->getListComponents(); + } else if(!is_array($aComponents)) { + $aComponents = array($aComponents); + } + $this->aComponents = $aComponents; + $this->sSeparator = $sSeparator; + } + + public function addListComponent($mComponent) { + $this->aComponents[] = $mComponent; + } + + public function getListComponents() { + return $this->aComponents; + } + + public function setListComponents($aComponents) { + $this->aComponents = $aComponents; + } + + public function getListSeparator() { + return $this->sSeparator; + } + + public function setListSeparator($sSeparator) { + $this->sSeparator = $sSeparator; + } + + function __toString() { + return implode($this->sSeparator, $this->aComponents); + } +} + +class CSSRuleValueList extends CSSValueList { + public function __construct($sSeparator = ',') { + parent::__construct(array(), $sSeparator); + } +} + +class CSSFunction extends CSSValueList { + private $sName; + public function __construct($sName, $aArguments) { + $this->sName = $sName; + parent::__construct($aArguments); + } + + public function getName() { + return $this->sName; + } + + public function setName($sName) { + $this->sName = $sName; + } + + public function getArguments() { + return $this->aComponents; + } + + public function __toString() { + $aArguments = parent::__toString(); + return "{$this->sName}({$aArguments})"; + } +} + +class CSSColor extends CSSFunction { + public function __construct($aColor) { + parent::__construct(implode('', array_keys($aColor)), $aColor); + } + + public function getColor() { + return $this->aComponents; + } + + public function setColor($aColor) { + $this->setName(implode('', array_keys($aColor))); + $this->aComponents = $aColor; + } + + public function getColorDescription() { + return $this->getName(); + } +} + + diff --git a/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php b/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php new file mode 100755 index 0000000..0d311c7 --- /dev/null +++ b/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php @@ -0,0 +1,223 @@ +parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->expandBorderShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function expandBorderShorthandProvider() + { + return array( + array('body{ border: 2px solid rgb(0,0,0) }', 'body {border-width: 2px;border-style: solid;border-color: rgb(0,0,0);}'), + array('body{ border: none }', 'body {border-style: none;}'), + array('body{ border: 2px }', 'body {border-width: 2px;}'), + array('body{ border: rgb(255,0,0) }', 'body {border-color: rgb(255,0,0);}'), + array('body{ border: 1em solid }', 'body {border-width: 1em;border-style: solid;}'), + array('body{ margin: 1em; }', 'body {margin: 1em;}') + ); + } + + /** + * @dataProvider expandFontShorthandProvider + **/ + public function testExpandFontShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->expandFontShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function expandFontShorthandProvider() + { + return array( + array( + 'body{ margin: 1em; }', + 'body {margin: 1em;}' + ), + array( + 'body {font: 12px serif;}', + 'body {font-style: normal;font-variant: normal;font-weight: normal;font-size: 12px;line-height: normal;font-family: serif;}' + ), + array( + 'body {font: italic 12px serif;}', + 'body {font-style: italic;font-variant: normal;font-weight: normal;font-size: 12px;line-height: normal;font-family: serif;}' + ), + array( + 'body {font: italic bold 12px serif;}', + 'body {font-style: italic;font-variant: normal;font-weight: bold;font-size: 12px;line-height: normal;font-family: serif;}' + ), + array( + 'body {font: italic bold 12px/1.6 serif;}', + 'body {font-style: italic;font-variant: normal;font-weight: bold;font-size: 12px;line-height: 1.6;font-family: serif;}' + ), + array( + 'body {font: italic small-caps bold 12px/1.6 serif;}', + 'body {font-style: italic;font-variant: small-caps;font-weight: bold;font-size: 12px;line-height: 1.6;font-family: serif;}' + ), + ); + } + + /** + * @dataProvider expandBackgroundShorthandProvider + **/ + public function testExpandBackgroundShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->expandBackgroundShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function expandBackgroundShorthandProvider() + { + return array( + array('body {border: 1px;}', 'body {border: 1px;}'), + array('body {background: rgb(255,0,0);}','body {background-color: rgb(255,0,0);background-image: none;background-repeat: repeat;background-attachment: scroll;background-position: 0% 0%;}'), + array('body {background: rgb(255,0,0) url("foobar.png");}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: repeat;background-attachment: scroll;background-position: 0% 0%;}'), + array('body {background: rgb(255,0,0) url("foobar.png") no-repeat;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: 0% 0%;}'), + array('body {background: rgb(255,0,0) url("foobar.png") no-repeat center;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: center center;}'), + array('body {background: rgb(255,0,0) url("foobar.png") no-repeat top left;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: top left;}'), + ); + } + + /** + * @dataProvider expandDimensionsShorthandProvider + **/ + public function testExpandDimensionsShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->expandDimensionsShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function expandDimensionsShorthandProvider() + { + return array( + array('body {border: 1px;}', 'body {border: 1px;}'), + array('body {margin-top: 1px;}', 'body {margin-top: 1px;}'), + array('body {margin: 1em;}','body {margin-top: 1em;margin-right: 1em;margin-bottom: 1em;margin-left: 1em;}'), + array('body {margin: 1em 2em;}','body {margin-top: 1em;margin-right: 2em;margin-bottom: 1em;margin-left: 2em;}'), + array('body {margin: 1em 2em 3em;}','body {margin-top: 1em;margin-right: 2em;margin-bottom: 3em;margin-left: 2em;}'), + ); + } + + /** + * @dataProvider createBorderShorthandProvider + **/ + public function testCreateBorderShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->createBorderShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function createBorderShorthandProvider() + { + return array( + array('body {border-width: 2px;border-style: solid;border-color: rgb(0,0,0);}', 'body {border: 2px solid rgb(0,0,0);}'), + array('body {border-style: none;}', 'body {border: none;}'), + array('body {border-width: 1em;border-style: solid;}', 'body {border: 1em solid;}'), + array('body {margin: 1em;}', 'body {margin: 1em;}') + ); + } + + /** + * @dataProvider createFontShorthandProvider + **/ + public function testCreateFontShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->createFontShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function createFontShorthandProvider() + { + return array( + array('body {font-size: 12px; font-family: serif}', 'body {font: 12px serif;}'), + array('body {font-size: 12px; font-family: serif; font-style: italic;}', 'body {font: italic 12px serif;}'), + array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold;}', 'body {font: italic bold 12px serif;}'), + array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold; line-height: 1.6;}', 'body {font: italic bold 12px/1.6 serif;}'), + array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold; line-height: 1.6; font-variant: small-caps;}', 'body {font: italic small-caps bold 12px/1.6 serif;}'), + array('body {margin: 1em;}', 'body {margin: 1em;}') + ); + } + + /** + * @dataProvider createDimensionsShorthandProvider + **/ + public function testCreateDimensionsShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->createDimensionsShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function createDimensionsShorthandProvider() + { + return array( + array('body {border: 1px;}', 'body {border: 1px;}'), + array('body {margin-top: 1px;}', 'body {margin-top: 1px;}'), + array('body {margin-top: 1em; margin-right: 1em; margin-bottom: 1em; margin-left: 1em;}','body {margin: 1em;}'), + array('body {margin-top: 1em; margin-right: 2em; margin-bottom: 1em; margin-left: 2em;}','body {margin: 1em 2em;}'), + array('body {margin-top: 1em; margin-right: 2em; margin-bottom: 3em; margin-left: 2em;}','body {margin: 1em 2em 3em;}'), + ); + } + + /** + * @dataProvider createBackgroundShorthandProvider + **/ + public function testCreateBackgroundShorthand($sCss, $sExpected) + { + $oParser = new CSSParser($sCss); + $oDoc = $oParser->parse(); + foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) + { + $oDeclaration->createBackgroundShorthand(); + } + $this->assertSame(trim((string)$oDoc), $sExpected); + } + public function createBackgroundShorthandProvider() + { + return array( + array('body {border: 1px;}', 'body {border: 1px;}'), + array('body {background-color: rgb(255,0,0);}', 'body {background: rgb(255,0,0);}'), + array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);}', 'body {background: rgb(255,0,0) url("foobar.png");}'), + array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat;}'), + array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat;}'), + array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;background-position: center;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat center;}'), + array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;background-position: top left;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat top left;}'), + ); + } + +} diff --git a/phpQuery/CSSParser/tests/CSSParserTests.php b/phpQuery/CSSParser/tests/CSSParserTests.php new file mode 100755 index 0000000..66071c2 --- /dev/null +++ b/phpQuery/CSSParser/tests/CSSParserTests.php @@ -0,0 +1,277 @@ +assertNotEquals('', $oParser->parse()->__toString()); + } catch(Exception $e) { + $this->fail($e); + } + } + closedir($rHandle); + } + } + + /** + * @depends testCssFiles + */ + function testColorParsing() { + $oDoc = $this->parsedStructureForFile('colortest'); + foreach($oDoc->getAllRuleSets() as $oRuleSet) { + if(!$oRuleSet instanceof CSSDeclarationBlock) { + continue; + } + $sSelector = $oRuleSet->getSelectors(); + $sSelector = $sSelector[0]->getSelector(); + if($sSelector == '#mine') { + $aColorRule = $oRuleSet->getRules('color'); + $aValues = $aColorRule['color']->getValues(); + $this->assertSame('red', $aValues[0][0]); + $aColorRule = $oRuleSet->getRules('background-'); + $aValues = $aColorRule['background-color']->getValues(); + $this->assertEquals(array('r' => new CSSSize(35.0, null, true), 'g' => new CSSSize(35.0, null, true), 'b' => new CSSSize(35.0, null, true)), $aValues[0][0]->getColor()); + $aColorRule = $oRuleSet->getRules('border-color'); + $aValues = $aColorRule['border-color']->getValues(); + $this->assertEquals(array('r' => new CSSSize(10.0, null, true), 'g' => new CSSSize(100.0, null, true), 'b' => new CSSSize(230.0, null, true), 'a' => new CSSSize(0.3, null, true)), $aValues[0][0]->getColor()); + $aColorRule = $oRuleSet->getRules('outline-color'); + $aValues = $aColorRule['outline-color']->getValues(); + $this->assertEquals(array('r' => new CSSSize(34.0, null, true), 'g' => new CSSSize(34.0, null, true), 'b' => new CSSSize(34.0, null, true)), $aValues[0][0]->getColor()); + } + } + foreach($oDoc->getAllValues('background-') as $oColor) { + if($oColor->getColorDescription() === 'hsl') { + $this->assertEquals(array('h' => new CSSSize(220.0, null, true), 's' => new CSSSize(10.0, null, true), 'l' => new CSSSize(220.0, null, true)), $oColor->getColor()); + } + } + foreach($oDoc->getAllValues('color') as $sColor) { + $this->assertSame('red', $sColor); + } + } + + function testUnicodeParsing() { + $oDoc = $this->parsedStructureForFile('unicode'); + foreach($oDoc->getAllDeclarationBlocks() as $oRuleSet) { + $sSelector = $oRuleSet->getSelectors(); + $sSelector = $sSelector[0]->getSelector(); + if(substr($sSelector, 0, strlen('.test-')) !== '.test-') { + continue; + } + $aContentRules = $oRuleSet->getRules('content'); + $aContents = $aContentRules['content']->getValues(); + $sCssString = $aContents[0][0]->__toString(); + if($sSelector == '.test-1') { + $this->assertSame('" "', $sCssString); + } + if($sSelector == '.test-2') { + $this->assertSame('"é"', $sCssString); + } + if($sSelector == '.test-3') { + $this->assertSame('" "', $sCssString); + } + if($sSelector == '.test-4') { + $this->assertSame('"𝄞"', $sCssString); + } + if($sSelector == '.test-5') { + $this->assertSame('"水"', $sCssString); + } + if($sSelector == '.test-6') { + $this->assertSame('"¥"', $sCssString); + } + if($sSelector == '.test-7') { + $this->assertSame('"\A"', $sCssString); + } + if($sSelector == '.test-8') { + $this->assertSame('"\"\""', $sCssString); + } + if($sSelector == '.test-9') { + $this->assertSame('"\"\\\'"', $sCssString); + } + if($sSelector == '.test-10') { + $this->assertSame('"\\\'\\\\"', $sCssString); + } + if($sSelector == '.test-11') { + $this->assertSame('"test"', $sCssString); + } + } + } + + function testSpecificity() { + $oDoc = $this->parsedStructureForFile('specificity'); + $oDeclarationBlock = $oDoc->getAllDeclarationBlocks(); + $oDeclarationBlock = $oDeclarationBlock[0]; + $aSelectors = $oDeclarationBlock->getSelectors(); + foreach($aSelectors as $oSelector) { + switch($oSelector->getSelector()) { + case "#test .help": + $this->assertSame(110, $oSelector->getSpecificity()); + break; + case "#file": + $this->assertSame(100, $oSelector->getSpecificity()); + break; + case ".help:hover": + $this->assertSame(20, $oSelector->getSpecificity()); + break; + case "ol li::before": + $this->assertSame(3, $oSelector->getSpecificity()); + break; + case "li.green": + $this->assertSame(11, $oSelector->getSpecificity()); + break; + default: + $this->fail("specificity: untested selector ".$oSelector->getSelector()); + } + } + $this->assertEquals(array(new CSSSelector('#test .help', true)), $oDoc->getSelectorsBySpecificity('> 100')); + } + + function testManipulation() { + $oDoc = $this->parsedStructureForFile('atrules'); + $this->assertSame('@charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}html, body {font-size: 1.6em;}'."\n", $oDoc->__toString()); + foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { + foreach($oBlock->getSelectors() as $oSelector) { + //Loop over all selector parts (the comma-separated strings in a selector) and prepend the id + $oSelector->setSelector('#my_id '.$oSelector->getSelector()); + } + } + $this->assertSame('@charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}#my_id html, #my_id body {font-size: 1.6em;}'."\n", $oDoc->__toString()); + + $oDoc = $this->parsedStructureForFile('values'); + $this->assertSame('#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;font-size: 10px;color: red !important;} +body {color: green;font: 75% "Lucida Grande","Trebuchet MS",Verdana,sans-serif;}'."\n", $oDoc->__toString()); + foreach($oDoc->getAllRuleSets() as $oRuleSet) { + $oRuleSet->removeRule('font-'); + } + $this->assertSame('#header {margin: 10px 2em 1cm 2%;color: red !important;} +body {color: green;}'."\n", $oDoc->__toString()); + } + + function testSlashedValues() { + $oDoc = $this->parsedStructureForFile('slashed'); + $this->assertSame('.test {font: 12px/1.5 Verdana,Arial,sans-serif;border-radius: 5px 10px 5px 10px/10px 5px 10px 5px;}'."\n", $oDoc->__toString()); + foreach($oDoc->getAllValues(null) as $mValue) { + if($mValue instanceof CSSSize && $mValue->isSize() && !$mValue->isRelative()) { + $mValue->setSize($mValue->getSize()*3); + } + } + foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { + $oRule = $oBlock->getRules('font'); + $oRule = $oRule['font']; + $oSpaceList = $oRule->getValue(); + $this->assertEquals(' ', $oSpaceList->getListSeparator()); + $oSlashList = $oSpaceList->getListComponents(); + $oCommaList = $oSlashList[1]; + $oSlashList = $oSlashList[0]; + $this->assertEquals(',', $oCommaList->getListSeparator()); + $this->assertEquals('/', $oSlashList->getListSeparator()); + $oRule = $oBlock->getRules('border-radius'); + $oRule = $oRule['border-radius']; + $oSlashList = $oRule->getValue(); + $this->assertEquals('/', $oSlashList->getListSeparator()); + $oSpaceList1 = $oSlashList->getListComponents(); + $oSpaceList2 = $oSpaceList1[1]; + $oSpaceList1 = $oSpaceList1[0]; + $this->assertEquals(' ', $oSpaceList1->getListSeparator()); + $this->assertEquals(' ', $oSpaceList2->getListSeparator()); + } + $this->assertSame('.test {font: 36px/1.5 Verdana,Arial,sans-serif;border-radius: 15px 30px 15px 30px/30px 15px 30px 15px;}'."\n", $oDoc->__toString()); + } + + function testFunctionSyntax() { + $oDoc = $this->parsedStructureForFile('functions'); + $sExpected = 'div.main {background-image: linear-gradient(rgb(0,0,0),rgb(255,255,255));} +.collapser::before, .collapser::-moz-before, .collapser::-webkit-before {content: "»";font-size: 1.2em;margin-right: 0.2em;-moz-transition-property: -moz-transform;-moz-transition-duration: 0.2s;-moz-transform-origin: center 60%;} +.collapser.expanded::before, .collapser.expanded::-moz-before, .collapser.expanded::-webkit-before {-moz-transform: rotate(90deg);} +.collapser + * {height: 0;overflow: hidden;-moz-transition-property: height;-moz-transition-duration: 0.3s;} +.collapser.expanded + * {height: auto;}'."\n"; + $this->assertSame($sExpected, $oDoc->__toString()); + + foreach($oDoc->getAllValues(null, true) as $mValue) { + if($mValue instanceof CSSSize && $mValue->isSize()) { + $mValue->setSize($mValue->getSize()*3); + } + } + $sExpected = str_replace(array('1.2em', '0.2em', '60%'), array('3.6em', '0.6em', '180%'), $sExpected); + $this->assertSame($sExpected, $oDoc->__toString()); + + foreach($oDoc->getAllValues(null, true) as $mValue) { + if($mValue instanceof CSSSize && !$mValue->isRelative() && !$mValue->isColorComponent()) { + $mValue->setSize($mValue->getSize()*2); + } + } + $sExpected = str_replace(array('0.2s', '0.3s', '90deg'), array('0.4s', '0.6s', '180deg'), $sExpected); + $this->assertSame($sExpected, $oDoc->__toString()); + } + + function testExpandShorthands() { + $oDoc = $this->parsedStructureForFile('expand-shorthands'); + $sExpected = 'body {font: italic 500 14px/1.618 "Trebuchet MS",Georgia,serif;border: 2px solid rgb(255,0,255);background: rgb(204,204,204) url("/images/foo.png") no-repeat left top;margin: 1em !important;padding: 2px 6px 3px;}'."\n"; + $this->assertSame($sExpected, $oDoc->__toString()); + $oDoc->expandShorthands(); + $sExpected = 'body {margin-top: 1em !important;margin-right: 1em !important;margin-bottom: 1em !important;margin-left: 1em !important;padding-top: 2px;padding-right: 6px;padding-bottom: 3px;padding-left: 6px;border-top-color: rgb(255,0,255);border-right-color: rgb(255,0,255);border-bottom-color: rgb(255,0,255);border-left-color: rgb(255,0,255);border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-width: 2px;border-right-width: 2px;border-bottom-width: 2px;border-left-width: 2px;font-style: italic;font-variant: normal;font-weight: 500;font-size: 14px;line-height: 1.618;font-family: "Trebuchet MS",Georgia,serif;background-color: rgb(204,204,204);background-image: url("/images/foo.png");background-repeat: no-repeat;background-attachment: scroll;background-position: left top;}'."\n"; + $this->assertSame($sExpected, $oDoc->__toString()); + } + + function testCreateShorthands() { + $oDoc = $this->parsedStructureForFile('create-shorthands'); + $sExpected = 'body {font-size: 2em;font-family: Helvetica,Arial,sans-serif;font-weight: bold;border-width: 2px;border-color: rgb(153,153,153);border-style: dotted;background-color: rgb(255,255,255);background-image: url("foobar.png");background-repeat: repeat-y;margin-top: 2px;margin-right: 3px;margin-bottom: 4px;margin-left: 5px;}'."\n"; + $this->assertSame($sExpected, $oDoc->__toString()); + $oDoc->createShorthands(); + $sExpected = 'body {background: rgb(255,255,255) url("foobar.png") repeat-y;margin: 2px 5px 4px 3px;border: 2px dotted rgb(153,153,153);font: bold 2em Helvetica,Arial,sans-serif;}'."\n"; + $this->assertSame($sExpected, $oDoc->__toString()); + } + + function testListValueRemoval() { + $oDoc = $this->parsedStructureForFile('atrules'); + foreach($oDoc->getContents() as $oItem) { + if($oItem instanceof CSSAtRule) { + $oDoc->remove($oItem); + break; + } + } + $this->assertSame('@charset "utf-8";html, body {font-size: 1.6em;}'."\n", $oDoc->__toString()); + + $oDoc = $this->parsedStructureForFile('nested'); + foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { + $oDoc->removeDeclarationBlockBySelector($oBlock, false); + break; + } + $this->assertSame('html {some-other: -test(val1);} +@media screen {html {some: -test(val2);} +}#unrelated {other: yes;}'."\n", $oDoc->__toString()); + + $oDoc = $this->parsedStructureForFile('nested'); + foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { + $oDoc->removeDeclarationBlockBySelector($oBlock, true); + break; + } + $this->assertSame('@media screen {html {some: -test(val2);} +}#unrelated {other: yes;}'."\n", $oDoc->__toString()); + } + + function parsedStructureForFile($sFileName) { + $sFile = dirname(__FILE__).DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR."$sFileName.css"; + $oParser = new CSSParser(file_get_contents($sFile)); + return $oParser->parse(); + } + +} diff --git a/phpQuery/CSSParser/tests/files/-tobedone.css b/phpQuery/CSSParser/tests/files/-tobedone.css new file mode 100755 index 0000000..7ec1da9 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/-tobedone.css @@ -0,0 +1,7 @@ +.some[selectors-may='contain-a-{'] { + +} + +.some { + filters: may(contain, a, ')'); +} diff --git a/phpQuery/CSSParser/tests/files/atrules.css b/phpQuery/CSSParser/tests/files/atrules.css new file mode 100755 index 0000000..adfa9f9 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/atrules.css @@ -0,0 +1,10 @@ +@charset "utf-8"; + +@font-face { + font-family: "CrassRoots"; + src: url("../media/cr.ttf") +} + +html, body { + font-size: 1.6em +} diff --git a/phpQuery/CSSParser/tests/files/colortest.css b/phpQuery/CSSParser/tests/files/colortest.css new file mode 100755 index 0000000..41fe2a2 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/colortest.css @@ -0,0 +1,10 @@ +#mine { + color: red; + border-color: rgba(10, 100, 230, 0.3); + outline-color: #222; + background-color: #232323; +} + +#yours { + background-color: hsl(220, 10, 220); +} diff --git a/phpQuery/CSSParser/tests/files/create-shorthands.css b/phpQuery/CSSParser/tests/files/create-shorthands.css new file mode 100755 index 0000000..c784d67 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/create-shorthands.css @@ -0,0 +1,7 @@ +body +{ + font-size: 2em; font-family: Helvetica,Arial,sans-serif; font-weight: bold; + border-width: 2px; border-color: #999; border-style: dotted; + background-color: #fff; background-image: url('foobar.png'); background-repeat: repeat-y; + margin-top: 2px; margin-right: 3px; margin-bottom: 4px; margin-left: 5px; +} diff --git a/phpQuery/CSSParser/tests/files/expand-shorthands.css b/phpQuery/CSSParser/tests/files/expand-shorthands.css new file mode 100755 index 0000000..89aab1e --- /dev/null +++ b/phpQuery/CSSParser/tests/files/expand-shorthands.css @@ -0,0 +1,7 @@ +body { + font: italic 500 14px/1.618 "Trebuchet MS", Georgia, serif; + border: 2px solid #f0f; + background: #ccc url("/images/foo.png") no-repeat left top; + margin: 1em !important; + padding: 2px 6px 3px; +} diff --git a/phpQuery/CSSParser/tests/files/functions.css b/phpQuery/CSSParser/tests/files/functions.css new file mode 100755 index 0000000..eabbd24 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/functions.css @@ -0,0 +1,22 @@ +div.main { background-image: linear-gradient(#000, #fff) } +.collapser::before, +.collapser::-moz-before, +.collapser::-webkit-before { + content: "»"; + font-size: 1.2em; + margin-right: .2em; + -moz-transition-property: -moz-transform; + -moz-transition-duration: .2s; + -moz-transform-origin: center 60%; +} +.collapser.expanded::before, +.collapser.expanded::-moz-before, +.collapser.expanded::-webkit-before { -moz-transform: rotate(90deg) } +.collapser + * { + height: 0; + overflow: hidden; + -moz-transition-property: height; + -moz-transition-duration: .3s; +} +.collapser.expanded + * { height: auto } + diff --git a/phpQuery/CSSParser/tests/files/ie.css b/phpQuery/CSSParser/tests/files/ie.css new file mode 100755 index 0000000..6c0fb38 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/ie.css @@ -0,0 +1,6 @@ +.nav-thumb-wrapper:hover img, a.activeSlide img { + filter: alpha(opacity=100); + -moz-opacity: 1; + -khtml-opacity: 1; + opacity: 1; +} diff --git a/phpQuery/CSSParser/tests/files/important.css b/phpQuery/CSSParser/tests/files/important.css new file mode 100755 index 0000000..edf24a8 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/important.css @@ -0,0 +1,8 @@ +div.rating-cancel,div.star-rating{float:left;width:17px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden} +div.rating-cancel,div.rating-cancel a{background:url(images/delete.gif) no-repeat 0 -16px} +div.star-rating,div.star-rating a{background:url(images/star.gif) no-repeat 0 0px} +div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0} +div.star-rating-on a{background-position:0 -16px!important} +div.star-rating-hover a{background-position:0 -32px} +div.star-rating-readonly a{cursor:default !important} +div.star-rating{background:transparent!important; overflow:hidden!important} \ No newline at end of file diff --git a/phpQuery/CSSParser/tests/files/nested.css b/phpQuery/CSSParser/tests/files/nested.css new file mode 100755 index 0000000..b59dc80 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/nested.css @@ -0,0 +1,17 @@ +html { + some: -test(val1); +} + +html { + some-other: -test(val1); +} + +@media screen { + html { + some: -test(val2); + } +} + +#unrelated { + other: yes; +} diff --git a/phpQuery/CSSParser/tests/files/slashed.css b/phpQuery/CSSParser/tests/files/slashed.css new file mode 100755 index 0000000..5b629be --- /dev/null +++ b/phpQuery/CSSParser/tests/files/slashed.css @@ -0,0 +1,4 @@ +.test { + font: 12px/1.5 Verdana, Arial, sans-serif; + border-radius: 5px 10px 5px 10px / 10px 5px 10px 5px; +} diff --git a/phpQuery/CSSParser/tests/files/specificity.css b/phpQuery/CSSParser/tests/files/specificity.css new file mode 100755 index 0000000..82a2939 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/specificity.css @@ -0,0 +1,7 @@ +#test .help, +#file, +.help:hover, +li.green, +ol li::before { + font-family: Helvetica; +} diff --git a/phpQuery/CSSParser/tests/files/unicode.css b/phpQuery/CSSParser/tests/files/unicode.css new file mode 100755 index 0000000..2482320 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/unicode.css @@ -0,0 +1,12 @@ +.test-1 { content: "\20"; } /* Same as " " */ +.test-2 { content: "\E9"; } /* Same as "é" */ +.test-3 { content: "\0020"; } /* Same as " " */ +.test-5 { content: "\6C34" } /* Same as "水" */ +.test-6 { content: "\00A5" } /* Same as "¥" */ +.test-7 { content: '\a' } /* Same as "\A" (Newline) */ +.test-8 { content: "\"\22" } /* Same as "\"\"" */ +.test-9 { content: "\"\27" } /* Same as ""\"\'"" */ +.test-10 { content: "\'\\" } /* Same as "'\" */ +.test-11 { content: "\test" } /* Same as "test" */ + +.test-4 { content: "\1D11E" } /* Beyond the Basic Multilingual Plane */ diff --git a/phpQuery/CSSParser/tests/files/values.css b/phpQuery/CSSParser/tests/files/values.css new file mode 100755 index 0000000..1f41863 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/values.css @@ -0,0 +1,11 @@ +#header { + margin: 10px 2em 1cm 2%; + font-family: Verdana, Helvetica, "Gill Sans", sans-serif; + font-size: 10px; + color: red !important; +} + +body { + color: green; + font: 75% "Lucida Grande", "Trebuchet MS", Verdana, sans-serif; +} diff --git a/phpQuery/CSSParser/tests/files/whitespace.css b/phpQuery/CSSParser/tests/files/whitespace.css new file mode 100755 index 0000000..6b21c24 --- /dev/null +++ b/phpQuery/CSSParser/tests/files/whitespace.css @@ -0,0 +1,3 @@ +.test { + background-image : url ( 4px ) ; +} diff --git a/phpQuery/CSSParser/tests/quickdump.php b/phpQuery/CSSParser/tests/quickdump.php new file mode 100755 index 0000000..071a72b --- /dev/null +++ b/phpQuery/CSSParser/tests/quickdump.php @@ -0,0 +1,15 @@ +parse(); + +echo '#### Structure (`var_dump()`)'."\n"; +var_dump($oDoc); + +echo '#### Output (`__toString()`)'."\n"; +print $oDoc->__toString(); +echo "\n"; + diff --git a/phpQuery/phpQuery.php b/phpQuery/phpQuery.php index be094d7..8f2d55b 100644 --- a/phpQuery/phpQuery.php +++ b/phpQuery/phpQuery.php @@ -24,6 +24,7 @@ require_once(dirname(__FILE__).'/phpQuery/Callback.php'); require_once(dirname(__FILE__).'/phpQuery/phpQueryObject.php'); require_once(dirname(__FILE__).'/phpQuery/compat/mbstring.php'); +require_once(dirname(__FILE__).'/CSSParser/CSSParser.php'); /** * Static namespace for phpQuery functions. * diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index 51087a4..39be085 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -75,11 +75,30 @@ class phpQueryObject * @access private */ protected $current = null; + + /** + * Indicates whether CSS has been parsed or not. We only parse CSS if needed. + * @access private + */ + protected $cssIsParsed = array(); + /** + * A collection of complete CSS selector strings. + * @access private; + */ + protected $cssString = array(); /** * Enter description here... * * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ + + protected $attribute_css_mapping = array( + 'bgcolor' => 'background-color', + 'text' => 'color', + 'width' => 'width', + 'height' => 'height' + ); + public function __construct($documentID) { // if ($documentID instanceof self) // var_dump($documentID->getDocumentID()); @@ -1362,22 +1381,132 @@ public function __loadSuccess($html) { ->markup($html); } } + /** - * Enter description here... + * Allows users to enter strings of CSS selectors. Useful + * when the CSS is loaded via style or @imports that phpQuery can't load + * because it doesn't know the URL context of the request. + */ + public function addCSS($string) { + if(!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = ''; + } + $this->cssString[$this->getDocumentID()] .= $string; + $this->parseCSS(); + } + /** + * Either sets the CSS property of an object or retrieves the + * CSS property of a proejct. * - * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @return string of css property value * @todo */ - public function css() { - // TODO - return $this; + public function css($property_name, $value = FALSE) { + if(!isset($this->cssIsParsed[$this->getDocumentID()]) || $this->cssIsParsed[$this->getDocumentID()] = false) { + $this->parseCSS(); + } + $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); + if(!$value) { + if(isset($data[$property_name])) { + return $data[$property_name]['value']; + } + return null; + } + $specificity = (isset($data[$property_name])) + ? $data[$property_name]['specificity'] + 1 + : 1000; + $data[$property_name] = array('specificity' => $specificity, 'value' => $value); + phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); + $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); + } + + public function parseCSS() { + if(!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) .'/default.css'); + } + foreach(phpQuery::pq('style', $this->getDocumentID()) as $style) { + $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); + } + + $CssParser = new CSSParser($this->cssString[$this->getDocumentID()]); + $CssDocument = $CssParser->parse(); + foreach($CssDocument->getAllRuleSets() as $ruleset) { + foreach($ruleset->getSelector() as $selector) { + $specificity = $selector->getSpecificity(); + foreach(phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + $ruleset->expandShorthands(); + foreach($ruleset->getRules() as $rule => $value) { + if(!isset($existing[$rule]) || $existing[$rule]['specificity'] <= $specificity) { + $value = $value->getValue(); + $value = (is_object($value)) + ? $value->__toString() + : $value; + $existing[$rule] = array('specificity' => $specificity, + 'value' => $value); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); + } + } + } + foreach(phpQuery::pq('*', $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + $style = pq($el)->attr('style'); + $style = strlen($style) ? explode(';', $style) : array(); + foreach($this->attribute_css_mapping as $map => $css_equivalent) { + if($el->hasAttribute($map)) { + $style[] = $css_equivalent .':'. pq($el)->attr($map); + } + } + if(count($style)) { + $CssParser = new CSSParser('#ruleset {'. implode(';', $style) .'}'); + $CssDocument = $CssParser->parse(); + $ruleset = $CssDocument->getAllRulesets(); + $ruleset = reset($ruleset); + $ruleset->expandShorthands(); + foreach($ruleset->getRules() as $rule => $value) { + if(!isset($existing[$rule]) || 1000 >= $existing[$rule]['specificity']) { + $value = $value->getValue(); + $value = (is_object($value)) + ? $value->__toString() + : $value; + $existing[$rule] = array('specificity' => 1000, + 'value' => $value); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); + } + } } + + protected function bubbleCSS($element) { + $style = $element->data('phpquery_css'); + foreach($element->children() as $element_child) { + $existing = phpQuery::pq($element_child)->data('phpquery_css'); + foreach($style as $rule => $value) { + if(!isset($existing[$rule]) || $value['specificity'] > $existing[$rule]['specificity']) { + $existing[$rule] = $value; + } + } + phpQuery::pq($element_child)->data('phpquery_css', $existing); + if(phpQuery::pq($element_child)->children()->length) { + $this->bubbleCSS(phpQuery::pq($element_child)); + } + } + } + /** * @todo * */ public function show(){ - // TODO + $display = ($this->data('phpquery_display_state')) + ? $this->data('phpquery_display_state') + : 'block'; + $this->css('display', $display); return $this; } /** @@ -1385,7 +1514,8 @@ public function show(){ * */ public function hide(){ - // TODO + $this->data('phpquery_display_state', $this->css('display')); + $this->css('display', 'none'); return $this; } /** From d8710f71bc1ec97d1db75f19a1e7f4cf544a63f8 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 07:57:13 -0600 Subject: [PATCH 22/59] Updated composer for wittiws repository. --- composer.json | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index 2ea5d66..8c8acc7 100644 --- a/composer.json +++ b/composer.json @@ -1,24 +1,35 @@ { - "name": "electrolinux/phpquery" - ,"type": "library" - ,"description": "phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library" - ,"version": "0.9.6" - ,"keywords": [] - ,"homepage": "http://code.google.com/p/phpquery/" - ,"license": "MIT" - ,"authors": [ + "name":"wittiws/phpquery", + "type":"library", + "description":"phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library", + "version":"0.9.6", + "keywords":[ + + ] + , + "homepage":"http://code.google.com/p/phpquery/", + "license":"MIT", + "authors":[ { - "name": "Tobiasz Cudnik" - ,"email": "tobiasz.cudnik@gmail.com" - ,"homepage": "https://github.com/TobiaszCudnik" - ,"role": "Developer" + "name":"Tobiasz Cudnik", + "email":"tobiasz.cudnik@gmail.com", + "homepage":"https://github.com/TobiaszCudnik", + "role":"Developer" } - ,{ - "name": "didier Belot" - ,"role": "Packager" + , + { + "name":"didier Belot", + "role":"Packager" + } + , + { + "name":"Greg Payne", + "role":"Packager" } ], - "autoload": { - "classmap": ["phpQuery/"] + "autoload":{ + "classmap":[ + "phpQuery/" + ] } -} +} \ No newline at end of file From 117608c442ca3c6cabda39c3445df28c8fa6b4c5 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 08:01:04 -0600 Subject: [PATCH 23/59] Added the sabberworm/php-css-parser package. --- .gitignore | 2 ++ composer.json | 4 ++++ 2 files changed, 6 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1502b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +vendor/ +composer.lock diff --git a/composer.json b/composer.json index 8c8acc7..f6819a0 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,10 @@ "role":"Packager" } ], + "require":{ + "php":">=5.3.3", + "sabberworm/php-css-parser":"5.1.*" + }, "autoload":{ "classmap":[ "phpQuery/" From 9ad9b85987f87e9ddc4cdae200c50a8d4e70cf0a Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 13:32:34 -0600 Subject: [PATCH 24/59] Corrected the existing unit tests (1 was broken). --- unit-tests/test.html | 2 +- unit-tests/test.php | 23 +++++++---------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/unit-tests/test.html b/unit-tests/test.html index 03d7c78..a1c89ea 100644 --- a/unit-tests/test.html +++ b/unit-tests/test.html @@ -11,7 +11,7 @@
    div.articles text node - < +
    • This is paragraph of first LI

      diff --git a/unit-tests/test.php b/unit-tests/test.php index 938aeb6..a1e5149 100644 --- a/unit-tests/test.php +++ b/unit-tests/test.php @@ -1,6 +1,5 @@ find('li') ->slice(1, 2); - + $this->assertTrue( $pq->whois() == $testResult ); } @@ -62,7 +61,7 @@ function testSlice2( $pq ) { $pq = $pq->find('li') ->slice(1, -1); - + $this->assertTrue( $pq->whois() == $testResult ); } @@ -107,7 +106,7 @@ function testClone( $pq ) { $document = null; $pq = $pq->toReference($document) ->find('p:first'); - + foreach(array(0,1,2) as $i) { $pq->clone() ->addClass("clone-test") @@ -166,7 +165,7 @@ function testSimpleDataInsertion( $pq ) {

      News 3 body

    -

    paragraph after UL

    +

    paragraph after UL

    EOF; $rows = array( @@ -197,18 +196,10 @@ function testSimpleDataInsertion( $pq ) { $row->appendTo($articles); } $result = $pq->find('.articles')->htmlOuter(); - //print htmlspecialchars("
    {$result}
    ").'
    '; - $similarity = 0.0; - similar_text($testResult, $result, $similarity); +// print htmlspecialchars("
    {$result}
    ").'
    '; - $this->assertGreaterThan( 90, $similarity); + $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); } - - -// function __construct() { -// xdebug_break(); -// parent::__construct(); -// } } $test = new phpQueryBasicTest(); From 3e28092cb90af0b31f23babad400b0d067bc2f57 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 14:47:34 -0600 Subject: [PATCH 25/59] Closes #3. Fixes phpQuery to use CSSParser. One unit test. --- phpQuery/phpQuery.php | 7 +- phpQuery/phpQuery/default.css | 81 +++++++++++ phpQuery/phpQuery/phpQueryObject.php | 208 ++++++++++++++++----------- unit-tests/test.php | 21 +++ 4 files changed, 229 insertions(+), 88 deletions(-) create mode 100644 phpQuery/phpQuery/default.css diff --git a/phpQuery/phpQuery.php b/phpQuery/phpQuery.php index 8f2d55b..9f2b21c 100644 --- a/phpQuery/phpQuery.php +++ b/phpQuery/phpQuery.php @@ -33,8 +33,8 @@ */ abstract class phpQuery { /** - * XXX: Workaround for mbstring problems - * + * XXX: Workaround for mbstring problems + * * @var bool */ public static $mbstringSupport = true; @@ -109,6 +109,9 @@ abstract class phpQuery { public static $lastModified = null; public static $active = 0; public static $dumpCount = 0; + public static $enableCssShorthand = FALSE; + + /** * Multi-purpose function. * Use pq() as shortcut. diff --git a/phpQuery/phpQuery/default.css b/phpQuery/phpQuery/default.css new file mode 100644 index 0000000..5fb4aac --- /dev/null +++ b/phpQuery/phpQuery/default.css @@ -0,0 +1,81 @@ +html, address, +blockquote, +body, dd, div, +dl, dt, fieldset, form, +frame, frameset, +h1, h2, h3, h4, +h5, h6, noframes, +ol, p, ul, center, +dir, hr, menu, pre { display: block; unicode-bidi: embed } +span { display: inline } +li { display: list-item } +head { display: none } +table { display: table } +tr { display: table-row } +thead { display: table-header-group } +tbody { display: table-row-group } +tfoot { display: table-footer-group } +col { display: table-column } +colgroup { display: table-column-group } +td, th { display: table-cell } +caption { display: table-caption } +th { font-weight: bolder; text-align: center } +caption { text-align: center } +body { margin: 8px; color: #000; background-color: #fff; font-size: 16px;} +h1 { font-size: 2em; margin: .67em 0 } +h2 { font-size: 1.5em; margin: .75em 0 } +h3 { font-size: 1.17em; margin: .83em 0 } +h4, p, +blockquote, ul, +fieldset, form, +ol, dl, dir, +menu { margin: 1.12em 0 } +h5 { font-size: .83em; margin: 1.5em 0 } +h6 { font-size: .75em; margin: 1.67em 0 } +h1, h2, h3, h4, +h5, h6, b, +strong { font-weight: bolder; display: inline; } +blockquote { margin-left: 40px; margin-right: 40px } +a { color: #0000ff; } +i, cite, em, +var, address { font-style: italic } +i, cite, em { display: inline } +pre, tt, code, +kbd, samp { font-family: monospace } +pre { white-space: pre } +button, textarea, +input, select { display: inline-block } +big { font-size: 1.17em; display: inline; } +small, sub, sup { font-size: .83em; display: inline; } +sub { vertical-align: sub } +sup { vertical-align: super } +table { border-spacing: 2px; } +thead, tbody, +tfoot { vertical-align: middle } +td, th, tr { vertical-align: inherit } +s, strike, del { text-decoration: line-through } +hr { border: 1px inset } +ol, ul, dir, +menu, dd { margin-left: 40px } +ol { list-style-type: decimal } +ol ul, ul ol, +ul ul, ol ol { margin-top: 0; margin-bottom: 0 } +u, ins { text-decoration: underline } +br:before { content: "\A"; white-space: pre-line } +center { text-align: center } +:link, :visited { text-decoration: underline } +:focus { outline: thin dotted invert } + +/* Begin bidirectionality settings (do not change) */ +BDO[DIR="ltr"] { direction: ltr; unicode-bidi: bidi-override } +BDO[DIR="rtl"] { direction: rtl; unicode-bidi: bidi-override } + +*[DIR="ltr"] { direction: ltr; unicode-bidi: embed } +*[DIR="rtl"] { direction: rtl; unicode-bidi: embed } + +@media print { + h1 { page-break-before: always } + h1, h2, h3, + h4, h5, h6 { page-break-after: avoid } + ul, ol, dl { page-break-before: avoid } +} \ No newline at end of file diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php index 39be085..7adf53f 100644 --- a/phpQuery/phpQuery/phpQueryObject.php +++ b/phpQuery/phpQuery/phpQueryObject.php @@ -1,4 +1,5 @@ 'background-color', 'text' => 'color', 'width' => 'width', 'height' => 'height' ); - + public function __construct($documentID) { // if ($documentID instanceof self) // var_dump($documentID->getDocumentID()); @@ -1381,7 +1382,7 @@ public function __loadSuccess($html) { ->markup($html); } } - + /** * Allows users to enter strings of CSS selectors. Useful * when the CSS is loaded via style or @imports that phpQuery can't load @@ -1401,87 +1402,122 @@ public function addCSS($string) { * @return string of css property value * @todo */ - public function css($property_name, $value = FALSE) { - if(!isset($this->cssIsParsed[$this->getDocumentID()]) || $this->cssIsParsed[$this->getDocumentID()] = false) { - $this->parseCSS(); - } - $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); - if(!$value) { - if(isset($data[$property_name])) { - return $data[$property_name]['value']; - } - return null; - } - $specificity = (isset($data[$property_name])) - ? $data[$property_name]['specificity'] + 1 - : 1000; - $data[$property_name] = array('specificity' => $specificity, 'value' => $value); - phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); - $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); - } - - public function parseCSS() { - if(!isset($this->cssString[$this->getDocumentID()])) { - $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) .'/default.css'); - } - foreach(phpQuery::pq('style', $this->getDocumentID()) as $style) { - $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); - } - - $CssParser = new CSSParser($this->cssString[$this->getDocumentID()]); - $CssDocument = $CssParser->parse(); - foreach($CssDocument->getAllRuleSets() as $ruleset) { - foreach($ruleset->getSelector() as $selector) { - $specificity = $selector->getSpecificity(); - foreach(phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - $ruleset->expandShorthands(); - foreach($ruleset->getRules() as $rule => $value) { - if(!isset($existing[$rule]) || $existing[$rule]['specificity'] <= $specificity) { - $value = $value->getValue(); - $value = (is_object($value)) - ? $value->__toString() - : $value; - $existing[$rule] = array('specificity' => $specificity, - 'value' => $value); - } - } - phpQuery::pq($el)->data('phpquery_css', $existing); + public function css($property_name, $value = FALSE) { + if (!isset($this->cssIsParsed[$this->getDocumentID()]) + || $this->cssIsParsed[$this->getDocumentID()] = false) { + $this->parseCSS(); + } + $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); + if (!$value) { + if (isset($data[$property_name])) { + return $data[$property_name]['value']; + } + return null; + } + $specificity = (isset($data[$property_name])) ? $data[$property_name]['specificity'] + + 1 : 1000; + $data[$property_name] = array( + 'specificity' => $specificity, + 'value' => $value + ); + phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); + $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); + + if ($specificity >= 1000) { + $styles = array(); + foreach ($this->data('phpquery_css') as $k => $v) { + if ($v['specificity'] >= 1000) { + $styles[$k] = trim($k) . ':' . trim($v['value']); + } + } + ksort($styles); + if (empty($styles)) { + $this->removeAttr('style'); + } + elseif (phpQuery::$enableCssShorthand) { + $parser = new Sabberworm\CSS\Parser('{' . join(';', $styles) . '}'); + $doc = $parser->parse(); + $doc->createShorthands(); + $style = trim($doc->__toString(), "\n\r\t {}"); + } + else { + $style = join(';', $styles); + } + $this->attr('style', $style); + } + } + + public function parseCSS() { + if (!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) + . '/default.css'); + } + foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) { + $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); + } + + $CssParser = new CssParser($this->cssString[$this->getDocumentID()]); + $CssDocument = $CssParser->parse(); + foreach ($CssDocument->getAllRuleSets() as $ruleset) { + foreach ($ruleset->getSelector() as $selector) { + $specificity = $selector->getSpecificity(); + foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || $existing[$rule]['specificity'] <= $specificity) { + $value = $value->getValue(); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => $specificity, + 'value' => $value + ); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); $this->bubbleCSS(phpQuery::pq($el)); - } - } - } - foreach(phpQuery::pq('*', $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - $style = pq($el)->attr('style'); - $style = strlen($style) ? explode(';', $style) : array(); - foreach($this->attribute_css_mapping as $map => $css_equivalent) { - if($el->hasAttribute($map)) { - $style[] = $css_equivalent .':'. pq($el)->attr($map); - } - } - if(count($style)) { - $CssParser = new CSSParser('#ruleset {'. implode(';', $style) .'}'); - $CssDocument = $CssParser->parse(); - $ruleset = $CssDocument->getAllRulesets(); - $ruleset = reset($ruleset); - $ruleset->expandShorthands(); - foreach($ruleset->getRules() as $rule => $value) { - if(!isset($existing[$rule]) || 1000 >= $existing[$rule]['specificity']) { + } + } + } + foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + $style = pq($el)->attr('style'); + $style = strlen($style) ? explode(';', $style) : array(); + foreach ($this->attribute_css_mapping as $map => $css_equivalent) { + if ($el->hasAttribute($map)) { + $style[] = $css_equivalent . ':' . pq($el)->attr($map); + } + } + if (count($style)) { + $CssParser = new CssParser('#ruleset {' . implode(';', $style) . '}'); + $CssDocument = $CssParser->parse(); + $ruleset = $CssDocument->getAllRulesets(); + $ruleset = reset($ruleset); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || 1000 >= $existing[$rule]['specificity']) { $value = $value->getValue(); - $value = (is_object($value)) - ? $value->__toString() - : $value; - $existing[$rule] = array('specificity' => 1000, - 'value' => $value); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => 1000, + 'value' => $value + ); } } phpQuery::pq($el)->data('phpquery_css', $existing); $this->bubbleCSS(phpQuery::pq($el)); } - } - } - + } + } + protected function bubbleCSS($element) { $style = $element->data('phpquery_css'); foreach($element->children() as $element_child) { @@ -1497,7 +1533,7 @@ protected function bubbleCSS($element) { } } } - + /** * @todo * @@ -2010,7 +2046,7 @@ public function php($code = null) { } /** * Enter description here... - * + * * @param $code * @return unknown_type */ @@ -2021,7 +2057,7 @@ public function markupPHP($code = null) { } /** * Enter description here... - * + * * @param $code * @return unknown_type */ @@ -2396,7 +2432,7 @@ public function text($text = null, $callback1 = null, $callback2 = null, $callba } return $return; } - + /** * @return The text content of each matching element, like * text() but returns an array with one entry per matched element. @@ -2409,7 +2445,7 @@ public function texts($attr = null) { } return $results; } - + /** * Enter description here... * @@ -2777,7 +2813,7 @@ public function attr($attr = null, $value = null) { return is_null($value) ? '' : $this; } - + /** * @return The same attribute of each matching element, like * attr() but returns an array with one entry per matched element. @@ -3081,7 +3117,7 @@ public function map($callback, $param1 = null, $param2 = null, $param3 = null) { } /** * Enter description here... - * + * * @param $key * @param $value */ @@ -3098,7 +3134,7 @@ public function data($key, $value = null) { } /** * Enter description here... - * + * * @param $key */ public function removeData($key) { diff --git a/unit-tests/test.php b/unit-tests/test.php index a1e5149..a927c2e 100644 --- a/unit-tests/test.php +++ b/unit-tests/test.php @@ -1,5 +1,6 @@ assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + public function testCssParser() { + phpQuery::$enableCssShorthand = FALSE; + + $expected_html = '
    Hello World!
    '; + $expected_pq = phpQuery::newDocumentHTML($expected_html); + + $test_pq = phpQuery::newDocumentHTML('
    '); + $test = pq('div'); + $test->append('Hello World!'); + $test->hide(); + $test->css('color', 'red'); + $test->css('margin', '20px'); + $this->assertEqualXMLStructure($expected_pq->find('div')->elements[0], $test->elements[0]); + } } $test = new phpQueryBasicTest(); From b991bb927720a884c93f59ca79c47d26649fcbeb Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 14:48:06 -0600 Subject: [PATCH 26/59] Added autoload file for reference by phpunit. --- autoload.php.dist | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 autoload.php.dist diff --git a/autoload.php.dist b/autoload.php.dist new file mode 100644 index 0000000..3fa4e46 --- /dev/null +++ b/autoload.php.dist @@ -0,0 +1,3 @@ + Date: Fri, 7 Mar 2014 14:50:50 -0600 Subject: [PATCH 27/59] Configured phpunit to run from the project main directory. --- phpunit.xml.dist | 31 +++++++++++++++++++++++++++++++ unit-tests/test.php | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 phpunit.xml.dist diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..2a493cb --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + + + ./unit-tests/test.php + + + + + + benchmark + + + diff --git a/unit-tests/test.php b/unit-tests/test.php index a927c2e..6465ca0 100644 --- a/unit-tests/test.php +++ b/unit-tests/test.php @@ -7,7 +7,7 @@ class phpQueryBasicTest extends PHPUnit_Framework_TestCase { function provider() { // TODO change filename return array( array( - phpQuery::newDocumentFile('test.html') + phpQuery::newDocumentFile(__DIR__ . '/test.html') )); } From 52ffc8047875414a80bdc6f4bc0a81bba836d76f Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 14:57:39 -0600 Subject: [PATCH 28/59] Removed api-reference and .idea folder as extras. --- .idea/.name | 1 - .idea/compiler.xml | 21 - .idea/copyright/profiles_settings.xml | 5 - .idea/encodings.xml | 5 - .idea/inspectionProfiles/Project_Default.xml | 7 - .../inspectionProfiles/profiles_settings.xml | 7 - .idea/misc.xml | 339 - .idea/modules.xml | 9 - .idea/php.xml | 16 - .idea/phpquery-git.iml | 22 - .idea/vcs.xml | 7 - api-reference/classtrees_phpQuery.html | 91 - api-reference/elementindex.html | 875 --- api-reference/elementindex_phpQuery.html | 907 --- api-reference/errors.html | 89 - api-reference/index.html | 81 - api-reference/li_phpQuery.html | 81 - api-reference/media/background.png | Bin 238 -> 0 bytes api-reference/media/empty.png | Bin 206 -> 0 bytes api-reference/media/style.css | 195 - api-reference/phpQuery/Callback.html | 305 - api-reference/phpQuery/CallbackParam.html | 122 - api-reference/phpQuery/CallbackReference.html | 234 - .../phpQuery/DOMDocumentWrapper.html | 1591 ----- api-reference/phpQuery/DOMEvent.html | 582 -- api-reference/phpQuery/_Callback.php.html | 99 - .../phpQuery/_DOMDocumentWrapper.php.html | 114 - api-reference/phpQuery/_DOMEvent.php.html | 95 - api-reference/phpQuery/_phpQuery.php.html | 223 - .../phpQuery/_phpQueryEvents.php.html | 95 - .../phpQuery/_phpQueryObject.php.html | 95 - api-reference/phpQuery/phpQuery.html | 2754 -------- api-reference/phpQuery/phpQueryEvents.html | 473 -- api-reference/phpQuery/phpQueryObject.html | 6172 ----------------- api-reference/phpQuery/phpQueryPlugins.html | 192 - api-reference/todolist.html | 161 - 36 files changed, 16065 deletions(-) delete mode 100644 .idea/.name delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/copyright/profiles_settings.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/phpquery-git.iml delete mode 100644 .idea/vcs.xml delete mode 100644 api-reference/classtrees_phpQuery.html delete mode 100644 api-reference/elementindex.html delete mode 100644 api-reference/elementindex_phpQuery.html delete mode 100644 api-reference/errors.html delete mode 100644 api-reference/index.html delete mode 100644 api-reference/li_phpQuery.html delete mode 100644 api-reference/media/background.png delete mode 100644 api-reference/media/empty.png delete mode 100644 api-reference/media/style.css delete mode 100644 api-reference/phpQuery/Callback.html delete mode 100644 api-reference/phpQuery/CallbackParam.html delete mode 100644 api-reference/phpQuery/CallbackReference.html delete mode 100644 api-reference/phpQuery/DOMDocumentWrapper.html delete mode 100644 api-reference/phpQuery/DOMEvent.html delete mode 100644 api-reference/phpQuery/_Callback.php.html delete mode 100644 api-reference/phpQuery/_DOMDocumentWrapper.php.html delete mode 100644 api-reference/phpQuery/_DOMEvent.php.html delete mode 100644 api-reference/phpQuery/_phpQuery.php.html delete mode 100644 api-reference/phpQuery/_phpQueryEvents.php.html delete mode 100644 api-reference/phpQuery/_phpQueryObject.php.html delete mode 100644 api-reference/phpQuery/phpQuery.html delete mode 100644 api-reference/phpQuery/phpQueryEvents.html delete mode 100644 api-reference/phpQuery/phpQueryObject.html delete mode 100644 api-reference/phpQuery/phpQueryPlugins.html delete mode 100644 api-reference/todolist.html diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 65a17ac..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -phpquery-git \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index a1b41c5..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index 3572571..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index e206d70..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 4a98b0f..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 3b31283..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index baa89dc..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - http://www.w3.org/1999/xhtml - - - - diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 905e8f1..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.idea/php.xml b/.idea/php.xml deleted file mode 100644 index a65db31..0000000 --- a/.idea/php.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/.idea/phpquery-git.iml b/.idea/phpquery-git.iml deleted file mode 100644 index 0561702..0000000 --- a/.idea/phpquery-git.iml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index c80f219..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/api-reference/classtrees_phpQuery.html b/api-reference/classtrees_phpQuery.html deleted file mode 100644 index 9f70cd9..0000000 --- a/api-reference/classtrees_phpQuery.html +++ /dev/null @@ -1,91 +0,0 @@ - - -Class Trees for Package phpQuery - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class Trees for Package phpQuery

    -
    -
    Root class Callback

    - - -
    -
    Root class CallbackParam

    - - -
    -
    Root class DOMDocumentWrapper

    - - -
    -
    Root class DOMEvent

    - - -
    -
    Root class phpQuery

    - - -
    -
    Root class phpQueryEvents

    - - -
    -
    Root class phpQueryObject

    - - -
    -
    Root class phpQueryPlugins

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/elementindex.html b/api-reference/elementindex.html deleted file mode 100644 index af26bb7..0000000 --- a/api-reference/elementindex.html +++ /dev/null @@ -1,875 +0,0 @@ - - -Element Index - - - - - - - - - - - - - -
    - - [ all elements ] -
    - - - - - - -
    -
    - - -

    Index of all elements

    - [ a ] - [ b ] - [ c ] - [ d ] - [ e ] - [ f ] - [ g ] - [ h ] - [ i ] - [ k ] - [ l ] - [ m ] - [ n ] - [ o ] - [ p ] - [ r ] - [ s ] - [ t ] - [ u ] - [ v ] - [ w ] - [ x ] - [ _ ] - -
    - -
    -

    a

    -
    -
    $active
    -
    in file phpQuery.php, variable phpQuery::$active
    -
    $ajaxAllowedHosts
    -
    in file phpQuery.php, variable phpQuery::$ajaxAllowedHosts
        Hosts allowed for AJAX connections.
    -
    $ajaxSettings
    -
    in file phpQuery.php, variable phpQuery::$ajaxSettings
        AJAX settings.
    -
    add
    -
    in file phpQueryEvents.php, method phpQueryEvents::add()
        Binds a handler to one or more events (like click) for each matched element.
    -
    add
    -
    in file phpQueryObject.php, method phpQueryObject::add()
        Enter description here...
    -
    addClass
    -
    in file phpQueryObject.php, method phpQueryObject::addClass()
        Enter description here...
    -
    addClassPHP
    -
    in file phpQueryObject.php, method phpQueryObject::addClassPHP()
        Enter description here...
    -
    after
    -
    in file phpQueryObject.php, method phpQueryObject::after()
        Enter description here...
    -
    afterMarkupLoad
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::afterMarkupLoad()
    -
    afterPHP
    -
    in file phpQueryObject.php, method phpQueryObject::afterPHP()
        Enter description here...
    -
    ajax
    -
    in file phpQuery.php, method phpQuery::ajax()
        Make an AJAX request.
    -
    ajaxAllowHost
    -
    in file phpQuery.php, method phpQuery::ajaxAllowHost()
    -
    ajaxAllowURL
    -
    in file phpQuery.php, method phpQuery::ajaxAllowURL()
    -
    ajaxSetup
    -
    in file phpQuery.php, method phpQuery::ajaxSetup()
    -
    ancestors
    -
    in file phpQueryObject.php, method phpQueryObject::ancestors()
        Enter description here...
    -
    andSelf
    -
    in file phpQueryObject.php, method phpQueryObject::andSelf()
        Enter description here...
    -
    append
    -
    in file phpQueryObject.php, method phpQueryObject::append()
        Enter description here...
    -
    appendPHP
    -
    in file phpQueryObject.php, method phpQueryObject::appendPHP()
        Enter description here...
    -
    appendTo
    -
    in file phpQueryObject.php, method phpQueryObject::appendTo()
        Enter description here...
    -
    attr
    -
    in file phpQueryObject.php, method phpQueryObject::attr()
    -
    attrAppend
    -
    in file phpQueryObject.php, method phpQueryObject::attrAppend()
        Enter description here...
    -
    attrEvents
    -
    in file phpQueryObject.php, method phpQueryObject::attrEvents()
    -
    attrPHP
    -
    in file phpQueryObject.php, method phpQueryObject::attrPHP()
        Enter description here...
    -
    attrPrepend
    -
    in file phpQueryObject.php, method phpQueryObject::attrPrepend()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    b

    -
    -
    $bubbles
    -
    in file DOMEvent.php, variable DOMEvent::$bubbles
        Returns a boolean indicating whether the event bubbles up through the DOM or not.
    -
    before
    -
    in file phpQueryObject.php, method phpQueryObject::before()
        Enter description here...
    -
    beforePHP
    -
    in file phpQueryObject.php, method phpQueryObject::beforePHP()
        Enter description here...
    -
    bind
    -
    in file phpQueryObject.php, method phpQueryObject::bind()
        Binds a handler to one or more events (like click) for each matched element.
    -
    browser
    -
    in file phpQuery.php, method phpQuery::browser()
    -
    browserGet
    -
    in file phpQuery.php, method phpQuery::browserGet()
    -
    browserPost
    -
    in file phpQuery.php, method phpQuery::browserPost()
    -
    -
    - top
    -
    - -
    -

    c

    -
    -
    $callback
    -
    in file Callback.php, variable Callback::$callback
    -
    $cancelable
    -
    in file DOMEvent.php, variable DOMEvent::$cancelable
        Returns a boolean indicating whether the event is cancelable.
    -
    $charset
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$charset
    -
    $charset
    -
    in file phpQueryObject.php, variable phpQueryObject::$charset
    -
    $contentType
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$contentType
    -
    $current
    -
    in file phpQueryObject.php, variable phpQueryObject::$current
        Iterator interface helper
    -
    $currentTarget
    -
    in file DOMEvent.php, variable DOMEvent::$currentTarget
        Returns a reference to the currently registered target for the event.
    -
    Callback
    -
    in file Callback.php, class Callback
        Callback class implementing ParamStructures, pattern similar to Currying.
    -
    Callback.php
    -
    procedural page Callback.php
    -
    CallbackParam
    -
    in file Callback.php, class CallbackParam
    -
    CallbackReference
    -
    in file Callback.php, class CallbackReference
        Callback class implementing ParamStructures, pattern similar to Currying.
    -
    callbackRun
    -
    in file phpQuery.php, method phpQuery::callbackRun()
    -
    change
    -
    in file phpQueryObject.php, method phpQueryObject::change()
        Enter description here...
    -
    charsetAppendToHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetAppendToHTML()
    -
    charsetAppendToXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetAppendToXML()
    -
    charsetFromHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetFromHTML()
    -
    charsetFromXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetFromXML()
    -
    children
    -
    in file phpQueryObject.php, method phpQueryObject::children()
        Enter description here...
    -
    click
    -
    in file phpQueryObject.php, method phpQueryObject::click()
        Enter description here...
    -
    contents
    -
    in file phpQueryObject.php, method phpQueryObject::contents()
        Enter description here...
    -
    contentsUnwrap
    -
    in file phpQueryObject.php, method phpQueryObject::contentsUnwrap()
        Enter description here...
    -
    contentTypeFromHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::contentTypeFromHTML()
    -
    contentTypeToArray
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::contentTypeToArray()
    -
    count
    -
    in file phpQueryObject.php, method phpQueryObject::count()
    -
    createDocumentWrapper
    -
    in file phpQuery.php, method phpQuery::createDocumentWrapper()
        Enter description here...
    -
    css
    -
    in file phpQueryObject.php, method phpQueryObject::css()
        Enter description here...
    -
    current
    -
    in file phpQueryObject.php, method phpQueryObject::current()
    -
    -
    - top
    -
    - -
    -

    d

    -
    -
    $data
    -
    in file DOMEvent.php, variable DOMEvent::$data
    -
    $debug
    -
    in file phpQuery.php, variable phpQuery::$debug
    -
    $defaultCharset
    -
    in file phpQuery.php, variable phpQuery::$defaultCharset
    -
    $defaultDoctype
    -
    in file phpQuery.php, variable phpQuery::$defaultDoctype
        Applies only to HTML.
    -
    $defaultDocumentID
    -
    in file phpQuery.php, variable phpQuery::$defaultDocumentID
    -
    $detail
    -
    in file DOMEvent.php, variable DOMEvent::$detail
        Returns detail about the event, depending on the type of event.
    -
    $document
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$document
    -
    $document
    -
    in file phpQueryObject.php, variable phpQueryObject::$document
        DOMDocument class.
    -
    $documentFragment
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentFragment
        Indicated if doument is just a fragment (no <html> tag).
    -
    $documentID
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentID
    -
    $documents
    -
    in file phpQuery.php, variable phpQuery::$documents
    -
    $documentWrapper
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentWrapper
    -
    $dumpCount
    -
    in file phpQuery.php, variable phpQuery::$dumpCount
    -
    debug
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::debug()
    -
    debug
    -
    in file phpQuery.php, method phpQuery::debug()
    -
    debug
    -
    in file phpQueryObject.php, method phpQueryObject::debug()
    -
    documentCreate
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentCreate()
    -
    documentFragment
    -
    in file phpQueryObject.php, method phpQueryObject::documentFragment()
    -
    documentFragmentCreate
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentFragmentCreate()
        Creates new document fragment.
    -
    documentFragmentToMarkup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentFragmentToMarkup()
    -
    DOMDOCUMENT
    -
    in file phpQuery.php, constant DOMDOCUMENT
    -
    DOMDocumentWrapper
    -
    in file DOMDocumentWrapper.php, class DOMDocumentWrapper
        DOMDocumentWrapper class simplifies work with DOMDocument.
    -
    DOMDocumentWrapper.php
    -
    procedural page DOMDocumentWrapper.php
    -
    DOMELEMENT
    -
    in file phpQuery.php, constant DOMELEMENT
    -
    DOMEvent
    -
    in file DOMEvent.php, class DOMEvent
        DOMEvent class.
    -
    DOMEvent.php
    -
    procedural page DOMEvent.php
    -
    DOMNODE
    -
    in file phpQuery.php, constant DOMNODE
    -
    DOMNODELIST
    -
    in file phpQuery.php, constant DOMNODELIST
    -
    DOMNodeListToArray
    -
    in file phpQuery.php, method phpQuery::DOMNodeListToArray()
    -
    dump
    -
    in file phpQueryObject.php, method phpQueryObject::dump()
        Dump htmlOuter and preserve chain. Usefull for debugging.
    -
    dumpDie
    -
    in file phpQueryObject.php, method phpQueryObject::dumpDie()
        Dump htmlOuter and stop script execution. Usefull for debugging.
    -
    dumpLength
    -
    in file phpQueryObject.php, method phpQueryObject::dumpLength()
    -
    dumpTree
    -
    in file phpQueryObject.php, method phpQueryObject::dumpTree()
    -
    dumpWhois
    -
    in file phpQueryObject.php, method phpQueryObject::dumpWhois()
    -
    -
    - top
    -
    - -
    -

    e

    -
    -
    $elements
    -
    in file phpQueryObject.php, variable phpQueryObject::$elements
        Stack of selected elements.
    -
    $elementsBackup
    -
    in file phpQueryObject.php, variable phpQueryObject::$elementsBackup
    -
    $elementsInterator
    -
    in file phpQueryObject.php, variable phpQueryObject::$elementsInterator
        Iterator interface helper
    -
    $eventPhase
    -
    in file DOMEvent.php, variable DOMEvent::$eventPhase
        Used to indicate which phase of the event flow is currently being evaluated.
    -
    $events
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$events
    -
    $eventsGlobal
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$eventsGlobal
    -
    $eventsNodes
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$eventsNodes
    -
    $explicitOriginalTarget
    -
    in file DOMEvent.php, variable DOMEvent::$explicitOriginalTarget
        The explicit original target of the event (Mozilla-specific).
    -
    each
    -
    in file phpQueryObject.php, method phpQueryObject::each()
        Enter description here...
    -
    each
    -
    in file phpQuery.php, method phpQuery::each()
    -
    elementsContainsNode
    -
    in file phpQueryObject.php, method phpQueryObject::elementsContainsNode()
    -
    end
    -
    in file phpQueryObject.php, method phpQueryObject::end()
        Enter description here...
    -
    eq
    -
    in file phpQueryObject.php, method phpQueryObject::eq()
        Enter description here...
    -
    expandEmptyTag
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::expandEmptyTag()
        expandEmptyTag
    -
    extend
    -
    in file phpQueryObject.php, method phpQueryObject::extend()
        Deprecated, use $pq->plugin() instead.
    -
    extend
    -
    in file phpQuery.php, method phpQuery::extend()
        Deprecated, use phpQuery::plugin() instead.
    -
    -
    - top
    -
    - -
    -

    f

    -
    -
    $frames
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$frames
        TODO
    -
    filter
    -
    in file phpQueryObject.php, method phpQueryObject::filter()
        Enter description here...
    -
    filterCallback
    -
    in file phpQueryObject.php, method phpQueryObject::filterCallback()
        Enter description here...
    -
    find
    -
    in file phpQueryObject.php, method phpQueryObject::find()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    g

    -
    -
    get
    -
    in file phpQuery.php, method phpQuery::get()
    -
    get
    -
    in file phpQueryObject.php, method phpQueryObject::get()
        Return matched DOM nodes.
    -
    getDocument
    -
    in file phpQueryObject.php, method phpQueryObject::getDocument()
        Returns object with stack set to document root.
    -
    getDocument
    -
    in file phpQuery.php, method phpQuery::getDocument()
        Returns document with id $id or last used as phpQueryObject.
    -
    getDocumentID
    -
    in file phpQueryObject.php, method phpQueryObject::getDocumentID()
        Get object's Document ID.
    -
    getDocumentID
    -
    in file phpQuery.php, method phpQuery::getDocumentID()
        Returns source's document ID.
    -
    getDocumentIDRef
    -
    in file phpQueryObject.php, method phpQueryObject::getDocumentIDRef()
        Saves object's DocumentID to $var by reference.
    -
    getDOMDocument
    -
    in file phpQueryObject.php, method phpQueryObject::getDOMDocument()
    -
    getDOMDocument
    -
    in file phpQuery.php, method phpQuery::getDOMDocument()
        Get DOMDocument object related to $source.
    -
    getElementSiblings
    -
    in file phpQueryObject.php, method phpQueryObject::getElementSiblings()
    -
    getNode
    -
    in file phpQueryEvents.php, method phpQueryEvents::getNode()
    -
    getNodeAttrs
    -
    in file phpQueryObject.php, method phpQueryObject::getNodeAttrs()
    -
    getNodeXpath
    -
    in file phpQueryObject.php, method phpQueryObject::getNodeXpath()
        Returns node's XPath.
    -
    getString
    -
    in file phpQueryObject.php, method phpQueryObject::getString()
        Return matched DOM nodes.
    -
    getStrings
    -
    in file phpQueryObject.php, method phpQueryObject::getStrings()
        Return matched DOM nodes.
    -
    grep
    -
    in file phpQuery.php, method phpQuery::grep()
    -
    -
    - top
    -
    - -
    -

    h

    -
    -
    hasClass
    -
    in file phpQueryObject.php, method phpQueryObject::hasClass()
        Enter description here...
    -
    hide
    -
    in file phpQueryObject.php, method phpQueryObject::hide()
    -
    html
    -
    in file phpQueryObject.php, method phpQueryObject::html()
        Enter description here...
    -
    htmlOuter
    -
    in file phpQueryObject.php, method phpQueryObject::htmlOuter()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    i

    -
    -
    $id
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$id
    -
    $isDocumentFragment
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isDocumentFragment
    -
    $isHTML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isHTML
    -
    $isXHTML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isXHTML
    -
    $isXML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isXML
    -
    import
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::import()
    -
    importAttr
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::importAttr()
    -
    inArray
    -
    in file phpQuery.php, method phpQuery::inArray()
    -
    index
    -
    in file phpQueryObject.php, method phpQueryObject::index()
        Enter description here...
    -
    insert
    -
    in file phpQueryObject.php, method phpQueryObject::insert()
        Various insert scenarios.
    -
    insertAfter
    -
    in file phpQueryObject.php, method phpQueryObject::insertAfter()
        Enter description here...
    -
    insertBefore
    -
    in file phpQueryObject.php, method phpQueryObject::insertBefore()
        Enter description here...
    -
    is
    -
    in file phpQueryObject.php, method phpQueryObject::is()
        Enter description here...
    -
    isChar
    -
    in file phpQueryObject.php, method phpQueryObject::isChar()
        Determines if $char is really a char.
    -
    isDocumentFragmentHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentHTML()
    -
    isDocumentFragmentXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentXHTML()
    -
    isDocumentFragmentXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentXML()
    -
    isFunction
    -
    in file phpQuery.php, method phpQuery::isFunction()
    -
    isHTML
    -
    in file phpQueryObject.php, method phpQueryObject::isHTML()
    -
    isMarkup
    -
    in file phpQuery.php, method phpQuery::isMarkup()
        Checks if $input is HTML string, which has to start with '<'.
    -
    isRegexp
    -
    in file phpQueryObject.php, method phpQueryObject::isRegexp()
    -
    isRoot
    -
    in file phpQueryObject.php, method phpQueryObject::isRoot()
    -
    issetGlobal
    -
    in file phpQueryEvents.php, method phpQueryEvents::issetGlobal()
    -
    isXHTML
    -
    in file phpQueryObject.php, method phpQueryObject::isXHTML()
    -
    isXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isXHTML()
    -
    isXML
    -
    in file phpQueryObject.php, method phpQueryObject::isXML()
    -
    isXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isXML()
    -
    -
    - top
    -
    - -
    -

    k

    -
    -
    key
    -
    in file phpQueryObject.php, method phpQueryObject::key()
    -
    -
    - top
    -
    - -
    -

    l

    -
    -
    $lastModified
    -
    in file phpQuery.php, variable phpQuery::$lastModified
    -
    length
    -
    in file phpQueryObject.php, method phpQueryObject::length()
        Enter description here...
    -
    load
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::load()
    -
    load
    -
    in file phpQueryObject.php, method phpQueryObject::load()
        Enter description here...
    -
    loadDocument
    -
    in file phpQuery.php, method phpQuery::loadDocument()
        Reuses existing DOMDocument object.
    -
    loadMarkup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkup()
    -
    loadMarkupHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupHTML()
    -
    loadMarkupReset
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupReset()
    -
    loadMarkupXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupXML()
    -
    -
    - top
    -
    - -
    -

    m

    -
    -
    makeArray
    -
    in file phpQuery.php, method phpQuery::makeArray()
    -
    map
    -
    in file phpQueryObject.php, method phpQueryObject::map()
        Enter description here...
    -
    map
    -
    in file phpQuery.php, method phpQuery::map()
    -
    markup
    -
    in file phpQueryObject.php, method phpQueryObject::markup()
        jQuey difference
    -
    markup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::markup()
        Return document markup, starting with optional $node as root.
    -
    markupEvents
    -
    in file phpQueryObject.php, method phpQueryObject::markupEvents()
    -
    markupFixXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::markupFixXHTML()
    -
    markupOuter
    -
    in file phpQueryObject.php, method phpQueryObject::markupOuter()
        jQuey difference
    -
    markupToPHP
    -
    in file phpQuery.php, method phpQuery::markupToPHP()
    -
    matchClasses
    -
    in file phpQueryObject.php, method phpQueryObject::matchClasses()
        Enter description here...
    -
    merge
    -
    in file phpQueryObject.php, method phpQueryObject::merge()
    -
    merge
    -
    in file phpQuery.php, method phpQuery::merge()
        Merge 2 phpQuery objects.
    -
    -
    - top
    -
    - -
    -

    n

    -
    -
    newDocument
    -
    in file phpQuery.php, method phpQuery::newDocument()
        Creates new document from markup.
    -
    newDocumentFile
    -
    in file phpQuery.php, method phpQuery::newDocumentFile()
        Creates new document from file $file.
    -
    newDocumentFileHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileHTML()
    -
    newDocumentFilePHP
    -
    in file phpQuery.php, method phpQuery::newDocumentFilePHP()
    -
    newDocumentFileXHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileXHTML()
    -
    newDocumentFileXML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileXML()
    -
    newDocumentHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentHTML()
    -
    newDocumentPHP
    -
    in file phpQuery.php, method phpQuery::newDocumentPHP()
    -
    newDocumentXHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentXHTML()
    -
    newDocumentXML
    -
    in file phpQuery.php, method phpQuery::newDocumentXML()
    -
    newInstance
    -
    in file phpQueryObject.php, method phpQueryObject::newInstance()
        Returns new instance of actual class.
    -
    next
    -
    in file phpQueryObject.php, method phpQueryObject::next()
        Double-function method.
    -
    nextAll
    -
    in file phpQueryObject.php, method phpQueryObject::nextAll()
    -
    not
    -
    in file phpQueryObject.php, method phpQueryObject::not()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    o

    -
    -
    $originalTarget
    -
    in file DOMEvent.php, variable DOMEvent::$originalTarget
        The original target of the event, before any retargetings (Mozilla-specific).
    -
    offsetExists
    -
    in file phpQueryObject.php, method phpQueryObject::offsetExists()
    -
    offsetGet
    -
    in file phpQueryObject.php, method phpQueryObject::offsetGet()
    -
    offsetSet
    -
    in file phpQueryObject.php, method phpQueryObject::offsetSet()
    -
    offsetUnset
    -
    in file phpQueryObject.php, method phpQueryObject::offsetUnset()
    -
    -
    - top
    -
    - -
    -

    p

    -
    -
    $params
    -
    in file Callback.php, variable Callback::$params
    -
    $plugins
    -
    in file phpQuery.php, variable phpQuery::$plugins
        Static namespace for plugins.
    -
    $pluginsLoaded
    -
    in file phpQuery.php, variable phpQuery::$pluginsLoaded
        List of loaded plugins.
    -
    $pluginsMethods
    -
    in file phpQuery.php, variable phpQuery::$pluginsMethods
    -
    $pluginsStaticMethods
    -
    in file phpQuery.php, variable phpQuery::$pluginsStaticMethods
    -
    $previous
    -
    in file phpQueryObject.php, variable phpQueryObject::$previous
    -
    param
    -
    in file phpQuery.php, method phpQuery::param()
        Enter description here...
    -
    param
    -
    in file Callback.php, method Callback::param()
    -
    parent
    -
    in file phpQueryObject.php, method phpQueryObject::parent()
        Enter description here...
    -
    parents
    -
    in file phpQueryObject.php, method phpQueryObject::parents()
        Enter description here...
    -
    parseJSON
    -
    in file phpQuery.php, method phpQuery::parseJSON()
        Parses JSON into proper PHP type.
    -
    parseSelector
    -
    in file phpQueryObject.php, method phpQueryObject::parseSelector()
    -
    php
    -
    in file phpQuery.php, method phpQuery::php()
    -
    php
    -
    in file phpQueryObject.php, method phpQueryObject::php()
        Just like html(), but returns markup with VALID (dangerous) PHP tags.
    -
    phpQuery
    -
    in file phpQuery.php, class phpQuery
        Static namespace for phpQuery functions.
    -
    phpQuery.php
    -
    procedural page phpQuery.php
    -
    phpQueryEvents
    -
    in file phpQueryEvents.php, class phpQueryEvents
        Event handling class.
    -
    phpQueryEvents.php
    -
    procedural page phpQueryEvents.php
    -
    phpQueryObject
    -
    in file phpQueryObject.php, class phpQueryObject
        Class representing phpQuery objects.
    -
    phpQueryObject.php
    -
    procedural page phpQueryObject.php
    -
    phpQueryPlugins
    -
    in file phpQuery.php, class phpQueryPlugins
        Plugins static namespace class.
    -
    phpToMarkup
    -
    in file phpQuery.php, method phpQuery::phpToMarkup()
    -
    plugin
    -
    in file phpQueryObject.php, method phpQueryObject::plugin()
        Enter description here...
    -
    plugin
    -
    in file phpQuery.php, method phpQuery::plugin()
        Extend phpQuery with $class from $file.
    -
    post
    -
    in file phpQuery.php, method phpQuery::post()
    -
    pq
    -
    in file phpQuery.php, method phpQuery::pq()
        Multi-purpose function.
    -
    pq
    -
    in file phpQuery.php, function pq()
        Shortcut to phpQuery::pq($arg1, $context) Chainable.
    -
    prepend
    -
    in file phpQueryObject.php, method phpQueryObject::prepend()
        Enter description here...
    -
    prependPHP
    -
    in file phpQueryObject.php, method phpQueryObject::prependPHP()
        Enter description here...
    -
    prependTo
    -
    in file phpQueryObject.php, method phpQueryObject::prependTo()
        Enter description here...
    -
    prev
    -
    in file phpQueryObject.php, method phpQueryObject::prev()
        Enter description here...
    -
    prevAll
    -
    in file phpQueryObject.php, method phpQueryObject::prevAll()
    -
    preventDefault
    -
    in file DOMEvent.php, method DOMEvent::preventDefault()
        Cancels the event (if it is cancelable).
    -
    pseudoClasses
    -
    in file phpQueryObject.php, method phpQueryObject::pseudoClasses()
    -
    -
    - top
    -
    - -
    -

    r

    -
    -
    $relatedTarget
    -
    in file DOMEvent.php, variable DOMEvent::$relatedTarget
        Identifies a secondary target for the event.
    -
    $root
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$root
        Document root, by default equals to document itself.
    -
    $root
    -
    in file phpQueryObject.php, variable phpQueryObject::$root
    -
    $runDefault
    -
    in file DOMEvent.php, variable DOMEvent::$runDefault
    -
    remove
    -
    in file phpQueryObject.php, method phpQueryObject::remove()
        Enter description here...
    -
    remove
    -
    in file phpQueryEvents.php, method phpQueryEvents::remove()
        Enter description here...
    -
    removeAttr
    -
    in file phpQueryObject.php, method phpQueryObject::removeAttr()
        Enter description here...
    -
    removeClass
    -
    in file phpQueryObject.php, method phpQueryObject::removeClass()
        Enter description here...
    -
    replaceAll
    -
    in file phpQueryObject.php, method phpQueryObject::replaceAll()
        Enter description here...
    -
    replaceWith
    -
    in file phpQueryObject.php, method phpQueryObject::replaceWith()
        Enter description here...
    -
    replaceWithPHP
    -
    in file phpQueryObject.php, method phpQueryObject::replaceWithPHP()
        Enter description here...
    -
    reverse
    -
    in file phpQueryObject.php, method phpQueryObject::reverse()
        Enter description here...
    -
    rewind
    -
    in file phpQueryObject.php, method phpQueryObject::rewind()
    -
    runQuery
    -
    in file phpQueryObject.php, method phpQueryObject::runQuery()
    -
    -
    - top
    -
    - -
    -

    s

    -
    -
    selectDocument
    -
    in file phpQuery.php, method phpQuery::selectDocument()
        Sets default document to $id. Document has to be loaded prior to using this method.
    -
    serialize
    -
    in file phpQueryObject.php, method phpQueryObject::serialize()
        Enter description here...
    -
    serializeArray
    -
    in file phpQueryObject.php, method phpQueryObject::serializeArray()
        Enter description here...
    -
    setNode
    -
    in file phpQueryEvents.php, method phpQueryEvents::setNode()
    -
    show
    -
    in file phpQueryObject.php, method phpQueryObject::show()
    -
    siblings
    -
    in file phpQueryObject.php, method phpQueryObject::siblings()
        Enter description here...
    -
    size
    -
    in file phpQueryObject.php, method phpQueryObject::size()
        Enter description here...
    -
    slice
    -
    in file phpQueryObject.php, method phpQueryObject::slice()
        Enter description here...
    -
    stack
    -
    in file phpQueryObject.php, method phpQueryObject::stack()
        Attribute method.
    -
    stackIsRoot
    -
    in file phpQueryObject.php, method phpQueryObject::stackIsRoot()
    -
    stopPropagation
    -
    in file DOMEvent.php, method DOMEvent::stopPropagation()
        Stops the propagation of events further along in the DOM.
    -
    submit
    -
    in file phpQueryObject.php, method phpQueryObject::submit()
        Enter description here...
    -
    switchWith
    -
    in file phpQueryObject.php, method phpQueryObject::switchWith()
    -
    -
    - top
    -
    - -
    -

    t

    -
    -
    $target
    -
    in file DOMEvent.php, variable DOMEvent::$target
        Returns a reference to the target to which the event was originally dispatched.
    -
    $timeStamp
    -
    in file DOMEvent.php, variable DOMEvent::$timeStamp
        Returns the time that the event was created.
    -
    $type
    -
    in file DOMEvent.php, variable DOMEvent::$type
        Returns the name of the event (case-insensitive).
    -
    text
    -
    in file phpQueryObject.php, method phpQueryObject::text()
        Return joined text content.
    -
    toggleClass
    -
    in file phpQueryObject.php, method phpQueryObject::toggleClass()
        Enter description here...
    -
    toJSON
    -
    in file phpQuery.php, method phpQuery::toJSON()
        Returns JSON representation of $data.
    -
    toReference
    -
    in file phpQueryObject.php, method phpQueryObject::toReference()
        Saves actual object to $var by reference.
    -
    toRoot
    -
    in file phpQueryObject.php, method phpQueryObject::toRoot()
        Enter description here...
    -
    trigger
    -
    in file phpQueryObject.php, method phpQueryObject::trigger()
        Trigger a type of event on every matched element.
    -
    trigger
    -
    in file phpQueryEvents.php, method phpQueryEvents::trigger()
        Trigger a type of event on every matched element.
    -
    triggerHandler
    -
    in file phpQueryObject.php, method phpQueryObject::triggerHandler()
        This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
    -
    trim
    -
    in file phpQuery.php, method phpQuery::trim()
    -
    -
    - top
    -
    - -
    -

    u

    -
    -
    unbind
    -
    in file phpQueryObject.php, method phpQueryObject::unbind()
        Enter description here...
    -
    unique
    -
    in file phpQuery.php, method phpQuery::unique()
    -
    unloadDocument
    -
    in file phpQueryObject.php, method phpQueryObject::unloadDocument()
        Unloads whole document from memory.
    -
    unloadDocuments
    -
    in file phpQuery.php, method phpQuery::unloadDocuments()
        Unloades all or specified document from memory.
    -
    unQuote
    -
    in file phpQueryObject.php, method phpQueryObject::unQuote()
    -
    unsafePHPTags
    -
    in file phpQuery.php, method phpQuery::unsafePHPTags()
        Parses phpQuery object or HTML result against PHP tags and makes them active.
    -
    -
    - top
    -
    - -
    -

    v

    -
    -
    $valid
    -
    in file phpQueryObject.php, variable phpQueryObject::$valid
        Iterator interface helper
    -
    val
    -
    in file phpQueryObject.php, method phpQueryObject::val()
        Return form element value.
    -
    valid
    -
    in file phpQueryObject.php, method phpQueryObject::valid()
    -
    -
    - top
    -
    - -
    -

    w

    -
    -
    whois
    -
    in file phpQueryObject.php, method phpQueryObject::whois()
    -
    wrap
    -
    in file phpQueryObject.php, method phpQueryObject::wrap()
        Enter description here...
    -
    wrapAll
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAll()
        Enter description here...
    -
    wrapAllOld
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAllOld()
        Enter description here...
    -
    wrapAllPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAllPHP()
        Enter description here...
    -
    wrapInner
    -
    in file phpQueryObject.php, method phpQueryObject::wrapInner()
        Enter description here...
    -
    wrapInnerPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapInnerPHP()
        Enter description here...
    -
    wrapPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapPHP()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    x

    -
    -
    $xpath
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$xpath
    -
    $xpath
    -
    in file phpQueryObject.php, variable phpQueryObject::$xpath
        XPath interface.
    -
    xml
    -
    in file phpQueryObject.php, method phpQueryObject::xml()
    -
    xmlOuter
    -
    in file phpQueryObject.php, method phpQueryObject::xmlOuter()
    -
    -
    - top
    -
    - -
    -

    _

    -
    -
    _clone
    -
    in file phpQueryObject.php, method phpQueryObject::_clone()
        Enter description here...
    -
    _empty
    -
    in file phpQueryObject.php, method phpQueryObject::_empty()
        Proper name without underscore (just ->empty()) also works.
    -
    _next
    -
    in file phpQueryObject.php, method phpQueryObject::_next()
        Safe rename of next().
    -
    _prev
    -
    in file phpQueryObject.php, method phpQueryObject::_prev()
        Use prev() and next().
    -
    __call
    -
    in file phpQuery.php, method phpQueryPlugins::__call()
    -
    __call
    -
    in file phpQueryObject.php, method phpQueryObject::__call()
    -
    __construct
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::__construct()
    -
    __construct
    -
    in file DOMEvent.php, method DOMEvent::__construct()
    -
    __construct
    -
    in file phpQueryObject.php, method phpQueryObject::__construct()
        Enter description here...
    -
    __construct
    -
    in file Callback.php, method CallbackReference::__construct()
    -
    __construct
    -
    in file Callback.php, method Callback::__construct()
    -
    __get
    -
    in file phpQueryObject.php, method phpQueryObject::__get()
    -
    __loadSuccess
    -
    in file phpQueryObject.php, method phpQueryObject::__loadSuccess()
    -
    __pseudoClassParam
    -
    in file phpQueryObject.php, method phpQueryObject::__pseudoClassParam()
    -
    __toString
    -
    in file phpQueryObject.php, method phpQueryObject::__toString()
    -
    ___wrapAllCallback
    -
    in file phpQueryObject.php, method phpQueryObject::___wrapAllCallback()
    -
    -
    - top
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/elementindex_phpQuery.html b/api-reference/elementindex_phpQuery.html deleted file mode 100644 index 544aa96..0000000 --- a/api-reference/elementindex_phpQuery.html +++ /dev/null @@ -1,907 +0,0 @@ - - -Package phpQuery Element Index - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - - -

    Element index for package phpQuery

    - [ a ] - [ b ] - [ c ] - [ d ] - [ e ] - [ f ] - [ g ] - [ h ] - [ i ] - [ k ] - [ l ] - [ m ] - [ n ] - [ o ] - [ p ] - [ r ] - [ s ] - [ t ] - [ u ] - [ v ] - [ w ] - [ x ] - [ _ ] - -
    - -
    -

    _

    -
    -
    _clone
    -
    in file phpQueryObject.php, method phpQueryObject::_clone()
        Enter description here...
    -
    _empty
    -
    in file phpQueryObject.php, method phpQueryObject::_empty()
        Proper name without underscore (just ->empty()) also works.
    -
    _next
    -
    in file phpQueryObject.php, method phpQueryObject::_next()
        Safe rename of next().
    -
    _prev
    -
    in file phpQueryObject.php, method phpQueryObject::_prev()
        Use prev() and next().
    -
    __call
    -
    in file phpQuery.php, method phpQueryPlugins::__call()
    -
    __call
    -
    in file phpQueryObject.php, method phpQueryObject::__call()
    -
    __construct
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::__construct()
    -
    __construct
    -
    in file DOMEvent.php, method DOMEvent::__construct()
    -
    __construct
    -
    in file phpQueryObject.php, method phpQueryObject::__construct()
        Enter description here...
    -
    __construct
    -
    in file Callback.php, method CallbackReference::__construct()
    -
    __construct
    -
    in file Callback.php, method Callback::__construct()
    -
    __get
    -
    in file phpQueryObject.php, method phpQueryObject::__get()
    -
    __loadSuccess
    -
    in file phpQueryObject.php, method phpQueryObject::__loadSuccess()
    -
    __pseudoClassParam
    -
    in file phpQueryObject.php, method phpQueryObject::__pseudoClassParam()
    -
    __toString
    -
    in file phpQueryObject.php, method phpQueryObject::__toString()
    -
    ___wrapAllCallback
    -
    in file phpQueryObject.php, method phpQueryObject::___wrapAllCallback()
    -
    -
    - top
    -
    - -
    -

    a

    -
    -
    $active
    -
    in file phpQuery.php, variable phpQuery::$active
    -
    $ajaxAllowedHosts
    -
    in file phpQuery.php, variable phpQuery::$ajaxAllowedHosts
        Hosts allowed for AJAX connections.
    -
    $ajaxSettings
    -
    in file phpQuery.php, variable phpQuery::$ajaxSettings
        AJAX settings.
    -
    add
    -
    in file phpQueryEvents.php, method phpQueryEvents::add()
        Binds a handler to one or more events (like click) for each matched element.
    -
    add
    -
    in file phpQueryObject.php, method phpQueryObject::add()
        Enter description here...
    -
    addClass
    -
    in file phpQueryObject.php, method phpQueryObject::addClass()
        Enter description here...
    -
    addClassPHP
    -
    in file phpQueryObject.php, method phpQueryObject::addClassPHP()
        Enter description here...
    -
    after
    -
    in file phpQueryObject.php, method phpQueryObject::after()
        Enter description here...
    -
    afterMarkupLoad
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::afterMarkupLoad()
    -
    afterPHP
    -
    in file phpQueryObject.php, method phpQueryObject::afterPHP()
        Enter description here...
    -
    ajax
    -
    in file phpQuery.php, method phpQuery::ajax()
        Make an AJAX request.
    -
    ajaxAllowHost
    -
    in file phpQuery.php, method phpQuery::ajaxAllowHost()
    -
    ajaxAllowURL
    -
    in file phpQuery.php, method phpQuery::ajaxAllowURL()
    -
    ajaxSetup
    -
    in file phpQuery.php, method phpQuery::ajaxSetup()
    -
    ancestors
    -
    in file phpQueryObject.php, method phpQueryObject::ancestors()
        Enter description here...
    -
    andSelf
    -
    in file phpQueryObject.php, method phpQueryObject::andSelf()
        Enter description here...
    -
    append
    -
    in file phpQueryObject.php, method phpQueryObject::append()
        Enter description here...
    -
    appendPHP
    -
    in file phpQueryObject.php, method phpQueryObject::appendPHP()
        Enter description here...
    -
    appendTo
    -
    in file phpQueryObject.php, method phpQueryObject::appendTo()
        Enter description here...
    -
    attr
    -
    in file phpQueryObject.php, method phpQueryObject::attr()
    -
    attrAppend
    -
    in file phpQueryObject.php, method phpQueryObject::attrAppend()
        Enter description here...
    -
    attrEvents
    -
    in file phpQueryObject.php, method phpQueryObject::attrEvents()
    -
    attrPHP
    -
    in file phpQueryObject.php, method phpQueryObject::attrPHP()
        Enter description here...
    -
    attrPrepend
    -
    in file phpQueryObject.php, method phpQueryObject::attrPrepend()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    b

    -
    -
    $bubbles
    -
    in file DOMEvent.php, variable DOMEvent::$bubbles
        Returns a boolean indicating whether the event bubbles up through the DOM or not.
    -
    before
    -
    in file phpQueryObject.php, method phpQueryObject::before()
        Enter description here...
    -
    beforePHP
    -
    in file phpQueryObject.php, method phpQueryObject::beforePHP()
        Enter description here...
    -
    bind
    -
    in file phpQueryObject.php, method phpQueryObject::bind()
        Binds a handler to one or more events (like click) for each matched element.
    -
    browser
    -
    in file phpQuery.php, method phpQuery::browser()
    -
    browserGet
    -
    in file phpQuery.php, method phpQuery::browserGet()
    -
    browserPost
    -
    in file phpQuery.php, method phpQuery::browserPost()
    -
    -
    - top
    -
    - -
    -

    c

    -
    -
    $callback
    -
    in file Callback.php, variable Callback::$callback
    -
    $cancelable
    -
    in file DOMEvent.php, variable DOMEvent::$cancelable
        Returns a boolean indicating whether the event is cancelable.
    -
    $charset
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$charset
    -
    $charset
    -
    in file phpQueryObject.php, variable phpQueryObject::$charset
    -
    $contentType
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$contentType
    -
    $current
    -
    in file phpQueryObject.php, variable phpQueryObject::$current
        Iterator interface helper
    -
    $currentTarget
    -
    in file DOMEvent.php, variable DOMEvent::$currentTarget
        Returns a reference to the currently registered target for the event.
    -
    Callback
    -
    in file Callback.php, class Callback
        Callback class implementing ParamStructures, pattern similar to Currying.
    -
    Callback.php
    -
    procedural page Callback.php
    -
    CallbackParam
    -
    in file Callback.php, class CallbackParam
    -
    CallbackReference
    -
    in file Callback.php, class CallbackReference
        Callback class implementing ParamStructures, pattern similar to Currying.
    -
    callbackRun
    -
    in file phpQuery.php, method phpQuery::callbackRun()
    -
    change
    -
    in file phpQueryObject.php, method phpQueryObject::change()
        Enter description here...
    -
    charsetAppendToHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetAppendToHTML()
    -
    charsetAppendToXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetAppendToXML()
    -
    charsetFromHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetFromHTML()
    -
    charsetFromXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::charsetFromXML()
    -
    children
    -
    in file phpQueryObject.php, method phpQueryObject::children()
        Enter description here...
    -
    click
    -
    in file phpQueryObject.php, method phpQueryObject::click()
        Enter description here...
    -
    contents
    -
    in file phpQueryObject.php, method phpQueryObject::contents()
        Enter description here...
    -
    contentsUnwrap
    -
    in file phpQueryObject.php, method phpQueryObject::contentsUnwrap()
        Enter description here...
    -
    contentTypeFromHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::contentTypeFromHTML()
    -
    contentTypeToArray
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::contentTypeToArray()
    -
    count
    -
    in file phpQueryObject.php, method phpQueryObject::count()
    -
    createDocumentWrapper
    -
    in file phpQuery.php, method phpQuery::createDocumentWrapper()
        Enter description here...
    -
    css
    -
    in file phpQueryObject.php, method phpQueryObject::css()
        Enter description here...
    -
    current
    -
    in file phpQueryObject.php, method phpQueryObject::current()
    -
    -
    - top
    -
    - -
    -

    d

    -
    -
    $data
    -
    in file DOMEvent.php, variable DOMEvent::$data
    -
    $debug
    -
    in file phpQuery.php, variable phpQuery::$debug
    -
    $defaultCharset
    -
    in file phpQuery.php, variable phpQuery::$defaultCharset
    -
    $defaultDoctype
    -
    in file phpQuery.php, variable phpQuery::$defaultDoctype
        Applies only to HTML.
    -
    $defaultDocumentID
    -
    in file phpQuery.php, variable phpQuery::$defaultDocumentID
    -
    $detail
    -
    in file DOMEvent.php, variable DOMEvent::$detail
        Returns detail about the event, depending on the type of event.
    -
    $document
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$document
    -
    $document
    -
    in file phpQueryObject.php, variable phpQueryObject::$document
        DOMDocument class.
    -
    $documentFragment
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentFragment
        Indicated if doument is just a fragment (no <html> tag).
    -
    $documentID
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentID
    -
    $documents
    -
    in file phpQuery.php, variable phpQuery::$documents
    -
    $documentWrapper
    -
    in file phpQueryObject.php, variable phpQueryObject::$documentWrapper
    -
    $dumpCount
    -
    in file phpQuery.php, variable phpQuery::$dumpCount
    -
    debug
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::debug()
    -
    debug
    -
    in file phpQuery.php, method phpQuery::debug()
    -
    debug
    -
    in file phpQueryObject.php, method phpQueryObject::debug()
    -
    documentCreate
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentCreate()
    -
    documentFragment
    -
    in file phpQueryObject.php, method phpQueryObject::documentFragment()
    -
    documentFragmentCreate
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentFragmentCreate()
        Creates new document fragment.
    -
    documentFragmentToMarkup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::documentFragmentToMarkup()
    -
    DOMDOCUMENT
    -
    in file phpQuery.php, constant DOMDOCUMENT
    -
    DOMDocumentWrapper
    -
    in file DOMDocumentWrapper.php, class DOMDocumentWrapper
        DOMDocumentWrapper class simplifies work with DOMDocument.
    -
    DOMDocumentWrapper.php
    -
    procedural page DOMDocumentWrapper.php
    -
    DOMELEMENT
    -
    in file phpQuery.php, constant DOMELEMENT
    -
    DOMEvent
    -
    in file DOMEvent.php, class DOMEvent
        DOMEvent class.
    -
    DOMEvent.php
    -
    procedural page DOMEvent.php
    -
    DOMNODE
    -
    in file phpQuery.php, constant DOMNODE
    -
    DOMNODELIST
    -
    in file phpQuery.php, constant DOMNODELIST
    -
    DOMNodeListToArray
    -
    in file phpQuery.php, method phpQuery::DOMNodeListToArray()
    -
    dump
    -
    in file phpQueryObject.php, method phpQueryObject::dump()
        Dump htmlOuter and preserve chain. Usefull for debugging.
    -
    dumpDie
    -
    in file phpQueryObject.php, method phpQueryObject::dumpDie()
        Dump htmlOuter and stop script execution. Usefull for debugging.
    -
    dumpLength
    -
    in file phpQueryObject.php, method phpQueryObject::dumpLength()
    -
    dumpTree
    -
    in file phpQueryObject.php, method phpQueryObject::dumpTree()
    -
    dumpWhois
    -
    in file phpQueryObject.php, method phpQueryObject::dumpWhois()
    -
    -
    - top
    -
    - -
    -

    e

    -
    -
    $elements
    -
    in file phpQueryObject.php, variable phpQueryObject::$elements
        Stack of selected elements.
    -
    $elementsBackup
    -
    in file phpQueryObject.php, variable phpQueryObject::$elementsBackup
    -
    $elementsInterator
    -
    in file phpQueryObject.php, variable phpQueryObject::$elementsInterator
        Iterator interface helper
    -
    $eventPhase
    -
    in file DOMEvent.php, variable DOMEvent::$eventPhase
        Used to indicate which phase of the event flow is currently being evaluated.
    -
    $events
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$events
    -
    $eventsGlobal
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$eventsGlobal
    -
    $eventsNodes
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$eventsNodes
    -
    $explicitOriginalTarget
    -
    in file DOMEvent.php, variable DOMEvent::$explicitOriginalTarget
        The explicit original target of the event (Mozilla-specific).
    -
    each
    -
    in file phpQueryObject.php, method phpQueryObject::each()
        Enter description here...
    -
    each
    -
    in file phpQuery.php, method phpQuery::each()
    -
    elementsContainsNode
    -
    in file phpQueryObject.php, method phpQueryObject::elementsContainsNode()
    -
    end
    -
    in file phpQueryObject.php, method phpQueryObject::end()
        Enter description here...
    -
    eq
    -
    in file phpQueryObject.php, method phpQueryObject::eq()
        Enter description here...
    -
    expandEmptyTag
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::expandEmptyTag()
        expandEmptyTag
    -
    extend
    -
    in file phpQueryObject.php, method phpQueryObject::extend()
        Deprecated, use $pq->plugin() instead.
    -
    extend
    -
    in file phpQuery.php, method phpQuery::extend()
        Deprecated, use phpQuery::plugin() instead.
    -
    -
    - top
    -
    - -
    -

    f

    -
    -
    $frames
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$frames
        TODO
    -
    filter
    -
    in file phpQueryObject.php, method phpQueryObject::filter()
        Enter description here...
    -
    filterCallback
    -
    in file phpQueryObject.php, method phpQueryObject::filterCallback()
        Enter description here...
    -
    find
    -
    in file phpQueryObject.php, method phpQueryObject::find()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    g

    -
    -
    get
    -
    in file phpQuery.php, method phpQuery::get()
    -
    get
    -
    in file phpQueryObject.php, method phpQueryObject::get()
        Return matched DOM nodes.
    -
    getDocument
    -
    in file phpQueryObject.php, method phpQueryObject::getDocument()
        Returns object with stack set to document root.
    -
    getDocument
    -
    in file phpQuery.php, method phpQuery::getDocument()
        Returns document with id $id or last used as phpQueryObject.
    -
    getDocumentID
    -
    in file phpQueryObject.php, method phpQueryObject::getDocumentID()
        Get object's Document ID.
    -
    getDocumentID
    -
    in file phpQuery.php, method phpQuery::getDocumentID()
        Returns source's document ID.
    -
    getDocumentIDRef
    -
    in file phpQueryObject.php, method phpQueryObject::getDocumentIDRef()
        Saves object's DocumentID to $var by reference.
    -
    getDOMDocument
    -
    in file phpQueryObject.php, method phpQueryObject::getDOMDocument()
    -
    getDOMDocument
    -
    in file phpQuery.php, method phpQuery::getDOMDocument()
        Get DOMDocument object related to $source.
    -
    getElementSiblings
    -
    in file phpQueryObject.php, method phpQueryObject::getElementSiblings()
    -
    getNode
    -
    in file phpQueryEvents.php, method phpQueryEvents::getNode()
    -
    getNodeAttrs
    -
    in file phpQueryObject.php, method phpQueryObject::getNodeAttrs()
    -
    getNodeXpath
    -
    in file phpQueryObject.php, method phpQueryObject::getNodeXpath()
        Returns node's XPath.
    -
    getString
    -
    in file phpQueryObject.php, method phpQueryObject::getString()
        Return matched DOM nodes.
    -
    getStrings
    -
    in file phpQueryObject.php, method phpQueryObject::getStrings()
        Return matched DOM nodes.
    -
    grep
    -
    in file phpQuery.php, method phpQuery::grep()
    -
    -
    - top
    -
    - -
    -

    h

    -
    -
    hasClass
    -
    in file phpQueryObject.php, method phpQueryObject::hasClass()
        Enter description here...
    -
    hide
    -
    in file phpQueryObject.php, method phpQueryObject::hide()
    -
    html
    -
    in file phpQueryObject.php, method phpQueryObject::html()
        Enter description here...
    -
    htmlOuter
    -
    in file phpQueryObject.php, method phpQueryObject::htmlOuter()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    i

    -
    -
    $id
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$id
    -
    $isDocumentFragment
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isDocumentFragment
    -
    $isHTML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isHTML
    -
    $isXHTML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isXHTML
    -
    $isXML
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$isXML
    -
    import
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::import()
    -
    importAttr
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::importAttr()
    -
    inArray
    -
    in file phpQuery.php, method phpQuery::inArray()
    -
    index
    -
    in file phpQueryObject.php, method phpQueryObject::index()
        Enter description here...
    -
    insert
    -
    in file phpQueryObject.php, method phpQueryObject::insert()
        Various insert scenarios.
    -
    insertAfter
    -
    in file phpQueryObject.php, method phpQueryObject::insertAfter()
        Enter description here...
    -
    insertBefore
    -
    in file phpQueryObject.php, method phpQueryObject::insertBefore()
        Enter description here...
    -
    is
    -
    in file phpQueryObject.php, method phpQueryObject::is()
        Enter description here...
    -
    isChar
    -
    in file phpQueryObject.php, method phpQueryObject::isChar()
        Determines if $char is really a char.
    -
    isDocumentFragmentHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentHTML()
    -
    isDocumentFragmentXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentXHTML()
    -
    isDocumentFragmentXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isDocumentFragmentXML()
    -
    isFunction
    -
    in file phpQuery.php, method phpQuery::isFunction()
    -
    isHTML
    -
    in file phpQueryObject.php, method phpQueryObject::isHTML()
    -
    isMarkup
    -
    in file phpQuery.php, method phpQuery::isMarkup()
        Checks if $input is HTML string, which has to start with '<'.
    -
    isRegexp
    -
    in file phpQueryObject.php, method phpQueryObject::isRegexp()
    -
    isRoot
    -
    in file phpQueryObject.php, method phpQueryObject::isRoot()
    -
    issetGlobal
    -
    in file phpQueryEvents.php, method phpQueryEvents::issetGlobal()
    -
    isXHTML
    -
    in file phpQueryObject.php, method phpQueryObject::isXHTML()
    -
    isXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isXHTML()
    -
    isXML
    -
    in file phpQueryObject.php, method phpQueryObject::isXML()
    -
    isXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::isXML()
    -
    -
    - top
    -
    - -
    -

    k

    -
    -
    key
    -
    in file phpQueryObject.php, method phpQueryObject::key()
    -
    -
    - top
    -
    - -
    -

    l

    -
    -
    $lastModified
    -
    in file phpQuery.php, variable phpQuery::$lastModified
    -
    length
    -
    in file phpQueryObject.php, method phpQueryObject::length()
        Enter description here...
    -
    load
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::load()
    -
    load
    -
    in file phpQueryObject.php, method phpQueryObject::load()
        Enter description here...
    -
    loadDocument
    -
    in file phpQuery.php, method phpQuery::loadDocument()
        Reuses existing DOMDocument object.
    -
    loadMarkup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkup()
    -
    loadMarkupHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupHTML()
    -
    loadMarkupReset
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupReset()
    -
    loadMarkupXML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::loadMarkupXML()
    -
    -
    - top
    -
    - -
    -

    m

    -
    -
    makeArray
    -
    in file phpQuery.php, method phpQuery::makeArray()
    -
    map
    -
    in file phpQueryObject.php, method phpQueryObject::map()
        Enter description here...
    -
    map
    -
    in file phpQuery.php, method phpQuery::map()
    -
    markup
    -
    in file phpQueryObject.php, method phpQueryObject::markup()
        jQuey difference
    -
    markup
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::markup()
        Return document markup, starting with optional $node as root.
    -
    markupEvents
    -
    in file phpQueryObject.php, method phpQueryObject::markupEvents()
    -
    markupFixXHTML
    -
    in file DOMDocumentWrapper.php, method DOMDocumentWrapper::markupFixXHTML()
    -
    markupOuter
    -
    in file phpQueryObject.php, method phpQueryObject::markupOuter()
        jQuey difference
    -
    markupToPHP
    -
    in file phpQuery.php, method phpQuery::markupToPHP()
    -
    matchClasses
    -
    in file phpQueryObject.php, method phpQueryObject::matchClasses()
        Enter description here...
    -
    merge
    -
    in file phpQueryObject.php, method phpQueryObject::merge()
    -
    merge
    -
    in file phpQuery.php, method phpQuery::merge()
        Merge 2 phpQuery objects.
    -
    -
    - top
    -
    - -
    -

    n

    -
    -
    newDocument
    -
    in file phpQuery.php, method phpQuery::newDocument()
        Creates new document from markup.
    -
    newDocumentFile
    -
    in file phpQuery.php, method phpQuery::newDocumentFile()
        Creates new document from file $file.
    -
    newDocumentFileHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileHTML()
    -
    newDocumentFilePHP
    -
    in file phpQuery.php, method phpQuery::newDocumentFilePHP()
    -
    newDocumentFileXHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileXHTML()
    -
    newDocumentFileXML
    -
    in file phpQuery.php, method phpQuery::newDocumentFileXML()
    -
    newDocumentHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentHTML()
    -
    newDocumentPHP
    -
    in file phpQuery.php, method phpQuery::newDocumentPHP()
    -
    newDocumentXHTML
    -
    in file phpQuery.php, method phpQuery::newDocumentXHTML()
    -
    newDocumentXML
    -
    in file phpQuery.php, method phpQuery::newDocumentXML()
    -
    newInstance
    -
    in file phpQueryObject.php, method phpQueryObject::newInstance()
        Returns new instance of actual class.
    -
    next
    -
    in file phpQueryObject.php, method phpQueryObject::next()
        Double-function method.
    -
    nextAll
    -
    in file phpQueryObject.php, method phpQueryObject::nextAll()
    -
    not
    -
    in file phpQueryObject.php, method phpQueryObject::not()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    o

    -
    -
    $originalTarget
    -
    in file DOMEvent.php, variable DOMEvent::$originalTarget
        The original target of the event, before any retargetings (Mozilla-specific).
    -
    offsetExists
    -
    in file phpQueryObject.php, method phpQueryObject::offsetExists()
    -
    offsetGet
    -
    in file phpQueryObject.php, method phpQueryObject::offsetGet()
    -
    offsetSet
    -
    in file phpQueryObject.php, method phpQueryObject::offsetSet()
    -
    offsetUnset
    -
    in file phpQueryObject.php, method phpQueryObject::offsetUnset()
    -
    -
    - top
    -
    - -
    -

    p

    -
    -
    $params
    -
    in file Callback.php, variable Callback::$params
    -
    $plugins
    -
    in file phpQuery.php, variable phpQuery::$plugins
        Static namespace for plugins.
    -
    $pluginsLoaded
    -
    in file phpQuery.php, variable phpQuery::$pluginsLoaded
        List of loaded plugins.
    -
    $pluginsMethods
    -
    in file phpQuery.php, variable phpQuery::$pluginsMethods
    -
    $pluginsStaticMethods
    -
    in file phpQuery.php, variable phpQuery::$pluginsStaticMethods
    -
    $previous
    -
    in file phpQueryObject.php, variable phpQueryObject::$previous
    -
    param
    -
    in file phpQuery.php, method phpQuery::param()
        Enter description here...
    -
    param
    -
    in file Callback.php, method Callback::param()
    -
    parent
    -
    in file phpQueryObject.php, method phpQueryObject::parent()
        Enter description here...
    -
    parents
    -
    in file phpQueryObject.php, method phpQueryObject::parents()
        Enter description here...
    -
    parseJSON
    -
    in file phpQuery.php, method phpQuery::parseJSON()
        Parses JSON into proper PHP type.
    -
    parseSelector
    -
    in file phpQueryObject.php, method phpQueryObject::parseSelector()
    -
    php
    -
    in file phpQuery.php, method phpQuery::php()
    -
    php
    -
    in file phpQueryObject.php, method phpQueryObject::php()
        Just like html(), but returns markup with VALID (dangerous) PHP tags.
    -
    phpQuery
    -
    in file phpQuery.php, class phpQuery
        Static namespace for phpQuery functions.
    -
    phpQuery.php
    -
    procedural page phpQuery.php
    -
    phpQueryEvents
    -
    in file phpQueryEvents.php, class phpQueryEvents
        Event handling class.
    -
    phpQueryEvents.php
    -
    procedural page phpQueryEvents.php
    -
    phpQueryObject
    -
    in file phpQueryObject.php, class phpQueryObject
        Class representing phpQuery objects.
    -
    phpQueryObject.php
    -
    procedural page phpQueryObject.php
    -
    phpQueryPlugins
    -
    in file phpQuery.php, class phpQueryPlugins
        Plugins static namespace class.
    -
    phpToMarkup
    -
    in file phpQuery.php, method phpQuery::phpToMarkup()
    -
    plugin
    -
    in file phpQueryObject.php, method phpQueryObject::plugin()
        Enter description here...
    -
    plugin
    -
    in file phpQuery.php, method phpQuery::plugin()
        Extend phpQuery with $class from $file.
    -
    post
    -
    in file phpQuery.php, method phpQuery::post()
    -
    pq
    -
    in file phpQuery.php, method phpQuery::pq()
        Multi-purpose function.
    -
    pq
    -
    in file phpQuery.php, function pq()
        Shortcut to phpQuery::pq($arg1, $context) Chainable.
    -
    prepend
    -
    in file phpQueryObject.php, method phpQueryObject::prepend()
        Enter description here...
    -
    prependPHP
    -
    in file phpQueryObject.php, method phpQueryObject::prependPHP()
        Enter description here...
    -
    prependTo
    -
    in file phpQueryObject.php, method phpQueryObject::prependTo()
        Enter description here...
    -
    prev
    -
    in file phpQueryObject.php, method phpQueryObject::prev()
        Enter description here...
    -
    prevAll
    -
    in file phpQueryObject.php, method phpQueryObject::prevAll()
    -
    preventDefault
    -
    in file DOMEvent.php, method DOMEvent::preventDefault()
        Cancels the event (if it is cancelable).
    -
    pseudoClasses
    -
    in file phpQueryObject.php, method phpQueryObject::pseudoClasses()
    -
    -
    - top
    -
    - -
    -

    r

    -
    -
    $relatedTarget
    -
    in file DOMEvent.php, variable DOMEvent::$relatedTarget
        Identifies a secondary target for the event.
    -
    $root
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$root
        Document root, by default equals to document itself.
    -
    $root
    -
    in file phpQueryObject.php, variable phpQueryObject::$root
    -
    $runDefault
    -
    in file DOMEvent.php, variable DOMEvent::$runDefault
    -
    remove
    -
    in file phpQueryObject.php, method phpQueryObject::remove()
        Enter description here...
    -
    remove
    -
    in file phpQueryEvents.php, method phpQueryEvents::remove()
        Enter description here...
    -
    removeAttr
    -
    in file phpQueryObject.php, method phpQueryObject::removeAttr()
        Enter description here...
    -
    removeClass
    -
    in file phpQueryObject.php, method phpQueryObject::removeClass()
        Enter description here...
    -
    replaceAll
    -
    in file phpQueryObject.php, method phpQueryObject::replaceAll()
        Enter description here...
    -
    replaceWith
    -
    in file phpQueryObject.php, method phpQueryObject::replaceWith()
        Enter description here...
    -
    replaceWithPHP
    -
    in file phpQueryObject.php, method phpQueryObject::replaceWithPHP()
        Enter description here...
    -
    reverse
    -
    in file phpQueryObject.php, method phpQueryObject::reverse()
        Enter description here...
    -
    rewind
    -
    in file phpQueryObject.php, method phpQueryObject::rewind()
    -
    runQuery
    -
    in file phpQueryObject.php, method phpQueryObject::runQuery()
    -
    -
    - top
    -
    - -
    -

    s

    -
    -
    selectDocument
    -
    in file phpQuery.php, method phpQuery::selectDocument()
        Sets default document to $id. Document has to be loaded prior to using this method.
    -
    serialize
    -
    in file phpQueryObject.php, method phpQueryObject::serialize()
        Enter description here...
    -
    serializeArray
    -
    in file phpQueryObject.php, method phpQueryObject::serializeArray()
        Enter description here...
    -
    setNode
    -
    in file phpQueryEvents.php, method phpQueryEvents::setNode()
    -
    show
    -
    in file phpQueryObject.php, method phpQueryObject::show()
    -
    siblings
    -
    in file phpQueryObject.php, method phpQueryObject::siblings()
        Enter description here...
    -
    size
    -
    in file phpQueryObject.php, method phpQueryObject::size()
        Enter description here...
    -
    slice
    -
    in file phpQueryObject.php, method phpQueryObject::slice()
        Enter description here...
    -
    stack
    -
    in file phpQueryObject.php, method phpQueryObject::stack()
        Attribute method.
    -
    stackIsRoot
    -
    in file phpQueryObject.php, method phpQueryObject::stackIsRoot()
    -
    stopPropagation
    -
    in file DOMEvent.php, method DOMEvent::stopPropagation()
        Stops the propagation of events further along in the DOM.
    -
    submit
    -
    in file phpQueryObject.php, method phpQueryObject::submit()
        Enter description here...
    -
    switchWith
    -
    in file phpQueryObject.php, method phpQueryObject::switchWith()
    -
    -
    - top
    -
    - -
    -

    t

    -
    -
    $target
    -
    in file DOMEvent.php, variable DOMEvent::$target
        Returns a reference to the target to which the event was originally dispatched.
    -
    $timeStamp
    -
    in file DOMEvent.php, variable DOMEvent::$timeStamp
        Returns the time that the event was created.
    -
    $type
    -
    in file DOMEvent.php, variable DOMEvent::$type
        Returns the name of the event (case-insensitive).
    -
    text
    -
    in file phpQueryObject.php, method phpQueryObject::text()
        Return joined text content.
    -
    toggleClass
    -
    in file phpQueryObject.php, method phpQueryObject::toggleClass()
        Enter description here...
    -
    toJSON
    -
    in file phpQuery.php, method phpQuery::toJSON()
        Returns JSON representation of $data.
    -
    toReference
    -
    in file phpQueryObject.php, method phpQueryObject::toReference()
        Saves actual object to $var by reference.
    -
    toRoot
    -
    in file phpQueryObject.php, method phpQueryObject::toRoot()
        Enter description here...
    -
    trigger
    -
    in file phpQueryObject.php, method phpQueryObject::trigger()
        Trigger a type of event on every matched element.
    -
    trigger
    -
    in file phpQueryEvents.php, method phpQueryEvents::trigger()
        Trigger a type of event on every matched element.
    -
    triggerHandler
    -
    in file phpQueryObject.php, method phpQueryObject::triggerHandler()
        This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
    -
    trim
    -
    in file phpQuery.php, method phpQuery::trim()
    -
    -
    - top
    -
    - -
    -

    u

    -
    -
    unbind
    -
    in file phpQueryObject.php, method phpQueryObject::unbind()
        Enter description here...
    -
    unique
    -
    in file phpQuery.php, method phpQuery::unique()
    -
    unloadDocument
    -
    in file phpQueryObject.php, method phpQueryObject::unloadDocument()
        Unloads whole document from memory.
    -
    unloadDocuments
    -
    in file phpQuery.php, method phpQuery::unloadDocuments()
        Unloades all or specified document from memory.
    -
    unQuote
    -
    in file phpQueryObject.php, method phpQueryObject::unQuote()
    -
    unsafePHPTags
    -
    in file phpQuery.php, method phpQuery::unsafePHPTags()
        Parses phpQuery object or HTML result against PHP tags and makes them active.
    -
    -
    - top
    -
    - -
    -

    v

    -
    -
    $valid
    -
    in file phpQueryObject.php, variable phpQueryObject::$valid
        Iterator interface helper
    -
    val
    -
    in file phpQueryObject.php, method phpQueryObject::val()
        Return form element value.
    -
    valid
    -
    in file phpQueryObject.php, method phpQueryObject::valid()
    -
    -
    - top
    -
    - -
    -

    w

    -
    -
    whois
    -
    in file phpQueryObject.php, method phpQueryObject::whois()
    -
    wrap
    -
    in file phpQueryObject.php, method phpQueryObject::wrap()
        Enter description here...
    -
    wrapAll
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAll()
        Enter description here...
    -
    wrapAllOld
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAllOld()
        Enter description here...
    -
    wrapAllPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapAllPHP()
        Enter description here...
    -
    wrapInner
    -
    in file phpQueryObject.php, method phpQueryObject::wrapInner()
        Enter description here...
    -
    wrapInnerPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapInnerPHP()
        Enter description here...
    -
    wrapPHP
    -
    in file phpQueryObject.php, method phpQueryObject::wrapPHP()
        Enter description here...
    -
    -
    - top
    -
    - -
    -

    x

    -
    -
    $xpath
    -
    in file DOMDocumentWrapper.php, variable DOMDocumentWrapper::$xpath
    -
    $xpath
    -
    in file phpQueryObject.php, variable phpQueryObject::$xpath
        XPath interface.
    -
    xml
    -
    in file phpQueryObject.php, method phpQueryObject::xml()
    -
    xmlOuter
    -
    in file phpQueryObject.php, method phpQueryObject::xmlOuter()
    -
    -
    - top
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/errors.html b/api-reference/errors.html deleted file mode 100644 index e974434..0000000 --- a/api-reference/errors.html +++ /dev/null @@ -1,89 +0,0 @@ - - -phpDocumentor Parser Errors and Warnings - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -Post-parsing
    -DOMDocumentWrapper.php
    -DOMEvent.php
    -phpQuery.php
    -phpQueryEvents.php
    -phpQueryObject.php
    - -

    Callback.php

    -

    Warnings:


    -Warning on line 7 - no @package tag was used in a DocBlock for class Callback
    -Warning on line 26 - no @package tag was used in a DocBlock for class CallbackReference
    -Warning on line 37 - File "/home/bob/workspace/phpQuery/phpQuery/Callback.php" has no page-level DocBlock, use @package in the first DocBlock to create one
    -Warning on line 37 - no @package tag was used in a DocBlock for class CallbackParam
    - -

    DOMDocumentWrapper.php

    -

    Warnings:


    -Warning on line 11 - DocBlock would be page-level, but precedes class "DOMDocumentWrapper", use another DocBlock to document the file
    - -

    DOMEvent.php

    -

    Warnings:


    -Warning on line 10 - DocBlock would be page-level, but precedes class "DOMEvent", use another DocBlock to document the file
    - -

    phpQuery.php

    -

    Warnings:


    -Warning on line 16 - Page-level DocBlock precedes "define DOMDOCUMENT", use another DocBlock to document the source element
    -Warning on line 897 - Unknown tag "@protected" used
    -

    Errors:


    -Error on line 1013 - DocBlock has multiple @package tags, illegal. ignoring additional tag "@package phpQuery"
    - -

    phpQueryEvents.php

    -

    Warnings:


    -Warning on line 8 - DocBlock would be page-level, but precedes class "phpQueryEvents", use another DocBlock to document the file
    - -

    phpQueryObject.php

    -

    Warnings:


    -Warning on line 13 - DocBlock would be page-level, but precedes class "phpQueryObject", use another DocBlock to document the file
    -Warning on line 1580 - Unknown tag "@testme" used
    -Warning on line 2188 - Unknown tag "@testme" used
    -

    Errors:


    -Error on line 2447 - @access was passed neither "public" nor "private." Was passed: "private - todo refactor to stackcontainsnode"
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:30 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/index.html b/api-reference/index.html deleted file mode 100644 index da8454e..0000000 --- a/api-reference/index.html +++ /dev/null @@ -1,81 +0,0 @@ - - -Generated Documentation - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Generated Documentation

    -Welcome to phpQuery!
    -
    -This documentation was generated by phpDocumentor v1.4.2
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/li_phpQuery.html b/api-reference/li_phpQuery.html deleted file mode 100644 index da8454e..0000000 --- a/api-reference/li_phpQuery.html +++ /dev/null @@ -1,81 +0,0 @@ - - -Generated Documentation - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Generated Documentation

    -Welcome to phpQuery!
    -
    -This documentation was generated by phpDocumentor v1.4.2
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/media/background.png b/api-reference/media/background.png deleted file mode 100644 index d6f36f6068d30005864e49d371606d39dbac3be6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^CxKXmgBeH)?09($NNJb2MwB=gr6!hS=I1GdWag$a zl;L41_usi$G7`mY9E|l(K3^3(}Yz5wYCnP1)Tp+R!$e1@pO+j=b55= cOIuv|iyatv1txKu0`)U^y85}Sb4q9e01EU+A^-pY diff --git a/api-reference/media/empty.png b/api-reference/media/empty.png deleted file mode 100644 index a9f29bb161a7b1efd9cc85043bc235e1a5060780..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx3?wy9o9qTs+9j?LCC){ui6xo&c?uz!xv320 z`3gqn3VHcu3PuJ7Mhb>zR)*$Q#>NWT28IR({)IOifZEtgJbhi+FL6ur3u;#0rMq>1fPyUPj=qiz3>*8o|0J>k`OE=6A+G=b|6hJY`UH^6SQ6wH o%;50sMjDXA<>}%WQgJIe0mx=zV0@~64`c#^r>mdKI;Vst04^Iepa1{> diff --git a/api-reference/media/style.css b/api-reference/media/style.css deleted file mode 100644 index bc65d89..0000000 --- a/api-reference/media/style.css +++ /dev/null @@ -1,195 +0,0 @@ -.php { - padding: 1em; -} -.php-src { font-family: 'Courier New', Courier, monospace; font-weight: normal; } - -body -{ - color: #000000; - background-color: #ffffff; - background-image: url("background.png"); - background-repeat: repeat-y; - font-family: tahoma, verdana, arial, sans-serif; - font-size: 10pt; - margin: 0; - padding: 0; -} - -a -{ - color: #000099; - background-color: transparent; - text-decoration: none; -} - -a:hover -{ - text-decoration: underline; -} - -a.menu -{ - color: #ffffff; - background-color: transparent; -} - -td -{ - font-size: 10pt; -} - -td.header_top -{ - color: #ffffff; - background-color: #9999cc; - font-size: 16pt; - font-weight: bold; - text-align: right; - padding: 10px; -} - -td.header_line -{ - color: #ffffff; - background-color: #333366; -} - -td.header_menu -{ - color: #ffffff; - background-color: #666699; - font-size: 8pt; - text-align: right; - padding: 2px; - padding-right: 5px; -} - -td.menu -{ - padding: 2px; - padding-left: 5px; -} - -td.code_border -{ - color: #000000; - background-color: #c0c0c0; -} - -td.code -{ - color: #000000; - background-color: #f0f0f0; -} - -td.type -{ - font-style: italic; -} - -div.credit -{ - font-size: 8pt; - text-align: center; -} - -div.package -{ - padding-left: 5px; -} - -div.tags -{ - padding-left: 15px; -} - -div.function -{ - padding-left: 15px; -} - -div.top -{ - font-size: 8pt; -} - -div.warning -{ - color: #ff0000; - background-color: transparent; -} - -div.description -{ - padding-left: 15px; -} - -hr -{ - height: 1px; - border-style: solid; - border-color: #c0c0c0; - margin-top: 10px; - margin-bottom: 10px; -} - -span.smalllinenumber -{ - font-size: 8pt; -} - -ul { - margin-left: 0px; - padding-left: 8px; -} -/* Syntax highlighting */ - -.src-code { background-color: #f5f5f5; border: 1px solid #ccc9a4; padding: 0 0 0 1em; margin : 0px; - font-family: 'Courier New', Courier, monospace; font-weight: normal; } -.src-line { font-family: 'Courier New', Courier, monospace; font-weight: normal; } - -.src-comm { color: green; } -.src-id { } -.src-inc { color: #0000FF; } -.src-key { color: #0000FF; } -.src-num { color: #CC0000; } -.src-str { color: #66cccc; } -.src-sym { font-weight: bold; } -.src-var { } - -.src-php { font-weight: bold; } - -.src-doc { color: #009999 } -.src-doc-close-template { color: #0000FF } -.src-doc-coretag { color: #0099FF; font-weight: bold } -.src-doc-inlinetag { color: #0099FF } -.src-doc-internal { color: #6699cc } -.src-doc-tag { color: #0080CC } -.src-doc-template { color: #0000FF } -.src-doc-type { font-style: italic } -.src-doc-var { font-style: italic } - -.tute-tag { color: #009999 } -.tute-attribute-name { color: #0000FF } -.tute-attribute-value { color: #0099FF } -.tute-entity { font-weight: bold; } -.tute-comment { font-style: italic } -.tute-inline-tag { color: #636311; font-weight: bold } - -/* tutorial */ - -.authors { } -.author { font-style: italic; font-weight: bold } -.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal } -.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; } -.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap; } -.release-info { font-size: 85%; font-style: italic; margin: 1em 0em } -.ref-title-box { } -.ref-title { } -.ref-purpose { font-style: italic; color: #666666 } -.ref-synopsis { } -.title { font-weight: bold; margin: 1em 0em 0em 0em; padding: .25em; border: 2px solid #999999; background-color: #9999CC } -.cmd-synopsis { margin: 1em 0em } -.cmd-title { font-weight: bold } -.toc { margin-left: 2em; padding-left: 0em } - diff --git a/api-reference/phpQuery/Callback.html b/api-reference/phpQuery/Callback.html deleted file mode 100644 index e0e1439..0000000 --- a/api-reference/phpQuery/Callback.html +++ /dev/null @@ -1,305 +0,0 @@ - - -Docs For Class Callback - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: Callback

    -Source Location: /Callback.php

    - - - - - - - - - - -
    - -

    Class Overview

    -

    -
    Callback class implementing ParamStructures, pattern similar to Currying.


    -

    Author(s):

    -
      -
    • Tobiasz Cudnik
    • -
    - - - - - - - -
    -

    Variables

    - -
    -

    Methods

    - -
    -
    - - - - - - - - - -
    -

    Child classes:

    -
    -
    -
    CallbackReference
    -
    Callback class implementing ParamStructures, pattern similar to Currying.
    -
    -
    -
    -
    - - -

    Class Details

    -
    -[line 8]
    -Callback class implementing ParamStructures, pattern similar to Currying.



    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik
    link:  http://code.google.com/p/phpquery/wiki/Callbacks#Param_Structures
    -
    -


    -
    [ Top ]

    - -
    - -

    Class Variables

    -
    - -

    -

    $callback =  null

    -

    [line 9]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $params =  null

    -

    [line 10]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    -

    - -
    - -

    Class Methods

    -
    - -
    - -

    constructor __construct [line 11]

    -
    -
    -
    - Callback __construct( - -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -

    Overridden in child classes as:
    -

    -
    CallbackReference::__construct()
    -
    -
    -

    - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    method param [line 22]

    -
    -
    -
    - void param( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/CallbackParam.html b/api-reference/phpQuery/CallbackParam.html deleted file mode 100644 index 8a40896..0000000 --- a/api-reference/phpQuery/CallbackParam.html +++ /dev/null @@ -1,122 +0,0 @@ - - -Docs For Class CallbackParam - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: CallbackParam

    -Source Location: /Callback.php

    - - - - - - - - -
    - -

    Class Overview

    -

    -


    - - - - - - - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 38]
    -


    -
    [ Top ]

    - - - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:24 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/CallbackReference.html b/api-reference/phpQuery/CallbackReference.html deleted file mode 100644 index dd99cb2..0000000 --- a/api-reference/phpQuery/CallbackReference.html +++ /dev/null @@ -1,234 +0,0 @@ - - -Docs For Class CallbackReference - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: CallbackReference

    -Source Location: /Callback.php

    - - - - - - - - - -
    - -

    Class Overview

    -
    Callback
    -   |
    -   --CallbackReference

    -
    Callback class implementing ParamStructures, pattern similar to Currying.


    -

    Author(s):

    -
      -
    • Tobiasz Cudnik
    • -
    - - - - - - - -
    -

    Methods

    - -
    -
    - - - - - - - - - - -
    -

    Inherited Variables

    -
    -

    Class: Callback

    -
    -
    - Callback::$callback -
    -
    - -
    -
    - Callback::$params -
    -
    - -
    -
    -
    -
    -

    Inherited Methods

    -
    -

    Class: Callback

    -
    -
    - Callback::__construct() -
    -
    - -
    -
    - Callback::param() -
    -
    - -
    -
    -
    -
    -
    - - -

    Class Details

    -
    -[line 27]
    -Callback class implementing ParamStructures, pattern similar to Currying.



    -

    Tags:

    -
    - - - - -
    author:  Tobiasz Cudnik
    -
    -


    -
    [ Top ]

    - - -
    - -

    Class Methods

    -
    - -
    - -

    constructor __construct [line 34]

    -
    -
    -
    - CallbackReference __construct( -$reference -&$reference, [$paramIndex -$name = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  implement $paramIndex; param index choose which callback param will be passed to reference
    access:  public
    -
    -

    - - Overrides Callback::__construct() (parent method not documented)

    -

    Parameters:

    -
    - - - - - - - - - - - -
    $reference  &$reference  
    $paramIndex  $name  
    -

    -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:24 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/DOMDocumentWrapper.html b/api-reference/phpQuery/DOMDocumentWrapper.html deleted file mode 100644 index 1e3df6c..0000000 --- a/api-reference/phpQuery/DOMDocumentWrapper.html +++ /dev/null @@ -1,1591 +0,0 @@ - - -Docs For Class DOMDocumentWrapper - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: DOMDocumentWrapper

    -Source Location: /DOMDocumentWrapper.php

    - - - - - - - - - - -
    - -

    Class Overview

    -

    -
    DOMDocumentWrapper class simplifies work with DOMDocument.


    -

    Author(s):

    - - - - - - - - -
    -

    Variables

    - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 12]
    -DOMDocumentWrapper class simplifies work with DOMDocument.

    Know bug:

    • in XHTML fragments,
      changes to




    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    todo:  check XML catalogs compatibility
    -
    -


    -
    [ Top ]

    - -
    - -

    Class Variables

    -
    - -

    -

    $charset =

    -

    [line 43]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $contentType =  ''

    -

    [line 22]

    -

    -

    Tags:

    -
    - - - - - - - -
    todo:  Rewrite as method and quess if null.
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $document =

    -

    [line 16]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  DOMDocument
    -


    -
    [ Top ]

    - -

    -

    $events = array()

    -

    [line 24]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $eventsGlobal = array()

    -

    [line 26]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $eventsNodes = array()

    -

    [line 25]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $frames = array()

    -

    [line 31]

    - TODO



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $id =

    -

    [line 17]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $isDocumentFragment =  null

    -

    [line 39]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $isHTML =  false

    -

    [line 42]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $isXHTML =  false

    -

    [line 41]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $isXML =  false

    -

    [line 40]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $root =

    -

    [line 38]

    - Document root, by default equals to document itself.

    Used by documentFragments.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  DOMNode
    -


    -
    [ Top ]

    - -

    -

    $xpath =

    -

    [line 23]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    -

    - -
    - -

    Class Methods

    -
    -
    - -

    static method debug [line 556]

    -
    -
    -
    - static void debug( - -$text) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $text  
    -

    -
    [ Top ]
    -
    -
    - -

    static method expandEmptyTag [line 568]

    -
    -
    -
    - static unknown_type expandEmptyTag( -$tag -$tag, $xml -$xml) -
    -

    - - expandEmptyTag



    -

    Tags:

    -
    - - - - - - - - - - -
    author:  mjaque at ilkebenson dot com
    link:  http://pl2.php.net/manual/en/domdocument.savehtml.php#81256
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $tag  $tag  
    $xml  $xml  
    -

    -
    [ Top ]
    -
    -
    - -

    static method isDocumentFragmentHTML [line 344]

    -
    -
    -
    - static void isDocumentFragmentHTML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    static method isDocumentFragmentXHTML [line 350]

    -
    -
    -
    - static void isDocumentFragmentXHTML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    static method isDocumentFragmentXML [line 347]

    -
    -
    -
    - static void isDocumentFragmentXML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    static method markupFixXHTML [line 550]

    -
    -
    -
    - static void markupFixXHTML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    - -
    - -

    constructor __construct [line 44]

    -
    -
    -
    - DOMDocumentWrapper __construct( -[ -$markup = null], [ -$contentType = null], [ -$newDocumentID = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $markup  
      $contentType  
      $newDocumentID  
    -

    -
    [ Top ]
    -
    -
    - -

    method afterMarkupLoad [line 64]

    -
    -
    -
    - void afterMarkupLoad( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method charsetAppendToHTML [line 317]

    -
    -
    -
    - void charsetAppendToHTML( - -$html, -$charset, [ -$xhtml = false]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $html  
      $charset  
      $xhtml  
    -

    -
    [ Top ]
    -
    -
    - -

    method charsetAppendToXML [line 340]

    -
    -
    -
    - void charsetAppendToXML( - -$markup, -$charset) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    method charsetFromHTML [line 303]

    -
    -
    -
    - void charsetFromHTML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method charsetFromXML [line 307]

    -
    -
    -
    - void charsetFromXML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method contentTypeFromHTML [line 289]

    -
    -
    -
    - array contentTypeFromHTML( -$markup -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    return:  contentType, charset
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $markup  $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method contentTypeToArray [line 272]

    -
    -
    -
    - void contentTypeToArray( - -$contentType) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $contentType  
    -

    -
    [ Top ]
    -
    -
    - -

    method documentCreate [line 107]

    -
    -
    -
    - void documentCreate( - -$charset, [ -$version = '1.0']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $charset  
      $version  
    -

    -
    [ Top ]
    -
    -
    - -

    method documentFragmentCreate [line 389]

    -
    -
    -
    - DOMDocumentWrapper documentFragmentCreate( -$source -$source, [ -$charset = null]) -
    -

    - - Creates new document fragment.



    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $source  $source  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    method documentFragmentToMarkup [line 459]

    -
    -
    -
    - void documentFragmentToMarkup( - -$fragment) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $fragment  
    -

    -
    [ Top ]
    -
    -
    - -

    method import [line 363]

    -
    -
    -
    - array import( -$source -$source, [$target -$sourceCharset = null], $sourceCharset -2) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    return:  Array of imported nodes.
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    $sourceCharset  2  
    $source  $source  
    $target  $sourceCharset  
    -

    -
    [ Top ]
    -
    -
    - -

    method importAttr [line 353]

    -
    -
    -
    - void importAttr( - -$value) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method isXHTML [line 257]

    -
    -
    -
    - void isXHTML( -[ -$markup = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method isXML [line 268]

    -
    -
    -
    - void isXML( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method load [line 48]

    -
    -
    -
    - void load( - -$markup, [ -$contentType = null], [ -$newDocumentID = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $markup  
      $contentType  
      $newDocumentID  
    -

    -
    [ Top ]
    -
    -
    - -

    method loadMarkup [line 69]

    -
    -
    -
    - void loadMarkup( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method loadMarkupHTML [line 119]

    -
    -
    -
    - void loadMarkupHTML( - -$markup, [ -$requestedCharset = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $requestedCharset  
    -

    -
    [ Top ]
    -
    -
    - -

    method loadMarkupReset [line 104]

    -
    -
    -
    - void loadMarkupReset( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method loadMarkupXML [line 165]

    -
    -
    -
    - void loadMarkupXML( - -$markup, [ -$requestedCharset = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $requestedCharset  
    -

    -
    [ Top ]
    -
    -
    - -

    method markup [line 486]

    -
    -
    -
    - string markup( -[$node -$nodes = null], [ -$innerMarkup = false]) -
    -

    - - Return document markup, starting with optional $node as root.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $node  $nodes  DOMNode|DOMNodeList
      $innerMarkup  
    -

    -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:24 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/DOMEvent.html b/api-reference/phpQuery/DOMEvent.html deleted file mode 100644 index 3bde79f..0000000 --- a/api-reference/phpQuery/DOMEvent.html +++ /dev/null @@ -1,582 +0,0 @@ - - -Docs For Class DOMEvent - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: DOMEvent

    -Source Location: /DOMEvent.php

    - - - - - - - - - - -
    - -

    Class Overview

    -

    -
    DOMEvent class.


    -

    Author(s):

    - - - - - - - - -
    -

    Variables

    - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 11]
    -DOMEvent class.

    Based on




    -

    Tags:

    -
    - - - - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    link:  http://developer.mozilla.org/En/DOM:event
    todo:  implement ArrayAccess ?
    -
    -


    -
    [ Top ]

    - -
    - -

    Class Variables

    -
    - -

    -

    $bubbles =  true

    -

    [line 17]

    - Returns a boolean indicating whether the event bubbles up through the DOM or not.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $cancelable =  true

    -

    [line 23]

    - Returns a boolean indicating whether the event is cancelable.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $currentTarget =

    -

    [line 29]

    - Returns a reference to the currently registered target for the event.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $data =  null

    -

    [line 85]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $detail =

    -

    [line 36]

    - Returns detail about the event, depending on the type of event.



    -

    Tags:

    -
    - - - - - - - -
    link:  http://developer.mozilla.org/en/DOM/event.detail
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $eventPhase =

    -

    [line 45]

    - Used to indicate which phase of the event flow is currently being evaluated.

    NOT IMPLEMENTED




    -

    Tags:

    -
    - - - - - - - -
    link:  http://developer.mozilla.org/en/DOM/event.eventPhase
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $explicitOriginalTarget =

    -

    [line 53]

    - The explicit original target of the event (Mozilla-specific).

    NOT IMPLEMENTED




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $originalTarget =

    -

    [line 61]

    - The original target of the event, before any retargetings (Mozilla-specific).

    NOT IMPLEMENTED




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $relatedTarget =

    -

    [line 67]

    - Identifies a secondary target for the event.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $runDefault =  true

    -

    [line 84]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $target =

    -

    [line 73]

    - Returns a reference to the target to which the event was originally dispatched.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $timeStamp =

    -

    [line 79]

    - Returns the time that the event was created.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    $type =

    -

    [line 83]

    - Returns the name of the event (case-insensitive).



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    -

    - -
    - -

    Class Methods

    -
    - -
    - -

    constructor __construct [line 86]

    -
    -
    -
    - DOMEvent __construct( - -$data) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $data  
    -

    -
    [ Top ]
    -
    -
    - -

    method preventDefault [line 97]

    -
    -
    -
    - void preventDefault( -) -
    -

    - - Cancels the event (if it is cancelable).



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method stopPropagation [line 104]

    -
    -
    -
    - void stopPropagation( -) -
    -

    - - Stops the propagation of events further along in the DOM.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:25 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_Callback.php.html b/api-reference/phpQuery/_Callback.php.html deleted file mode 100644 index 32c0588..0000000 --- a/api-reference/phpQuery/_Callback.php.html +++ /dev/null @@ -1,99 +0,0 @@ - - -Docs for page Callback.php - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Procedural File: Callback.php

    -Source Location: /Callback.php

    - -
    -
    - -
    -

    Classes:

    -
    Callback
    -
    Callback class implementing ParamStructures, pattern similar to Currying.
    -
    CallbackReference
    -
    Callback class implementing ParamStructures, pattern similar to Currying.
    -
    CallbackParam
    -
    -


    - -

    Page Details:

    -

    -

    -

    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:23 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_DOMDocumentWrapper.php.html b/api-reference/phpQuery/_DOMDocumentWrapper.php.html deleted file mode 100644 index 5ba7de4..0000000 --- a/api-reference/phpQuery/_DOMDocumentWrapper.php.html +++ /dev/null @@ -1,114 +0,0 @@ - - - Docs for page DOMDocumentWrapper.php - - - - - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - ` - - - - - - -
    - - - - -
    - -

    Procedural File: DOMDocumentWrapper.php

    - Source Location: /DOMDocumentWrapper.php

    - -
    -
    - -
    -

    Classes:

    -
    DOMDocumentWrapper
    -
    DOMDocumentWrapper class simplifies work with DOMDocument.
    -
    -

    - -

    Page Details:

    -

    -

    -

    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:24 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_DOMEvent.php.html b/api-reference/phpQuery/_DOMEvent.php.html deleted file mode 100644 index 78eccf7..0000000 --- a/api-reference/phpQuery/_DOMEvent.php.html +++ /dev/null @@ -1,95 +0,0 @@ - - -Docs for page DOMEvent.php - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Procedural File: DOMEvent.php

    -Source Location: /DOMEvent.php

    - -
    -
    - -
    -

    Classes:

    -
    DOMEvent
    -
    DOMEvent class.
    -


    - -

    Page Details:

    -

    -

    -

    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:25 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_phpQuery.php.html b/api-reference/phpQuery/_phpQuery.php.html deleted file mode 100644 index 458e6db..0000000 --- a/api-reference/phpQuery/_phpQuery.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - -Docs for page phpQuery.php - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Procedural File: phpQuery.php

    -Source Location: /phpQuery.php

    - -
    -
    - -
    -

    Classes:

    -
    phpQuery
    -
    Static namespace for phpQuery functions.
    -
    phpQueryPlugins
    -
    Plugins static namespace class.
    -


    - -

    Page Details:

    -phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library.



    -

    Tags:

    -
    - - - - - - - - - - - - - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    version:  0.9.5 beta3
    link:  http://jquery.com/
    link:  http://phpquery-library.blogspot.com/
    link:  http://code.google.com/p/phpquery/
    license:  MIT License
    -
    -

    -

    Includes:

    -
    -require_once(dirname(__FILE__).'/phpQueryObject.php') [line 25]
    -require_once(dirname(__FILE__).'/Callback.php') [line 24]
    -require_once(dirname(__FILE__).'/DOMEvent.php') [line 21]
    -require_once(dirname(__FILE__).'/bootstrap.php') [line 1025]
    -require_once(dirname(__FILE__).'/compat/mbstring.php') [line 26]
    -require_once(dirname(__FILE__).'/DOMDocumentWrapper.php') [line 22]
    -require_once(dirname(__FILE__).'/phpQueryEvents.php') [line 23]
    -
    -

    -

    -
    - -

    DOMDOCUMENT [line 17]

    -
    -
    -
    - DOMDOCUMENT = 'DOMDocument' -
    -
    - -
    -
    -
    [ Top ]


    -
    - -

    DOMELEMENT [line 18]

    -
    -
    -
    - DOMELEMENT = 'DOMElement' -
    -
    - -
    -
    -
    [ Top ]


    -
    - -

    DOMNODE [line 20]

    -
    -
    -
    - DOMNODE = 'DOMNode' -
    -
    - -
    -
    -
    [ Top ]


    -
    - -

    DOMNODELIST [line 19]

    -
    -
    -
    - DOMNODELIST = 'DOMNodeList' -
    -
    - -
    -
    -
    [ Top ]


    -
    -
    - -

    pq [line 1008]

    -
    -
    -
    - phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup pq( - $arg1, [ $context = null]) -
    -

    - - Shortcut to phpQuery::pq($arg1, $context) Chainable.



    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    see:  phpQuery::pq()
    -
    -

    - -

    Parameters

    - - - - - - - - - - - -
      $arg1  
      $context  
    -
    [ Top ]


    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:25 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_phpQueryEvents.php.html b/api-reference/phpQuery/_phpQueryEvents.php.html deleted file mode 100644 index c08bf33..0000000 --- a/api-reference/phpQuery/_phpQueryEvents.php.html +++ /dev/null @@ -1,95 +0,0 @@ - - -Docs for page phpQueryEvents.php - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Procedural File: phpQueryEvents.php

    -Source Location: /phpQueryEvents.php

    - -
    -
    - -
    -

    Classes:

    -
    phpQueryEvents
    -
    Event handling class.
    -


    - -

    Page Details:

    -

    -

    -

    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:26 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/_phpQueryObject.php.html b/api-reference/phpQuery/_phpQueryObject.php.html deleted file mode 100644 index 4c50353..0000000 --- a/api-reference/phpQuery/_phpQueryObject.php.html +++ /dev/null @@ -1,95 +0,0 @@ - - -Docs for page phpQueryObject.php - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Procedural File: phpQueryObject.php

    -Source Location: /phpQueryObject.php

    - -
    -
    - -
    -

    Classes:

    -
    phpQueryObject
    -
    Class representing phpQuery objects.
    -


    - -

    Page Details:

    -

    -

    -

    -
    - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:26 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/phpQuery.html b/api-reference/phpQuery/phpQuery.html deleted file mode 100644 index 378612d..0000000 --- a/api-reference/phpQuery/phpQuery.html +++ /dev/null @@ -1,2754 +0,0 @@ - - -Docs For Class phpQuery - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: phpQuery

    -Source Location: /phpQuery.php

    - - - - - - - - - - -
    - -

    Class Overview

    -

    -
    Static namespace for phpQuery functions.


    -

    Author(s):

    - - - - - - - - -
    -

    Variables

    - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 33]
    -Static namespace for phpQuery functions.



    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    abstract:  
    -
    -


    -
    [ Top ]

    - -
    - -

    Class Variables

    -
    - -

    -

    static $active =  0

    -

    [line 96]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $ajaxAllowedHosts = array(
    -      '.'
    -   )

    -

    [line 66]

    - Hosts allowed for AJAX connections.

    Dot '.' means $_SERVER['HTTP_HOST'] (if any).




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  array
    -


    -
    [ Top ]

    - -

    -

    static $ajaxSettings = array(
    -      'url' => '',//TODO
    -      'global' => true,
    -      'type' => "GET",
    -      'timeout' => null,
    -      'contentType' => "application/x-www-form-urlencoded",
    -      'processData' => true,
    -//      'async' => true,
    -      'data' => null,
    -      'username' => null,
    -      'password' => null,
    -      'accepts' => array(
    -         'xml' => "application/xml, text/xml",
    -         'html' => "text/html",
    -         'script' => "text/javascript, application/javascript",
    -         'json' => "application/json, text/javascript",
    -         'text' => "text/plain",
    -         '_default' => "*/*"
    -      ))

    -

    [line 75]

    - AJAX settings.



    -

    Tags:

    -
    - - - - - - - -
    var:  XXX should it be static or not ?
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  array
    -


    -
    [ Top ]

    - -

    -

    static $debug =  false

    -

    [line 34]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $defaultCharset =  'UTF-8'

    -

    [line 45]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $defaultDoctype =  '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    -"http://www.w3.org/TR/html4/loose.dtd">'

    -

    [line 43]

    - Applies only to HTML.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    static $defaultDocumentID =  null

    -

    [line 36]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $documents = array()

    -

    [line 35]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $dumpCount =  0

    -

    [line 97]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $lastModified =  null

    -

    [line 95]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $plugins = array()

    -

    [line 51]

    - Static namespace for plugins.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  object
    -


    -
    [ Top ]

    - -

    -

    static $pluginsLoaded = array()

    -

    [line 57]

    - List of loaded plugins.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  unknown_type
    -


    -
    [ Top ]

    - -

    -

    static $pluginsMethods = array()

    -

    [line 58]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    static $pluginsStaticMethods = array()

    -

    [line 59]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    -

    - -
    - -

    Class Methods

    -
    -
    - -

    static method ajax [line 540]

    -
    -
    -
    - static Zend_Http_Client ajax( -[array -$options = array()], [ -$xhr = null]) -
    -

    - - Make an AJAX request.



    -

    Tags:

    -
    - - - - - - - - - - - - - - - - -
    link:  http://docs.jquery.com/Ajax/jQuery.ajax
    TODO:  $options['cache']
    TODO:  $options['processData']
    TODO:  support callbackStructure like each() and map()
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    array  $options  See $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions Additional options are: 'document' - document for global events, @see phpQuery::getDocumentID() 'referer' - implemented 'requested_with' - TODO; not implemented (X-Requested-With)
      $xhr  
    -

    -
    [ Top ]
    -
    -
    - -

    static method ajaxAllowHost [line 705]

    -
    -
    -
    - static void ajaxAllowHost( - -$host1, [ -$host2 = null], [ -$host3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $host1  
      $host2  
      $host3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method ajaxAllowURL [line 715]

    -
    -
    -
    - static void ajaxAllowURL( - -$url1, [ -$url2 = null], [ -$url3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $url1  
      $url2  
      $url3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method ajaxSetup [line 699]

    -
    -
    -
    - static void ajaxSetup( - -$options) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $options  
    -

    -
    [ Top ]
    -
    -
    - -

    static method browser [line 964]

    -
    -
    -
    - static void browser( - -$ajaxSettings, -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $ajaxSettings  
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method browserGet [line 948]

    -
    -
    -
    - static void browserGet( - -$url, -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $url  
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method browserPost [line 956]

    -
    -
    -
    - static void browserPost( - -$url, -$data, -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $url  
      $data  
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method callbackRun [line 868]

    -
    -
    -
    - static unknown_type callbackRun( -$callback -$callback, [$params -$params = null], [$paramStructure -$paramStructure = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    $callback  $callback  Callback
    $params  $params  
    $paramStructure  $paramStructure  
    -

    -
    [ Top ]
    -
    -
    - -

    static method createDocumentWrapper [line 381]

    -
    -
    -
    - static unknown createDocumentWrapper( -unknown_type -$html, [ -$contentType = null], [ -$documentID = null], unknown_type -$domId) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - - - - - - - -
    return:  New DOM ID
    todo:  support passing DOMDocument object from self::loadDocument
    todo:  support PHP tags in input
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    unknown_type  $html  
    unknown_type  $domId  
      $contentType  
      $documentID  
    -

    -
    [ Top ]
    -
    -
    - -

    static method debug [line 521]

    -
    -
    -
    - static void debug( - -$text) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $text  
    -

    -
    [ Top ]
    -
    -
    - -

    static method DOMNodeListToArray [line 502]

    -
    -
    -
    - static void DOMNodeListToArray( - -$DOMNodeList) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $DOMNodeList  
    -

    -
    [ Top ]
    -
    -
    - -

    static method each [line 818]

    -
    -
    -
    - static unknown_type each( -$object -$object, $callback -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Utilities/jQuery.each
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    $object  $object  
    $callback  $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method extend [line 416]

    -
    -
    -
    - static unknown_type extend( -$class -$class, [$file -$file = null]) -
    -

    - - Deprecated, use phpQuery::plugin() instead.



    -

    Tags:

    -
    - - - - - - - -
    deprecated:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $class  $class  
    $file  $file  
    -

    -
    [ Top ]
    -
    -
    - -

    static method get [line 671]

    -
    -
    -
    - static void get( - -$url, [ -$data = null], [ -$callback = null], [ -$type = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $url  
      $data  
      $callback  
      $type  
    -

    -
    [ Top ]
    -
    -
    - -

    static method getDocument [line 239]

    -
    -
    -
    - static phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup getDocument( -[unknown_type -$id = null]) -
    -

    - - Returns document with id $id or last used as phpQueryObject.

    $id can be retrived via getDocumentID() or getDocumentIDRef(). Chainable.




    -

    Tags:

    -
    - - - - - - - -
    see:  phpQuery::selectDocument()
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    unknown_type  $id  
    -

    -
    [ Top ]
    -
    -
    - -

    static method getDocumentID [line 754]

    -
    -
    -
    - static string getDocumentID( -$source -$source) -
    -

    - - Returns source's document ID.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $source  $source  DOMNode|phpQueryObject
    -

    -
    [ Top ]
    -
    -
    - -

    static method getDOMDocument [line 777]

    -
    -
    -
    - static string getDOMDocument( -$source -$source) -
    -

    - - Get DOMDocument object related to $source.

    Returns null if such document doesn't exist.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $source  $source  DOMNode|phpQueryObject|string
    -

    -
    [ Top ]
    -
    -
    - -

    static method grep [line 922]

    -
    -
    -
    - static unknown_type grep( -$array -$array, $callback -$callback, [$invert -$invert = false]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Utilities/jQuery.grep
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    $array  $array  
    $callback  $callback  
    $invert  $invert  
    -

    -
    [ Top ]
    -
    -
    - -

    static method inArray [line 808]

    -
    -
    -
    - static void inArray( - -$value, -$array) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $value  
      $array  
    -

    -
    [ Top ]
    -
    -
    - -

    static method isFunction [line 941]

    -
    -
    -
    - static unknown_type isFunction( -$function -$function) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  there are problems with non-static methods, second parameter pass it but doesnt verify is method is really callable
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $function  $function  
    -

    -
    [ Top ]
    -
    -
    - -

    static method isMarkup [line 518]

    -
    -
    -
    - static Bool isMarkup( -String -$input) -
    -

    - - Checks if $input is HTML string, which has to start with '<'.



    -

    Tags:

    -
    - - - - - - - - - - -
    deprecated:  
    todo:  still used ?
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String  $input  
    -

    -
    [ Top ]
    -
    -
    - -

    static method loadDocument [line 368]

    -
    -
    -
    - static phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPick loadDocument( -$document -$document) -
    -

    - - Reuses existing DOMDocument object.

    Chainable.




    -

    Tags:

    -
    - - - - - - - -
    return:  up
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $document  $document  DOMDocument
    -

    -
    [ Top ]
    -
    -
    - -

    static method makeArray [line 794]

    -
    -
    -
    - static unknown_type makeArray( - -$obj) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Utilities/jQuery.makeArray
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $obj  
    -

    -
    [ Top ]
    -
    -
    - -

    static method map [line 836]

    -
    -
    -
    - static void map( - -$array, -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Utilities/jQuery.map
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
      $array  
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    static method markupToPHP [line 298]

    -
    -
    -
    - static void markupToPHP( - -$content) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    static method merge [line 898]

    -
    -
    -
    - static void merge( -array -$one, array -$two) -
    -

    - - Merge 2 phpQuery objects.



    -

    Tags:

    -
    - - - - - - - -
    todo:  node lists, phpQueryObject
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    array  $one  
    array  $two  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocument [line 254]

    -
    -
    -
    - static phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup newDocument( -[unknown_type -$markup = null], [ -$contentType = null]) -
    -

    - - Creates new document from markup.

    Chainable.




    -

    Tags:

    -
    - - - - - - - -
    TODO:  support DOMDocument
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $markup  
      $contentType  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentFile [line 342]

    -
    -
    -
    - static phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup newDocumentFile( -string -$file, [ -$contentType = null]) -
    -

    - - Creates new document from file $file.

    Chainable.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    string  $file  URLs allowed. See File wrapper page at php.net for more supported sources.
      $contentType  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentFileHTML [line 348]

    -
    -
    -
    - static void newDocumentFileHTML( - -$file, [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $file  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentFilePHP [line 357]

    -
    -
    -
    - static void newDocumentFilePHP( - -$file, [ -$contentType = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $file  
      $contentType  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentFileXHTML [line 354]

    -
    -
    -
    - static void newDocumentFileXHTML( - -$file, [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $file  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentFileXML [line 351]

    -
    -
    -
    - static void newDocumentFileXML( - -$file, [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $file  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentHTML [line 260]

    -
    -
    -
    - static void newDocumentHTML( -[ -$markup = null], [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentPHP [line 271]

    -
    -
    -
    - static void newDocumentPHP( -[ -$markup = null], [ -$contentType = "text/html;charset=utf-8"]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $contentType  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentXHTML [line 268]

    -
    -
    -
    - static void newDocumentXHTML( -[ -$markup = null], [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method newDocumentXML [line 265]

    -
    -
    -
    - static void newDocumentXML( -[ -$markup = null], [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $markup  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method param [line 667]

    -
    -
    -
    - static void param( -array|phpQuery -$data) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    array|phpQuery  $data  
    -

    -
    [ Top ]
    -
    -
    - -

    static method parseJSON [line 742]

    -
    -
    -
    - static mixed parseJSON( -string -$json) -
    -

    - - Parses JSON into proper PHP type.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    string  $json  
    -

    -
    [ Top ]
    -
    -
    - -

    static method php [line 972]

    -
    -
    -
    - static void php( - -$code) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $code  
    -

    -
    [ Top ]
    -
    -
    - -

    static method phpToMarkup [line 275]

    -
    -
    -
    - static void phpToMarkup( - -$php, [ -$charset = 'utf-8']) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $php  
      $charset  
    -

    -
    [ Top ]
    -
    -
    - -

    static method plugin [line 425]

    -
    -
    -
    - static void plugin( -string -$class, [string -$file = null]) -
    -

    - - Extend phpQuery with $class from $file.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    string  $class  Extending class name. Real class name can be prepended phpQuery_.
    string  $file  Filename to include. Defaults to "{$class}.php".
    -

    -
    [ Top ]
    -
    -
    - -

    static method post [line 686]

    -
    -
    -
    - static void post( - -$url, [ -$data = null], [ -$callback = null], [ -$type = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $url  
      $data  
      $callback  
      $type  
    -

    -
    [ Top ]
    -
    -
    - -

    static method pq [line 131]

    -
    -
    -
    - static phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false pq( -string|DOMNode|DOMNodeList|array -$arg1, [string|phpQueryObject|DOMNode -$context = null]) -
    -

    - - Multi-purpose function.

    Use pq() as shortcut.

    In below examples, $pq is any result of pq(); function.

    1. Import markup into existing document (without any attaching):
    • Import into selected document: - pq('<div/>') // DOESNT accept text nodes at beginning of input string !
    • Import into document with ID from $pq->getDocumentID(): - pq('<div/>', $pq->getDocumentID())
    • Import into same document as DOMNode belongs to: - pq('<div/>', DOMNode)
    • Import into document from phpQuery object: - pq('<div/>', $pq)
    2. Run query:
    • Run query on last selected document: - pq('div.myClass')
    • Run query on document with ID from $pq->getDocumentID(): - pq('div.myClass', $pq->getDocumentID())
    • Run query on same document as DOMNode belongs to and use node(s)as root for query: - pq('div.myClass', DOMNode)
    • Run query on document from phpQuery object - and use object's stack as root node(s) for query: - pq('div.myClass', $pq)




    -

    Tags:

    -
    - - - - - - - -
    return:  phpQuery object or false in case of error.
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    string|DOMNode|DOMNodeList|array  $arg1  HTML markup, CSS Selector, DOMNode or array of DOMNodes
    string|phpQueryObject|DOMNode  $context  DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or DOMNode (determines also query root)
    -

    -
    [ Top ]
    -
    -
    - -

    static method selectDocument [line 225]

    -
    -
    -
    - static void selectDocument( -unknown_type -$id) -
    -

    - - Sets default document to $id. Document has to be loaded prior to using this method.

    $id can be retrived via getDocumentID() or getDocumentIDRef().




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    unknown_type  $id  
    -

    -
    [ Top ]
    -
    -
    - -

    static method toJSON [line 729]

    -
    -
    -
    - static string toJSON( -mixed -$data) -
    -

    - - Returns JSON representation of $data.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    mixed  $data  
    -

    -
    [ Top ]
    -
    -
    - -

    static method trim [line 944]

    -
    -
    -
    - static void trim( - -$str) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $str  
    -

    -
    [ Top ]
    -
    -
    - -

    static method unique [line 931]

    -
    -
    -
    - static void unique( - -$array) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $array  
    -

    -
    [ Top ]
    -
    -
    - -

    static method unloadDocuments [line 485]

    -
    -
    -
    - static void unloadDocuments( -[ -$id = null], mixed -$documentID) -
    -

    - - Unloades all or specified document from memory.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    mixed  $documentID  @see phpQuery::getDocumentID() for supported types.
      $id  
    -

    -
    [ Top ]
    -
    -
    - -

    static method unsafePHPTags [line 499]

    -
    -
    -
    - static string unsafePHPTags( -phpQuery|string -$content) -
    -

    - - Parses phpQuery object or HTML result against PHP tags and makes them active.



    -

    Tags:

    -
    - - - - - - - -
    deprecated:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    phpQuery|string  $content  
    -

    -
    [ Top ]
    -
    - -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:25 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/phpQueryEvents.html b/api-reference/phpQuery/phpQueryEvents.html deleted file mode 100644 index e2936c0..0000000 --- a/api-reference/phpQuery/phpQueryEvents.html +++ /dev/null @@ -1,473 +0,0 @@ - - -Docs For Class phpQueryEvents - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: phpQueryEvents

    -Source Location: /phpQueryEvents.php

    - - - - - - - - - -
    - -

    Class Overview

    -

    -
    Event handling class.


    -

    Author(s):

    -
      -
    • Tobiasz Cudnik
    • -
    - - - - - - - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 9]
    -Event handling class.



    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik
    abstract:  
    -
    -


    -
    [ Top ]

    - - -
    - -

    Class Methods

    -
    -
    - -

    static method add [line 96]

    -
    -
    -
    - static void add( -DOMNode|phpQueryObject|string -$document, -$node, unknown_type -$type, unknown_type -$data, [unknown_type -$callback = null]) -
    -

    - - Binds a handler to one or more events (like click) for each matched element.

    Can also bind custom events.




    -

    Tags:

    -
    - - - - - - - - - - - - - -
    TODO:  support binding to global events
    TODO:  support '!' (exclusive) events
    TODO:  support more than event in $type (space-separated)
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    DOMNode|phpQueryObject|string  $document  
    unknown_type  $type  
    unknown_type  $data  Optional
    unknown_type  $callback  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    static method getNode [line 136]

    -
    -
    -
    - static void getNode( - -$documentID, -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $documentID  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    static method issetGlobal [line 148]

    -
    -
    -
    - static void issetGlobal( - -$documentID, -$type) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $documentID  
      $type  
    -

    -
    [ Top ]
    -
    -
    - -

    static method remove [line 123]

    -
    -
    -
    - static void remove( -DOMNode|phpQueryObject|string -$document, -$node, [unknown_type -$type = null], [unknown_type -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - - - - -
    TODO:  support more than event in $type (space-separated)
    TODO:  namespace events
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    DOMNode|phpQueryObject|string  $document  
    unknown_type  $type  
    unknown_type  $callback  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    static method setNode [line 142]

    -
    -
    -
    - static void setNode( - -$documentID, -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $documentID  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    static method trigger [line 21]

    -
    -
    -
    - static void trigger( -DOMNode|phpQueryObject|string -$document, unknown_type -$type, [unknown_type -$data = array()], [ -$node = null]) -
    -

    - - Trigger a type of event on every matched element.



    -

    Tags:

    -
    - - - - - - - - - - - - - -
    TODO:  support more than event in $type (space-separated)
    TODO:  exclusive events (with !)
    TODO:  global events (test)
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    DOMNode|phpQueryObject|string  $document  
    unknown_type  $type  
    unknown_type  $data  
      $node  
    -

    -
    [ Top ]
    -
    - -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:26 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/phpQueryObject.html b/api-reference/phpQuery/phpQueryObject.html deleted file mode 100644 index 2c58c01..0000000 --- a/api-reference/phpQuery/phpQueryObject.html +++ /dev/null @@ -1,6172 +0,0 @@ - - -Docs For Class phpQueryObject - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: phpQueryObject

    -Source Location: /phpQueryObject.php

    - - - - - - - - - - -
    - -

    Class Overview

    -

    -
    Class representing phpQuery objects.


    -

    Author(s):

    - - - - - - - -

    - Implements interfaces: -

      -
    • Iterator (internal interface)
    • Countable (internal interface)
    • ArrayAccess (internal interface)
    -

    - -
    -

    Variables

    - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 13]
    -Class representing phpQuery objects.



    -

    Tags:

    -
    - - - - - - - - - - - - - - - - -
    method:  phpQueryObject clone(): clone()
    method:  phpQueryObject empty(): empty()
    method:  phpQueryObject next(): next($selector = null)
    method:  phpQueryObject prev(): prev($selector = null)
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    -
    -


    -
    [ Top ]

    - -
    - -

    Class Variables

    -
    - -

    -

    $charset =  null

    -

    [line 22]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $current =  null

    -

    [line 77]

    - Iterator interface helper



    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $document =  null

    -

    [line 21]

    - DOMDocument class.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  DOMDocument
    -


    -
    [ Top ]

    - -

    -

    $documentFragment =  true

    -

    [line 62]

    - Indicated if doument is just a fragment (no <html> tag).

    Every document is realy a full document, so even documentFragments can be queried against <html>, but getDocument(id)->htmlOuter() will return only contents of <body>.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  bool
    -


    -
    [ Top ]

    - -

    -

    $documentID =  null

    -

    [line 15]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $documentWrapper =  null

    -

    [line 27]

    -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  DOMDocumentWrapper
    -


    -
    [ Top ]

    - -

    -

    $elements = array()

    -

    [line 39]

    - Stack of selected elements.



    -

    Tags:

    -
    - - - - - - - -
    TODO:  refactor to ->nodes
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  array
    -


    -
    [ Top ]

    - -

    -

    $elementsBackup = array()

    -

    [line 43]

    -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $elementsInterator = array()

    -

    [line 67]

    - Iterator interface helper



    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $previous =  null

    -

    [line 47]

    -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $root = array()

    -

    [line 52]

    -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  deprecate
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $valid =  false

    -

    [line 72]

    - Iterator interface helper



    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    - -
    -
    - - - - - -
    Type:  mixed
    -


    -
    [ Top ]

    - -

    -

    $xpath =  null

    -

    [line 33]

    - XPath interface.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    - -
    -
    - - - - - -
    Type:  DOMXPath
    -


    -
    [ Top ]

    -

    - -
    - -

    Class Methods

    -
    -
    - -

    static method extend [line 2254]

    -
    -
    -
    - static unknown_type extend( -$class -$class, [$file -$file = null]) -
    -

    - - Deprecated, use $pq->plugin() instead.



    -

    Tags:

    -
    - - - - - - - -
    deprecated:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $class  $class  
    $file  $file  
    -

    -
    [ Top ]
    -
    -
    - -

    static method unQuote [line 1296]

    -
    -
    -
    - static unknown_type unQuote( -$value -$value) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  implement in all methods using passed parameters
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $value  $value  
    -

    -
    [ Top ]
    -
    - -
    - -

    constructor __construct [line 83]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery __construct( - -$documentID) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $documentID  
    -

    -
    [ Top ]
    -
    -
    - -

    method add [line 2426]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery add( -[string|phpQueryObject -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    string|phpQueryObject  $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method addClass [line 2757]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery addClass( - -$className) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $className  
    -

    -
    [ Top ]
    -
    -
    - -

    method addClassPHP [line 2775]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery addClassPHP( - -$className) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $className  
    -

    -
    [ Top ]
    -
    -
    - -

    method after [line 1984]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery after( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method afterPHP [line 1992]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery afterPHP( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method ancestors [line 1898]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery ancestors( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method andSelf [line 2746]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery andSelf( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method append [line 1907]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery append( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method appendPHP [line 1915]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery appendPHP( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method appendTo [line 1923]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery appendTo( - -$seletor) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $seletor  
    -

    -
    [ Top ]
    -
    -
    - -

    method attr [line 2574]

    -
    -
    -
    - void attr( -[ -$attr = null], [ -$value = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $attr  
      $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method attrAppend [line 2626]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery attrAppend( -string -$attr, mixed -$value) -
    -

    - - Enter description here...

    jQuery difference.




    -

    Tags:

    -
    - - - - - - - -
    todo:  use attr() function (encoding issues etc).
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    string  $attr  
    mixed  $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method attrEvents [line 2525]

    -
    -
    -
    - void attrEvents( - -$attr, -$oldAttr, -$oldValue, -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $attr  
      $oldAttr  
      $oldValue  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    method attrPHP [line 2648]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery attrPHP( - -$attr, -$value) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  check CDATA ???
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $attr  
      $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method attrPrepend [line 2609]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery attrPrepend( -string -$attr, mixed -$value) -
    -

    - - Enter description here...

    jQuery difference.




    -

    Tags:

    -
    - - - - - - - -
    todo:  use attr() function (encoding issues etc).
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    string  $attr  
    mixed  $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method before [line 1958]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery before( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method beforePHP [line 1966]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery beforePHP( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method bind [line 1410]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery bind( -unknown_type -$type, unknown_type -$data, [unknown_type -$callback = null]) -
    -

    - - Binds a handler to one or more events (like click) for each matched element.

    Can also bind custom events.




    -

    Tags:

    -
    - - - - - - - - - - -
    TODO:  support more than event in $type (space-separated)
    TODO:  support '!' (exclusive) events
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    unknown_type  $type  
    unknown_type  $data  Optional
    unknown_type  $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method change [line 1439]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery change( -[ -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method children [line 1874]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery children( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method click [line 1459]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery click( -[ -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method contents [line 1581]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery contents( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method contentsUnwrap [line 1600]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery contentsUnwrap( -) -
    -

    - - Enter description here...

    jQuery difference.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method count [line 1658]

    -
    -
    -
    - void count( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Countable::count
    -
    - -
    [ Top ]
    -
    -
    - -

    method css [line 1355]

    -
    -
    -
    - phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery css( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method current [line 2935]

    -
    -
    -
    - void current( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Iterator::current
    -
    - -
    [ Top ]
    -
    -
    - -

    method debug [line 271]

    -
    -
    -
    - void debug( - -$in) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $in  
    -

    -
    [ Top ]
    -
    -
    - -

    method documentFragment [line 128]

    -
    -
    -
    - void documentFragment( -[ -$state = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $state  
    -

    -
    [ Top ]
    -
    -
    - -

    method dump [line 3076]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery dump( -) -
    -

    - - Dump htmlOuter and preserve chain. Usefull for debugging.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method dumpDie [line 3123]

    -
    -
    -
    - void dumpDie( -) -
    -

    - - Dump htmlOuter and stop script execution. Usefull for debugging.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method dumpLength [line 3093]

    -
    -
    -
    - void dumpLength( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method dumpTree [line 3102]

    -
    -
    -
    - void dumpTree( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method dumpWhois [line 3084]

    -
    -
    -
    - void dumpWhois( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method each [line 2880]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery each( -array|string -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null], array -$scope, array -$arg1, array -$arg2) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    array|string  $callback  Expects $node as first param, $index as second
    array  $scope  External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope)
    array  $arg1  Will ba passed as third and futher args to callback.
    array  $arg2  Will ba passed as fourth and futher args to callback, and so on...
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    method elementsContainsNode [line 2448]

    -
    -
    -
    - void elementsContainsNode( - -$nodeToCheck, [ -$elementsStack = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $nodeToCheck  
      $elementsStack  
    -

    -
    [ Top ]
    -
    -
    - -

    method end [line 1668]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery end( -[ -$level = 1]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  $level
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $level  
    -

    -
    [ Top ]
    -
    -
    - -

    method eq [line 1631]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery eq( - -$num) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $num  
    -

    -
    [ Top ]
    -
    -
    - -

    method filter [line 1163]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery filter( - -$selectors, [ -$_skipHistory = false]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Traversing/filter
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $selectors  
      $_skipHistory  
    -

    -
    [ Top ]
    -
    -
    - -

    method filterCallback [line 1142]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery filterCallback( - -$callback, [ -$_skipHistory = false]) -
    -

    - - Enter description here...

    jQuery difference.




    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Traversing/filter
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $callback  
      $_skipHistory  
    -

    -
    [ Top ]
    -
    -
    - -

    method find [line 682]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery find( - -$selectors, [ -$context = null], [ -$noHistory = false]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $selectors  
      $context  
      $noHistory  
    -

    -
    [ Top ]
    -
    -
    - -

    method get [line 476]

    -
    -
    -
    - array|DOMElement get( -[int -$index = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Return matched DOM nodes.



    -

    Tags:

    -
    - - - - - - - -
    return:  Single DOMElement or array of DOMElement.
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    int  $index  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method getDocument [line 186]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery getDocument( -) -
    -

    - - Returns object with stack set to document root.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method getDocumentID [line 201]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery getDocumentID( -) -
    -

    - - Get object's Document ID.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method getDocumentIDRef [line 177]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery getDocumentIDRef( - -&$documentID, unknown_type -$domId) -
    -

    - - Saves object's DocumentID to $var by reference.

    1.  $myDocumentId;
    2. -
    3.  phpQuery::newDocument('<div/>')
    4. -
    5.      ->getDocumentIDRef($myDocumentId)
    6. -
    7.      ->find('div')->...
    8. -




    -

    Tags:

    -
    - - - - - - - - - - -
    see:  phpQuery::newDocument
    see:  phpQuery::newDocumentFile
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $domId  
      &$documentID  
    -

    -
    [ Top ]
    -
    -
    - -

    method getDOMDocument [line 193]

    -
    -
    -
    - DOMDocument getDOMDocument( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method getElementSiblings [line 2340]

    -
    -
    -
    - void getElementSiblings( - -$direction, [ -$selector = null], [ -$limitToOne = false]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $direction  
      $selector  
      $limitToOne  
    -

    -
    [ Top ]
    -
    -
    - -

    method getNodeAttrs [line 2636]

    -
    -
    -
    - void getNodeAttrs( - -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    method getNodeXpath [line 3012]

    -
    -
    -
    - string getNodeXpath( -[unknown_type -$oneNode = null], [ -$namespace = null]) -
    -

    - - Returns node's XPath.



    -

    Tags:

    -
    - - - - - - - -
    TODO:  use native getNodePath is avaible
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $oneNode  
      $namespace  
    -

    -
    [ Top ]
    -
    -
    - -

    method getString [line 502]

    -
    -
    -
    - array|string getString( -[int -$index = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Return matched DOM nodes.

    jQuery difference.




    -

    Tags:

    -
    - - - - - - - - - - - - - - - - -
    return:  Returns string if $index != null
    todo:  implement callbacks
    todo:  return only arrays ?
    todo:  maybe other name...
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    int  $index  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method getStrings [line 529]

    -
    -
    -
    - array|string getStrings( -[int -$index = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Return matched DOM nodes.

    jQuery difference.




    -

    Tags:

    -
    - - - - - - - - - - - - - - - - -
    return:  Returns string if $index != null
    todo:  implement callbacks
    todo:  return only arrays ?
    todo:  maybe other name...
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    int  $index  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method hasClass [line 2804]

    -
    -
    -
    - bool hasClass( -string -$className) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    string  $className  
    -

    -
    [ Top ]
    -
    -
    - -

    method hide [line 1371]

    -
    -
    -
    - void hide( -) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method html [line 1794]

    -
    -
    -
    - string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery html( -[unknown_type -$html = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    TODO:  force html result
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    unknown_type  $html  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method htmlOuter [line 1837]

    -
    -
    -
    - String htmlOuter( -[ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    TODO:  force html result
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method index [line 2168]

    -
    -
    -
    - Int index( - -$subject) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $subject  
    -

    -
    [ Top ]
    -
    -
    - -

    method insert [line 2012]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery insert( -unknown_type -$target, unknown_type -$type) -
    -

    - - Various insert scenarios.



    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $target  
    unknown_type  $type  
    -

    -
    [ Top ]
    -
    -
    - -

    method insertAfter [line 2000]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery insertAfter( - -$seletor) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $seletor  
    -

    -
    [ Top ]
    -
    -
    - -

    method insertBefore [line 1975]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery insertBefore( -String|phpQuery -$seletor) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $seletor  
    -

    -
    [ Top ]
    -
    -
    - -

    method is [line 1117]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery is( - -$selector, [ -$nodes = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $selector  
      $nodes  
    -

    -
    [ Top ]
    -
    -
    - -

    method isChar [line 300]

    -
    -
    -
    - bool isChar( -string -$char) -
    -

    - - Determines if $char is really a char.



    -

    Tags:

    -
    - - - - - - - -
    todo:  rewrite me to charcode range ! ;)
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    string  $char  
    -

    -
    [ Top ]
    -
    -
    - -

    method isHTML [line 214]

    -
    -
    -
    - void isHTML( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method isRegexp [line 286]

    -
    -
    -
    - void isRegexp( - -$pattern) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $pattern  
    -

    -
    [ Top ]
    -
    -
    - -

    method isRoot [line 139]

    -
    -
    -
    - void isRoot( - -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  documentWrapper
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    method isXHTML [line 217]

    -
    -
    -
    - void isXHTML( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method isXML [line 220]

    -
    -
    -
    - void isXML( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method key [line 2941]

    -
    -
    -
    - void key( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Iterator::key
    -
    - -
    [ Top ]
    -
    -
    - -

    method length [line 1655]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery length( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    deprecated:  Use length as attribute
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method load [line 1308]

    -
    -
    -
    - phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery load( - -$url, [ -$data = null], [ -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - - - - -
    link:  http://docs.jquery.com/Ajax/load
    todo:  Support $selector
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $url  
      $data  
      $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method map [line 2897]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery map( - -$callback, [ -$param1 = null], [ -$param2 = null], [ -$param3 = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  add $scope and $args as in each() ???
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $callback  
      $param1  
      $param2  
      $param3  
    -

    -
    [ Top ]
    -
    -
    - -

    method markup [line 1767]

    -
    -
    -
    - unknown_type markup( -[$markup -$markup = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - jQuey difference



    -

    Tags:

    -
    - - - - - - - -
    TODO:  trigger change event for textarea
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
    $markup  $markup  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method markupEvents [line 1749]

    -
    -
    -
    - void markupEvents( - -$newMarkup, -$oldMarkup, -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $newMarkup  
      $oldMarkup  
      $node  
    -

    -
    [ Top ]
    -
    -
    - -

    method markupOuter [line 1780]

    -
    -
    -
    - unknown_type markupOuter( -[$markup -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - jQuey difference



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    $markup  $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method matchClasses [line 582]

    -
    -
    -
    - boolean matchClasses( -unknown_type -$class, unknown_type -$node) -
    -

    - - Enter description here...

    In the future, when PHP will support XLS 2.0, then we would do that this way: contains(tokenize(@class, '\s'), "something")




    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $class  
    unknown_type  $node  
    -

    -
    [ Top ]
    -
    -
    - -

    method merge [line 2438]

    -
    -
    -
    - void merge( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method newInstance [line 555]

    -
    -
    -
    - void newInstance( -[array -$newStack = null]) -
    -

    - - Returns new instance of actual class.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    array  $newStack  Optional. Will replace old stack with new and move old one to history.c
    -

    -
    [ Top ]
    -
    -
    - -

    method next [line 2955]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery next( -[ -$cssSelector = null]) -
    -

    - - Double-function method.

    First: main iterator interface method. Second: Returning next sibling, alias for _next().

    Proper functionality is choosed automagicaly.




    -

    Tags:

    -
    - - - - - - - -
    see:  phpQueryObject::_next()
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Iterator::next
    -
    - -

    Parameters:

    -
    - - - - - - -
      $cssSelector  
    -

    -
    [ Top ]
    -
    -
    - -

    method nextAll [line 2332]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery nextAll( -[ -$selector = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  FIXME: returns source elements insted of next siblings
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method not [line 2386]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery not( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method offsetExists [line 2980]

    -
    -
    -
    - void offsetExists( - -$offset) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    ArrayAccess::offsetExists
    -
    - -

    Parameters:

    -
    - - - - - - -
      $offset  
    -

    -
    [ Top ]
    -
    -
    - -

    method offsetGet [line 2986]

    -
    -
    -
    - void offsetGet( - -$offset) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    ArrayAccess::offsetGet
    -
    - -

    Parameters:

    -
    - - - - - - -
      $offset  
    -

    -
    [ Top ]
    -
    -
    - -

    method offsetSet [line 2992]

    -
    -
    -
    - void offsetSet( - -$offset, -$value) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    ArrayAccess::offsetSet
    -
    - -

    Parameters:

    -
    - - - - - - - - - - - -
      $offset  
      $value  
    -

    -
    [ Top ]
    -
    -
    - -

    method offsetUnset [line 2999]

    -
    -
    -
    - void offsetUnset( - -$offset) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    ArrayAccess::offsetUnset
    -
    - -

    Parameters:

    -
    - - - - - - -
      $offset  
    -

    -
    [ Top ]
    -
    -
    - -

    method parent [line 2464]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery parent( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method parents [line 2481]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery parents( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method parseSelector [line 308]

    -
    -
    -
    - void parseSelector( - -$query) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $query  
    -

    -
    [ Top ]
    -
    -
    - -

    method php [line 1862]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery php( -[ -$code = null]) -
    -

    - - Just like html(), but returns markup with VALID (dangerous) PHP tags.



    -

    Tags:

    -
    - - - - - - - -
    todo:  support returning markup with PHP tags when called without param
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $code  
    -

    -
    [ Top ]
    -
    -
    - -

    method plugin [line 2242]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery plugin( - -$class, [ -$file = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $class  
      $file  
    -

    -
    [ Top ]
    -
    -
    - -

    method prepend [line 1932]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery prepend( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method prependPHP [line 1941]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery prependPHP( - -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  accept many arguments, which are joined, arrays maybe also
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method prependTo [line 1949]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery prependTo( - -$seletor) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $seletor  
    -

    -
    [ Top ]
    -
    -
    - -

    method prev [line 2312]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery prev( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method prevAll [line 2322]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery prevAll( -[ -$selector = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method pseudoClasses [line 843]

    -
    -
    -
    - void pseudoClasses( - -$class) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  create API for classes with pseudoselectors
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $class  
    -

    -
    [ Top ]
    -
    -
    - -

    method remove [line 1736]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery remove( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method removeAttr [line 2679]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery removeAttr( - -$attr) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $attr  
    -

    -
    [ Top ]
    -
    -
    - -

    method removeClass [line 2817]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery removeClass( - -$className) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $className  
    -

    -
    [ Top ]
    -
    -
    - -

    method replaceAll [line 1723]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery replaceAll( -String -$selector) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    todo:  this works ?
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String  $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method replaceWith [line 1712]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery replaceWith( -String|phpQuery -$content) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Manipulation/replaceWith#content
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $content  
    -

    -
    [ Top ]
    -
    -
    - -

    method replaceWithPHP [line 1701]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery replaceWithPHP( - -$code) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $code  
    -

    -
    [ Top ]
    -
    -
    - -

    method reverse [line 2210]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery reverse( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method rewind [line 2920]

    -
    -
    -
    - void rewind( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Iterator::rewind
    -
    - -
    [ Top ]
    -
    -
    - -

    method runQuery [line 612]

    -
    -
    -
    - void runQuery( - -$XQuery, [ -$selector = null], [ -$compare = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $XQuery  
      $selector  
      $compare  
    -

    -
    [ Top ]
    -
    -
    - -

    method serialize [line 229]

    -
    -
    -
    - string serialize( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Ajax/serialize
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method serializeArray [line 239]

    -
    -
    -
    - array serializeArray( -[ -$submit = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - -
    link:  http://docs.jquery.com/Ajax/serializeArray
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $submit  
    -

    -
    [ Top ]
    -
    -
    - -

    method show [line 1363]

    -
    -
    -
    - void show( -) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    todo:  
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method siblings [line 2368]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery siblings( -[ -$selector = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method size [line 1645]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery size( -) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method slice [line 2189]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery slice( -unknown_type -$start, [unknown_type -$end = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $start  
    unknown_type  $end  
    -

    -
    [ Top ]
    -
    -
    - -

    method stack [line 2513]

    -
    -
    -
    - string|array|phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery stack( -[ -$nodeTypes = null], unknown_type -$attr, unknown_type -$value) -
    -

    - - Attribute method.

    Accepts * for all attributes (for setting and getting)




    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
    unknown_type  $attr  
    unknown_type  $value  
      $nodeTypes  
    -

    -
    [ Top ]
    -
    -
    - -

    method stackIsRoot [line 148]

    -
    -
    -
    - void stackIsRoot( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method submit [line 1449]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery submit( -[ -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method switchWith [line 1615]

    -
    -
    -
    - void switchWith( - -$markup) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $markup  
    -

    -
    [ Top ]
    -
    -
    - -

    method text [line 2220]

    -
    -
    -
    - String text( -[ -$text = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - - Return joined text content.



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $text  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method toggleClass [line 2836]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery toggleClass( - -$className) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $className  
    -

    -
    [ Top ]
    -
    -
    - -

    method toReference [line 125]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery toReference( - -&$var, phpQueryObject -$var) -
    -

    - - Saves actual object to $var by reference.

    Useful when need to break chain.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    phpQueryObject  $var  
      &$var  
    -

    -
    [ Top ]
    -
    -
    - -

    method toRoot [line 158]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery toRoot( -) -
    -

    - - Enter description here...

    NON JQUERY METHOD

    TODO SUPPORT FOR end() !!! Causing problems in queryTemplates...




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method trigger [line 1383]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery trigger( -unknown_type -$type, [unknown_type -$data = array()]) -
    -

    - - Trigger a type of event on every matched element.



    -

    Tags:

    -
    - - - - - - - -
    TODO:  support more than event in $type (space-separated)
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $type  
    unknown_type  $data  
    -

    -
    [ Top ]
    -
    -
    - -

    method triggerHandler [line 1396]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery triggerHandler( -unknown_type -$type, [unknown_type -$data = array()]) -
    -

    - - This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.



    -

    Tags:

    -
    - - - - - - - -
    TODO:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $type  
    unknown_type  $data  
    -

    -
    [ Top ]
    -
    -
    - -

    method unbind [line 1429]

    -
    -
    -
    - unknown unbind( -[unknown_type -$type = null], [unknown_type -$callback = null]) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - - - - - - - -
    TODO:  support more than event in $type (space-separated)
    TODO:  namespace events
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    unknown_type  $type  
    unknown_type  $callback  
    -

    -
    [ Top ]
    -
    -
    - -

    method unloadDocument [line 211]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery unloadDocument( -) -
    -

    - - Unloads whole document from memory.

    CAUTION! None further operations will be possible on this document. All objects refering to it will be useless.




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method val [line 2698]

    -
    -
    -
    - String val( -[ -$val = null]) -
    -

    - - Return form element value.



    -

    Tags:

    -
    - - - - - - - -
    return:  Fields value.
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $val  
    -

    -
    [ Top ]
    -
    -
    - -

    method valid [line 2972]

    -
    -
    -
    - void valid( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - -
    -
    Implementation of:
    -
    -
    Iterator::valid
    -
    - -
    [ Top ]
    -
    -
    - -

    method whois [line 3047]

    -
    -
    -
    - void whois( -[ -$oneNode = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $oneNode  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrap [line 1534]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrap( -String|phpQuery -$wrapper) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $wrapper  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapAll [line 1489]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapAll( -String|phpQuery -$wrapper) -
    -

    - - Enter description here...

    TODO testme...




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $wrapper  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapAllOld [line 1470]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapAllOld( -String|phpQuery -$wrapper) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $wrapper  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapAllPHP [line 1518]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapAllPHP( -String|phpQuery -$codeBefore, -$codeAfter) -
    -

    - - Enter description here...

    NON JQUERY METHOD




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    String|phpQuery  $codeBefore  
      $codeAfter  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapInner [line 1558]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapInner( -String|phpQuery -$wrapper) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $wrapper  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapInnerPHP [line 1570]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapInnerPHP( -String|phpQuery -$wrapper) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    String|phpQuery  $wrapper  
    -

    -
    [ Top ]
    -
    -
    - -

    method wrapPHP [line 1546]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery wrapPHP( -String|phpQuery -$codeBefore, -$codeAfter) -
    -

    - - Enter description here...



    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    String|phpQuery  $codeBefore  
      $codeAfter  
    -

    -
    [ Top ]
    -
    -
    - -

    method xml [line 1827]

    -
    -
    -
    - void xml( -[ -$xml = null], [ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  force xml result
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - - - - - - -
      $xml  
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method xmlOuter [line 1849]

    -
    -
    -
    - void xmlOuter( -[ -$callback1 = null], [ -$callback2 = null], [ -$callback3 = null]) -
    -

    - -

    -

    Tags:

    -
    - - - - - - - -
    TODO:  force xml result
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - - - - - - -
      $callback1  
      $callback2  
      $callback3  
    -

    -
    [ Top ]
    -
    -
    - -

    method _clone [line 1684]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery _clone( -) -
    -

    - - Enter description here...

    Normal use ->clone() .




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method _empty [line 2863]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery _empty( -) -
    -

    - - Proper name without underscore (just ->empty()) also works.

    Removes all child nodes from the set of matched elements.

    Example: pq("p")._empty()

    HTML: <p>Hello, <span>Person</span> <a href="#">and person</a></p>

    Result: [ <p></p> ]




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method _next [line 2292]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery _next( -[ -$selector = null]) -
    -

    - - Safe rename of next().

    Use it ONLY when need to call next() on an iterated object (in same time). Normaly there is no need to do such thing ;)




    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method _prev [line 2304]

    -
    -
    -
    - phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery _prev( -[ -$selector = null]) -
    -

    - - Use prev() and next().



    -

    Tags:

    -
    - - - - - - - -
    deprecated:  
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $selector  
    -

    -
    [ Top ]
    -
    -
    - -

    method __call [line 2264]

    -
    -
    -
    - unknown_type __call( -$method -$method, $args -$args) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
    $method  $method  
    $args  $args  
    -

    -
    [ Top ]
    -
    -
    - -

    method __get [line 109]

    -
    -
    -
    - unknown_type __get( -$attr -$attr) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $attr  $attr  
    -

    -
    [ Top ]
    -
    -
    - -

    method __loadSuccess [line 1339]

    -
    -
    -
    - unknown_type __loadSuccess( -$html -$html) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $html  $html  
    -

    -
    [ Top ]
    -
    -
    - -

    method __pseudoClassParam [line 1109]

    -
    -
    -
    - void __pseudoClassParam( - -$paramsString) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  protected
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
      $paramsString  
    -

    -
    [ Top ]
    -
    -
    - -

    method __toString [line 1853]

    -
    -
    -
    - void __toString( -) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -
    [ Top ]
    -
    -
    - -

    method ___wrapAllCallback [line 1504]

    -
    -
    -
    - unknown_type ___wrapAllCallback( -$node -$node) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - -
    $node  $node  
    -

    -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:26 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/phpQuery/phpQueryPlugins.html b/api-reference/phpQuery/phpQueryPlugins.html deleted file mode 100644 index 1dfc1c1..0000000 --- a/api-reference/phpQuery/phpQueryPlugins.html +++ /dev/null @@ -1,192 +0,0 @@ - - -Docs For Class phpQueryPlugins - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Class: phpQueryPlugins

    -Source Location: /phpQuery.php

    - - - - - - - - - -
    - -

    Class Overview

    -

    -
    Plugins static namespace class.


    -

    Author(s):

    - - - - - - - - -
    -

    Methods

    - -
    -
    - - - - - - - - -
    -
    - - -

    Class Details

    -
    -[line 983]
    -Plugins static namespace class.



    -

    Tags:

    -
    - - - - - - - -
    author:  Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
    todo:  move plugin methods here (as statics)
    -
    -


    -
    [ Top ]

    - - -
    - -

    Class Methods

    -
    - -
    - -

    method __call [line 984]

    -
    -
    -
    - void __call( - -$method, -$args) -
    -

    - -

    -

    Tags:

    -
    - - - - -
    access:  public
    -
    -

    - - -

    Parameters:

    -
    - - - - - - - - - - - -
      $method  
      $args  
    -

    -
    [ Top ]
    -
    -

    - - -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:26 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file diff --git a/api-reference/todolist.html b/api-reference/todolist.html deleted file mode 100644 index 13e5363..0000000 --- a/api-reference/todolist.html +++ /dev/null @@ -1,161 +0,0 @@ - - -Todo List - - - - - - - - - - - - - -
    phpQuery
    - - - [ class tree: phpQuery ] - [ index: phpQuery ] - [ all elements ] -
    - - - - - - -
    -
    - -

    Todo List

    -

    phpQuery

    -

    DOMDocumentWrapper::$contentType

    -
      -
    • Rewrite as method and quess if null.
    • -
    -

    phpQueryObject::attrAppend()

    -
      -
    • use attr() function (encoding issues etc).
    • -
    -

    phpQueryObject::attrPHP()

    -
      -
    • check CDATA ???
    • -
    -

    phpQueryObject::attrPrepend()

    -
      -
    • use attr() function (encoding issues etc).
    • -
    -

    phpQuery::createDocumentWrapper()

    -
      -
    • support passing DOMDocument object from self::loadDocument
    • -
    • support PHP tags in input
    • -
    -

    phpQueryObject::css()

    -
      -
    • -
    -

    DOMDocumentWrapper

    -
      -
    • check XML catalogs compatibility
    • -
    -

    DOMEvent

    -
      -
    • implement ArrayAccess ?
    • -
    -

    phpQueryObject::end()

    -
      -
    • $level
    • -
    -

    phpQueryObject::getString()

    -
      -
    • implement callbacks
    • -
    • maybe other name...
    • -
    • return only arrays ?
    • -
    -

    phpQueryObject::getStrings()

    -
      -
    • implement callbacks
    • -
    • maybe other name...
    • -
    • return only arrays ?
    • -
    -

    phpQueryObject::hide()

    -
      -
    • -
    -

    phpQueryObject::isChar()

    -
      -
    • rewrite me to charcode range ! ;)
    • -
    -

    phpQuery::isMarkup()

    -
      -
    • still used ?
    • -
    -

    phpQueryObject::load()

    -
      -
    • Support $selector
    • -
    -

    phpQueryObject::map()

    -
      -
    • add $scope and $args as in each() ???
    • -
    -

    phpQuery::merge()

    -
      -
    • node lists, phpQueryObject
    • -
    -

    phpQueryObject::nextAll()

    -
      -
    • FIXME: returns source elements insted of next siblings
    • -
    -

    phpQueryObject::php()

    -
      -
    • support returning markup with PHP tags when called without param
    • -
    -

    phpQueryPlugins

    -
      -
    • move plugin methods here (as statics)
    • -
    -

    phpQueryObject::prependPHP()

    -
      -
    • accept many arguments, which are joined, arrays maybe also
    • -
    -

    phpQueryObject::prevAll()

    -
      -
    • -
    -

    phpQueryObject::pseudoClasses()

    -
      -
    • create API for classes with pseudoselectors
    • -
    -

    phpQueryObject::replaceAll()

    -
      -
    • this works ?
    • -
    -

    phpQueryObject::show()

    -
      -
    • -
    -

    CallbackReference::__construct()

    -
      -
    • implement $paramIndex; param index choose which callback param will be passed to reference
    • -
    -
    -
    - Documentation generated on Tue, 18 Nov 2008 19:39:30 +0100 by phpDocumentor 1.4.2 -
    -
    -
    - - - \ No newline at end of file From 92357ee8543cb4ff32d89d3a4a37c25b92851b8a Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 14:59:21 -0600 Subject: [PATCH 29/59] Added extra example. --- cli/phpquery | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/phpquery b/cli/phpquery index 10dccf5..a652b51 100755 --- a/cli/phpquery +++ b/cli/phpquery @@ -5,6 +5,7 @@ if (!isset($argv[1]) || $argv[1] == 'help' || $argv[1] == '--help' || $argv[1] = phpquery URL --method1 arg1 arg2 argN --method2 arg1 arg2 argN ... Example: phpquery 'http://localhost' --find 'div > p' --contents + phpquery 'http://example.com/' --find 'a' --attrs 'href' Pipe: cat index.html | phpquery --find 'div > p' --contents Docs: @@ -65,4 +66,4 @@ function phpQueryCli($markup, $callQueue) { print $pq."\n"; //var_dump($pq); } -?> \ No newline at end of file +?> From a6744a34e67824a2a5ff14e9dab0be6227364c4f Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 15:06:24 -0600 Subject: [PATCH 30/59] Added travis-ci configuration. --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..a1629ba --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: php +php: + - 5.5 + - 5.4 + - 5.3 +before_install: + - wget http://getcomposer.org/composer.phar; chmod +x composer.phar; ./composer.phar install From c24871a0cb0faf720095bc68363d373ee45246cf Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 15:11:48 -0600 Subject: [PATCH 31/59] Updated README to explain the goal of this fork. --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 6287d32..f17f0b8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ +# Revisiting PhpQuery + +[![Build Status](https://travis-ci.org/wittiws/phonarc.png?branch=master)](https://travis-ci.org/wittiws/phonarc) + +I am using this fork to modernize phpQuery. I am going to adjust folder structures, add namespaces and expand the unit tests. Prior to making those sweeping changes, the code came from a combination of: + +1. https://github.com/electrolinux/phpquery +2. https://github.com/kevee/phpquery/tree/phpquery-css + +# Original README from electrolinux + ## phpQuery, one more fork! My intent is to have it easily integrated in differents projects, so available on packagist. From 736c51ac6f79dc82356a467789939e034395e443 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 15:13:42 -0600 Subject: [PATCH 32/59] Removed the snapshot of the old CSSParser - it is not in use. #3 --- phpQuery/CSSParser/CSSParser.php | 465 ------------- phpQuery/CSSParser/README.md | 376 ---------- phpQuery/CSSParser/lib/CSSList.php | 236 ------- phpQuery/CSSParser/lib/CSSProperties.php | 124 ---- phpQuery/CSSParser/lib/CSSRule.php | 135 ---- phpQuery/CSSParser/lib/CSSRuleSet.php | 653 ------------------ phpQuery/CSSParser/lib/CSSValue.php | 110 --- phpQuery/CSSParser/lib/CSSValueList.php | 92 --- .../tests/CSSDeclarationBlockTest.php | 223 ------ phpQuery/CSSParser/tests/CSSParserTests.php | 277 -------- phpQuery/CSSParser/tests/files/-tobedone.css | 7 - phpQuery/CSSParser/tests/files/atrules.css | 10 - phpQuery/CSSParser/tests/files/colortest.css | 10 - .../tests/files/create-shorthands.css | 7 - .../tests/files/expand-shorthands.css | 7 - phpQuery/CSSParser/tests/files/functions.css | 22 - phpQuery/CSSParser/tests/files/ie.css | 6 - phpQuery/CSSParser/tests/files/important.css | 8 - phpQuery/CSSParser/tests/files/nested.css | 17 - phpQuery/CSSParser/tests/files/slashed.css | 4 - .../CSSParser/tests/files/specificity.css | 7 - phpQuery/CSSParser/tests/files/unicode.css | 12 - phpQuery/CSSParser/tests/files/values.css | 11 - phpQuery/CSSParser/tests/files/whitespace.css | 3 - phpQuery/CSSParser/tests/quickdump.php | 15 - phpQuery/phpQuery.php | 1 - 26 files changed, 2838 deletions(-) delete mode 100755 phpQuery/CSSParser/CSSParser.php delete mode 100755 phpQuery/CSSParser/README.md delete mode 100755 phpQuery/CSSParser/lib/CSSList.php delete mode 100755 phpQuery/CSSParser/lib/CSSProperties.php delete mode 100755 phpQuery/CSSParser/lib/CSSRule.php delete mode 100755 phpQuery/CSSParser/lib/CSSRuleSet.php delete mode 100755 phpQuery/CSSParser/lib/CSSValue.php delete mode 100755 phpQuery/CSSParser/lib/CSSValueList.php delete mode 100755 phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php delete mode 100755 phpQuery/CSSParser/tests/CSSParserTests.php delete mode 100755 phpQuery/CSSParser/tests/files/-tobedone.css delete mode 100755 phpQuery/CSSParser/tests/files/atrules.css delete mode 100755 phpQuery/CSSParser/tests/files/colortest.css delete mode 100755 phpQuery/CSSParser/tests/files/create-shorthands.css delete mode 100755 phpQuery/CSSParser/tests/files/expand-shorthands.css delete mode 100755 phpQuery/CSSParser/tests/files/functions.css delete mode 100755 phpQuery/CSSParser/tests/files/ie.css delete mode 100755 phpQuery/CSSParser/tests/files/important.css delete mode 100755 phpQuery/CSSParser/tests/files/nested.css delete mode 100755 phpQuery/CSSParser/tests/files/slashed.css delete mode 100755 phpQuery/CSSParser/tests/files/specificity.css delete mode 100755 phpQuery/CSSParser/tests/files/unicode.css delete mode 100755 phpQuery/CSSParser/tests/files/values.css delete mode 100755 phpQuery/CSSParser/tests/files/whitespace.css delete mode 100755 phpQuery/CSSParser/tests/quickdump.php diff --git a/phpQuery/CSSParser/CSSParser.php b/phpQuery/CSSParser/CSSParser.php deleted file mode 100755 index 5477927..0000000 --- a/phpQuery/CSSParser/CSSParser.php +++ /dev/null @@ -1,465 +0,0 @@ -sText = $sText; - $this->iCurrentPosition = 0; - $this->setCharset($sDefaultCharset); - } - - public function setCharset($sCharset) { - $this->sCharset = $sCharset; - $this->iLength = mb_strlen($this->sText, $this->sCharset); - } - - public function getCharset() { - return $this->sCharset; - } - - public function parse() { - $oResult = new CSSDocument(); - $this->parseDocument($oResult); - return $oResult; - } - - private function parseDocument(CSSDocument $oDocument) { - $this->consumeWhiteSpace(); - $this->parseList($oDocument, true); - } - - private function parseList(CSSList $oList, $bIsRoot = false) { - while(!$this->isEnd()) { - if($this->comes('@')) { - $oList->append($this->parseAtRule()); - } else if($this->comes('}')) { - $this->consume('}'); - if($bIsRoot) { - throw new Exception("Unopened {"); - } else { - return; - } - } else { - $oList->append($this->parseSelector()); - } - $this->consumeWhiteSpace(); - } - if(!$bIsRoot) { - throw new Exception("Unexpected end of document"); - } - } - - private function parseAtRule() { - $this->consume('@'); - $sIdentifier = $this->parseIdentifier(); - $this->consumeWhiteSpace(); - if($sIdentifier === 'media') { - $oResult = new CSSMediaQuery(); - $oResult->setQuery(trim($this->consumeUntil('{'))); - $this->consume('{'); - $this->consumeWhiteSpace(); - $this->parseList($oResult); - return $oResult; - } else if($sIdentifier === 'import') { - $oLocation = $this->parseURLValue(); - $this->consumeWhiteSpace(); - $sMediaQuery = null; - if(!$this->comes(';')) { - $sMediaQuery = $this->consumeUntil(';'); - } - $this->consume(';'); - return new CSSImport($oLocation, $sMediaQuery); - } else if($sIdentifier === 'charset') { - $sCharset = $this->parseStringValue(); - $this->consumeWhiteSpace(); - $this->consume(';'); - $this->setCharset($sCharset->getString()); - return new CSSCharset($sCharset); - } else { - //Unknown other at rule (font-face or such) - $this->consume('{'); - $this->consumeWhiteSpace(); - $oAtRule = new CSSAtRule($sIdentifier); - $this->parseRuleSet($oAtRule); - return $oAtRule; - } - } - - private function parseIdentifier($bAllowFunctions = true) { - $sResult = $this->parseCharacter(true); - if($sResult === null) { - throw new Exception("Identifier expected, got {$this->peek(5)}"); - } - $sCharacter; - while(($sCharacter = $this->parseCharacter(true)) !== null) { - $sResult .= $sCharacter; - } - if($bAllowFunctions && $this->comes('(')) { - $this->consume('('); - $sResult = new CSSFunction($sResult, $this->parseValue(array('=', ','))); - $this->consume(')'); - } - return $sResult; - } - - private function parseStringValue() { - $sBegin = $this->peek(); - $sQuote = null; - if($sBegin === "'") { - $sQuote = "'"; - } else if($sBegin === '"') { - $sQuote = '"'; - } - if($sQuote !== null) { - $this->consume($sQuote); - } - $sResult = ""; - $sContent = null; - if($sQuote === null) { - //Unquoted strings end in whitespace or with braces, brackets, parentheses - while(!preg_match('/[\\s{}()<>\\[\\]]/isu', $this->peek())) { - $sResult .= $this->parseCharacter(false); - } - } else { - while(!$this->comes($sQuote)) { - $sContent = $this->parseCharacter(false); - if($sContent === null) { - throw new Exception("Non-well-formed quoted string {$this->peek(3)}"); - } - $sResult .= $sContent; - } - $this->consume($sQuote); - } - return new CSSString($sResult); - } - - private function parseCharacter($bIsForIdentifier) { - if($this->peek() === '\\') { - $this->consume('\\'); - if($this->comes('\n') || $this->comes('\r')) { - return ''; - } - $aMatches; - if(preg_match('/[0-9a-fA-F]/Su', $this->peek()) === 0) { - return $this->consume(1); - } - $sUnicode = $this->consumeExpression('/^[0-9a-fA-F]{1,6}/u'); - if(mb_strlen($sUnicode, $this->sCharset) < 6) { - //Consume whitespace after incomplete unicode escape - if(preg_match('/\\s/isSu', $this->peek())) { - if($this->comes('\r\n')) { - $this->consume(2); - } else { - $this->consume(1); - } - } - } - $iUnicode = intval($sUnicode, 16); - $sUtf32 = ""; - for($i=0;$i<4;$i++) { - $sUtf32 .= chr($iUnicode & 0xff); - $iUnicode = $iUnicode >> 8; - } - return iconv('utf-32le', $this->sCharset, $sUtf32); - } - if($bIsForIdentifier) { - if(preg_match('/[a-zA-Z0-9]|-|_/u', $this->peek()) === 1) { - return $this->consume(1); - } else if(ord($this->peek()) > 0xa1) { - return $this->consume(1); - } else { - return null; - } - } else { - return $this->consume(1); - } - // Does not reach here - return null; - } - - private function parseSelector() { - $oResult = new CSSDeclarationBlock(); - $oResult->setSelector($this->consumeUntil('{')); - $this->consume('{'); - $this->consumeWhiteSpace(); - $this->parseRuleSet($oResult); - return $oResult; - } - - private function parseRuleSet($oRuleSet) { - while(!$this->comes('}')) { - $oRuleSet->addRule($this->parseRule()); - $this->consumeWhiteSpace(); - } - $this->consume('}'); - } - - private function parseRule() { - $oRule = new CSSRule($this->parseIdentifier()); - $this->consumeWhiteSpace(); - $this->consume(':'); - $oValue = $this->parseValue(self::listDelimiterForRule($oRule->getRule())); - $oRule->setValue($oValue); - if($this->comes('!')) { - $this->consume('!'); - $this->consumeWhiteSpace(); - $sImportantMarker = $this->consume(strlen('important')); - if(mb_convert_case($sImportantMarker, MB_CASE_LOWER) !== 'important') { - throw new Exception("! was followed by “".$sImportantMarker."”. Expected “important”"); - } - $oRule->setIsImportant(true); - } - if($this->comes(';')) { - $this->consume(';'); - } - return $oRule; - } - - private function parseValue($aListDelimiters) { - $aStack = array(); - $this->consumeWhiteSpace(); - while(!($this->comes('}') || $this->comes(';') || $this->comes('!') || $this->comes(')'))) { - if(count($aStack) > 0) { - $bFoundDelimiter = false; - foreach($aListDelimiters as $sDelimiter) { - if($this->comes($sDelimiter)) { - array_push($aStack, $this->consume($sDelimiter)); - $this->consumeWhiteSpace(); - $bFoundDelimiter = true; - break; - } - } - if(!$bFoundDelimiter) { - //Whitespace was the list delimiter - array_push($aStack, ' '); - } - } - array_push($aStack, $this->parsePrimitiveValue()); - $this->consumeWhiteSpace(); - } - foreach($aListDelimiters as $sDelimiter) { - if(count($aStack) === 1) { - return $aStack[0]; - } - $iStartPosition = null; - while(($iStartPosition = array_search($sDelimiter, $aStack, true)) !== false) { - $iLength = 2; //Number of elements to be joined - for($i=$iStartPosition+2;$iaddListComponent($aStack[$i]); - } - array_splice($aStack, $iStartPosition-1, $iLength*2-1, array($oList)); - } - } - return $aStack[0]; - } - - private static function listDelimiterForRule($sRule) { - if(preg_match('/^font($|-)/', $sRule)) { - return array(',', '/', ' '); - } - return array(',', ' ', '/'); - } - - private function parsePrimitiveValue() { - $oValue = null; - $this->consumeWhiteSpace(); - if(is_numeric($this->peek()) || (($this->comes('-') || $this->comes('.')) && is_numeric($this->peek(1, 1)))) { - $oValue = $this->parseNumericValue(); - } else if($this->comes('#') || $this->comes('rgb') || $this->comes('hsl')) { - $oValue = $this->parseColorValue(); - } else if($this->comes('url')){ - $oValue = $this->parseURLValue(); - } else if($this->comes("'") || $this->comes('"')){ - $oValue = $this->parseStringValue(); - } else { - $oValue = $this->parseIdentifier(); - } - $this->consumeWhiteSpace(); - return $oValue; - } - - private function parseNumericValue($bForColor = false) { - $sSize = ''; - if($this->comes('-')) { - $sSize .= $this->consume('-'); - } - while(is_numeric($this->peek()) || $this->comes('.')) { - if($this->comes('.')) { - $sSize .= $this->consume('.'); - } else { - $sSize .= $this->consume(1); - } - } - $fSize = floatval($sSize); - $sUnit = null; - if($this->comes('%')) { - $sUnit = $this->consume('%'); - } else if($this->comes('em')) { - $sUnit = $this->consume('em'); - } else if($this->comes('ex')) { - $sUnit = $this->consume('ex'); - } else if($this->comes('px')) { - $sUnit = $this->consume('px'); - } else if($this->comes('deg')) { - $sUnit = $this->consume('deg'); - } else if($this->comes('s')) { - $sUnit = $this->consume('s'); - } else if($this->comes('cm')) { - $sUnit = $this->consume('cm'); - } else if($this->comes('pt')) { - $sUnit = $this->consume('pt'); - } else if($this->comes('in')) { - $sUnit = $this->consume('in'); - } else if($this->comes('pc')) { - $sUnit = $this->consume('pc'); - } else if($this->comes('cm')) { - $sUnit = $this->consume('cm'); - } else if($this->comes('mm')) { - $sUnit = $this->consume('mm'); - } - return new CSSSize($fSize, $sUnit, $bForColor); - } - - private function parseColorValue() { - $aColor = array(); - if($this->comes('#')) { - $this->consume('#'); - $sValue = $this->parseIdentifier(false); - if(mb_strlen($sValue, $this->sCharset) === 3) { - $sValue = $sValue[0].$sValue[0].$sValue[1].$sValue[1].$sValue[2].$sValue[2]; - } - $aColor = array('r' => new CSSSize(intval($sValue[0].$sValue[1], 16), null, true), 'g' => new CSSSize(intval($sValue[2].$sValue[3], 16), null, true), 'b' => new CSSSize(intval($sValue[4].$sValue[5], 16), null, true)); - } else { - $sColorMode = $this->parseIdentifier(false); - $this->consumeWhiteSpace(); - $this->consume('('); - $iLength = mb_strlen($sColorMode, $this->sCharset); - for($i=0;$i<$iLength;$i++) { - $this->consumeWhiteSpace(); - $aColor[$sColorMode[$i]] = $this->parseNumericValue(true); - $this->consumeWhiteSpace(); - if($i < ($iLength-1)) { - $this->consume(','); - } - } - $this->consume(')'); - } - return new CSSColor($aColor); - } - - private function parseURLValue() { - $bUseUrl = $this->comes('url'); - if($bUseUrl) { - $this->consume('url'); - $this->consumeWhiteSpace(); - $this->consume('('); - } - $this->consumeWhiteSpace(); - $oResult = new CSSURL($this->parseStringValue()); - if($bUseUrl) { - $this->consumeWhiteSpace(); - $this->consume(')'); - } - return $oResult; - } - - private function comes($sString, $iOffset = 0) { - if($this->isEnd()) { - return false; - } - return $this->peek($sString, $iOffset) == $sString; - } - - private function peek($iLength = 1, $iOffset = 0) { - if($this->isEnd()) { - return ''; - } - if(is_string($iLength)) { - $iLength = mb_strlen($iLength, $this->sCharset); - } - if(is_string($iOffset)) { - $iOffset = mb_strlen($iOffset, $this->sCharset); - } - return mb_substr($this->sText, $this->iCurrentPosition+$iOffset, $iLength, $this->sCharset); - } - - private function consume($mValue = 1) { - if(is_string($mValue)) { - $iLength = mb_strlen($mValue, $this->sCharset); - if(mb_substr($this->sText, $this->iCurrentPosition, $iLength, $this->sCharset) !== $mValue) { - throw new Exception("Expected $mValue, got ".$this->peek(5)); - } - $this->iCurrentPosition += mb_strlen($mValue, $this->sCharset); - return $mValue; - } else { - if($this->iCurrentPosition+$mValue > $this->iLength) { - throw new Exception("Tried to consume $mValue chars, exceeded file end"); - } - $sResult = mb_substr($this->sText, $this->iCurrentPosition, $mValue, $this->sCharset); - $this->iCurrentPosition += $mValue; - return $sResult; - } - } - - private function consumeExpression($mExpression) { - $aMatches; - if(preg_match($mExpression, $this->inputLeft(), $aMatches, PREG_OFFSET_CAPTURE) === 1) { - return $this->consume($aMatches[0][0]); - } - throw new Exception("Expected pattern $mExpression not found, got: {$this->peek(5)}"); - } - - private function consumeWhiteSpace() { - do { - while(preg_match('/\\s/isSu', $this->peek()) === 1) { - $this->consume(1); - } - } while($this->consumeComment()); - } - - private function consumeComment() { - if($this->comes('/*')) { - $this->consumeUntil('*/'); - $this->consume('*/'); - return true; - } - return false; - } - - private function isEnd() { - return $this->iCurrentPosition >= $this->iLength; - } - - private function consumeUntil($sEnd) { - $iEndPos = mb_strpos($this->sText, $sEnd, $this->iCurrentPosition, $this->sCharset); - if($iEndPos === false) { - throw new Exception("Required $sEnd not found, got {$this->peek(5)}"); - } - return $this->consume($iEndPos-$this->iCurrentPosition); - } - - private function inputLeft() { - return mb_substr($this->sText, $this->iCurrentPosition, -1, $this->sCharset); - } -} - diff --git a/phpQuery/CSSParser/README.md b/phpQuery/CSSParser/README.md deleted file mode 100755 index 594574f..0000000 --- a/phpQuery/CSSParser/README.md +++ /dev/null @@ -1,376 +0,0 @@ -PHP CSS Parser --------------- - -A Parser for CSS Files written in PHP. Allows extraction of CSS files into a data structure, manipulation of said structure and output as (optimized) CSS. - -## Usage - -### Installation - -Include the `CSSParser.php` file somewhere in your code using `require_once` (or `include_once`, if you prefer), the given `lib` folder needs to exist next to the file. - -### Extraction - -To use the CSS Parser, create a new instance. The constructor takes the following form: - - new CSSParser($sCssContents, $sCharset = 'utf-8'); - -The charset is used only if no @charset declaration is found in the CSS file. - -To read a file, for example, you’d do the following: - - $oCssParser = new CSSParser(file_get_contents('somefile.css')); - $oCssDocument = $oCssParser->parse(); - -The resulting CSS document structure can be manipulated prior to being output. - -### Manipulation - -The resulting data structure consists mainly of five basic types: `CSSList`, `CSSRuleSet`, `CSSRule`, `CSSSelector` and `CSSValue`. There are two additional types used: `CSSImport` and `CSSCharset` which you won’t use often. - -#### CSSList - -`CSSList` represents a generic CSS container, most likely containing declaration blocks (rule sets with a selector) but it may also contain at-rules, charset declarations, etc. `CSSList` has the following concrete subtypes: - -* `CSSDocument` – representing the root of a CSS file. -* `CSSMediaQuery` – represents a subsection of a CSSList that only applies to a output device matching the contained media query. - -#### CSSRuleSet - -`CSSRuleSet` is a container for individual rules. The most common form of a rule set is one constrained by a selector. The following concrete subtypes exist: - -* `CSSAtRule` – for generic at-rules which do not match the ones specifically mentioned like @import, @charset or @media. A common example for this is @font-face. -* `CSSDeclarationBlock` – a RuleSet constrained by a `CSSSelector; contains an array of selector objects (comma-separated in the CSS) as well as the rules to be applied to the matching elements. - -Note: A `CSSList` can contain other `CSSList`s (and `CSSImport`s as well as a `CSSCharset`) while a `CSSRuleSet` can only contain `CSSRule`s. - -#### CSSRule - -`CSSRule`s just have a key (the rule) and multiple values (the part after the colon in the CSS file). This means the `values` attribute is an array consisting of arrays. The inner level of arrays is comma-separated in the CSS file while the outer level is whitespace-separated. - -#### CSSValue - -`CSSValue` is an abstract class that only defines the `__toString` method. The concrete subclasses are: - -* `CSSSize` – consists of a numeric `size` value and a unit. -* `CSSColor` – colors can be input in the form #rrggbb, #rgb or schema(val1, val2, …) but are alwas stored as an array of ('s' => val1, 'c' => val2, 'h' => val3, …) and output in the second form. -* `CSSString` – this is just a wrapper for quoted strings to distinguish them from keywords; always output with double quotes. -* `CSSURL` – URLs in CSS; always output in URL("") notation. - -To access the items stored in a `CSSList` – like the document you got back when calling `$oCssParser->parse()` –, use `getContents()`, then iterate over that collection and use instanceof to check whether you’re dealing with another `CSSList`, a `CSSRuleSet`, a `CSSImport` or a `CSSCharset`. - -To append a new item (selector, media query, etc.) to an existing `CSSList`, construct it using the constructor for this class and use the `append($oItem)` method. - -If you want to manipulate a `CSSRuleSet`, use the methods `addRule(CSSRule $oRule)`, `getRules()` and `removeRule($mRule)` (which accepts either a CSSRule instance or a rule name; optionally suffixed by a dash to remove all related rules). - -#### Convenience methods - -There are a few convenience methods on CSSDocument to ease finding, manipulating and deleting rules: - -* `getAllDeclarationBlocks()` – does what it says; no matter how deeply nested your selectors are. Aliased as `getAllSelectors()`. -* `getAllRuleSets()` – does what it says; no matter how deeply nested your rule sets are. -* `getAllValues()` – finds all `CSSValue` objects inside `CSSRule`s. - -### Use cases - -#### Use `CSSParser` to prepend an id to all selectors - - $sMyId = "#my_id"; - $oParser = new CSSParser($sCssContents); - $oCss = $oParser->parse(); - foreach($oCss->getAllDeclarationBlocks() as $oBlock) { - foreach($oBlock->getSelectors() as $oSelector) { - //Loop over all selector parts (the comma-separated strings in a selector) and prepend the id - $oSelector->setSelector($sMyId.' '.$oSelector->getSelector()); - } - } - -#### Shrink all absolute sizes to half - - $oParser = new CSSParser($sCssContents); - $oCss = $oParser->parse(); - foreach($oCss->getAllValues() as $mValue) { - if($mValue instanceof CSSSize && !$mValue->isRelative()) { - $mValue->setSize($mValue->getSize()/2); - } - } - -#### Remove unwanted rules - - $oParser = new CSSParser($sCssContents); - $oCss = $oParser->parse(); - foreach($oCss->getAllRuleSets() as $oRuleSet) { - $oRuleSet->removeRule('font-'); //Note that the added dash will make this remove all rules starting with font- (like font-size, font-weight, etc.) as well as a potential font-rule - $oRuleSet->removeRule('cursor'); - } - -### Output - -To output the entire CSS document into a variable, just use `->__toString()`: - - $oCssParser = new CSSParser(file_get_contents('somefile.css')); - $oCssDocument = $oCssParser->parse(); - print $oCssDocument->__toString(); - -## Examples - -### Example 1 (At-Rules) - -#### Input - - @charset "utf-8"; - - @font-face { - font-family: "CrassRoots"; - src: url("../media/cr.ttf") - } - - html, body { - font-size: 1.6em - } - -#### Structure (`var_dump()`) - - object(CSSDocument)#2 (1) { - ["aContents":"CSSList":private]=> - array(3) { - [0]=> - object(CSSCharset)#4 (1) { - ["sCharset":"CSSCharset":private]=> - object(CSSString)#3 (1) { - ["sString":"CSSString":private]=> - string(5) "utf-8" - } - } - [1]=> - object(CSSAtRule)#5 (2) { - ["sType":"CSSAtRule":private]=> - string(9) "font-face" - ["aRules":"CSSRuleSet":private]=> - array(2) { - ["font-family"]=> - object(CSSRule)#6 (3) { - ["sRule":"CSSRule":private]=> - string(11) "font-family" - ["mValue":"CSSRule":private]=> - object(CSSString)#7 (1) { - ["sString":"CSSString":private]=> - string(10) "CrassRoots" - } - ["bIsImportant":"CSSRule":private]=> - bool(false) - } - ["src"]=> - object(CSSRule)#8 (3) { - ["sRule":"CSSRule":private]=> - string(3) "src" - ["mValue":"CSSRule":private]=> - object(CSSURL)#9 (1) { - ["oURL":"CSSURL":private]=> - object(CSSString)#10 (1) { - ["sString":"CSSString":private]=> - string(15) "../media/cr.ttf" - } - } - ["bIsImportant":"CSSRule":private]=> - bool(false) - } - } - } - [2]=> - object(CSSDeclarationBlock)#11 (2) { - ["aSelectors":"CSSDeclarationBlock":private]=> - array(2) { - [0]=> - object(CSSSelector)#12 (2) { - ["sSelector":"CSSSelector":private]=> - string(4) "html" - ["iSpecificity":"CSSSelector":private]=> - NULL - } - [1]=> - object(CSSSelector)#13 (2) { - ["sSelector":"CSSSelector":private]=> - string(4) "body" - ["iSpecificity":"CSSSelector":private]=> - NULL - } - } - ["aRules":"CSSRuleSet":private]=> - array(1) { - ["font-size"]=> - object(CSSRule)#14 (3) { - ["sRule":"CSSRule":private]=> - string(9) "font-size" - ["mValue":"CSSRule":private]=> - object(CSSSize)#15 (3) { - ["fSize":"CSSSize":private]=> - float(1.6) - ["sUnit":"CSSSize":private]=> - string(2) "em" - ["bIsColorComponent":"CSSSize":private]=> - bool(false) - } - ["bIsImportant":"CSSRule":private]=> - bool(false) - } - } - } - } - } - -#### Output (`__toString()`) - - @charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}html, body {font-size: 1.6em;} - -### Example 2 (Values) - -#### Input - - #header { - margin: 10px 2em 1cm 2%; - font-family: Verdana, Helvetica, "Gill Sans", sans-serif; - color: red !important; - } - -#### Structure (`var_dump()`) - - object(CSSDocument)#2 (1) { - ["aContents":"CSSList":private]=> - array(1) { - [0]=> - object(CSSDeclarationBlock)#3 (2) { - ["aSelectors":"CSSDeclarationBlock":private]=> - array(1) { - [0]=> - object(CSSSelector)#4 (2) { - ["sSelector":"CSSSelector":private]=> - string(7) "#header" - ["iSpecificity":"CSSSelector":private]=> - NULL - } - } - ["aRules":"CSSRuleSet":private]=> - array(3) { - ["margin"]=> - object(CSSRule)#5 (3) { - ["sRule":"CSSRule":private]=> - string(6) "margin" - ["mValue":"CSSRule":private]=> - object(CSSRuleValueList)#10 (2) { - ["aComponents":protected]=> - array(4) { - [0]=> - object(CSSSize)#6 (3) { - ["fSize":"CSSSize":private]=> - float(10) - ["sUnit":"CSSSize":private]=> - string(2) "px" - ["bIsColorComponent":"CSSSize":private]=> - bool(false) - } - [1]=> - object(CSSSize)#7 (3) { - ["fSize":"CSSSize":private]=> - float(2) - ["sUnit":"CSSSize":private]=> - string(2) "em" - ["bIsColorComponent":"CSSSize":private]=> - bool(false) - } - [2]=> - object(CSSSize)#8 (3) { - ["fSize":"CSSSize":private]=> - float(1) - ["sUnit":"CSSSize":private]=> - string(2) "cm" - ["bIsColorComponent":"CSSSize":private]=> - bool(false) - } - [3]=> - object(CSSSize)#9 (3) { - ["fSize":"CSSSize":private]=> - float(2) - ["sUnit":"CSSSize":private]=> - string(1) "%" - ["bIsColorComponent":"CSSSize":private]=> - bool(false) - } - } - ["sSeparator":protected]=> - string(1) " " - } - ["bIsImportant":"CSSRule":private]=> - bool(false) - } - ["font-family"]=> - object(CSSRule)#11 (3) { - ["sRule":"CSSRule":private]=> - string(11) "font-family" - ["mValue":"CSSRule":private]=> - object(CSSRuleValueList)#13 (2) { - ["aComponents":protected]=> - array(4) { - [0]=> - string(7) "Verdana" - [1]=> - string(9) "Helvetica" - [2]=> - object(CSSString)#12 (1) { - ["sString":"CSSString":private]=> - string(9) "Gill Sans" - } - [3]=> - string(10) "sans-serif" - } - ["sSeparator":protected]=> - string(1) "," - } - ["bIsImportant":"CSSRule":private]=> - bool(false) - } - ["color"]=> - object(CSSRule)#14 (3) { - ["sRule":"CSSRule":private]=> - string(5) "color" - ["mValue":"CSSRule":private]=> - string(3) "red" - ["bIsImportant":"CSSRule":private]=> - bool(true) - } - } - } - } - } - -#### Output (`__toString()`) - - #header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans", sans-serif;color: red !important;} - -## To-Do - -* More convenience methods [like `selectorsWithElement($sId/Class/TagName)`, `removeSelector($oSelector)`, `attributesOfType($sType)`, `removeAttributesOfType($sType)`] -* Options for output (compact, verbose, etc.) -* Support for @namespace -* Named color support (using `CSSColor` instead of an anonymous string literal) -* Test suite -* Adopt lenient parsing rules -* Support for @-rules (other than @media) that are CSSLists (to support @-webkit-keyframes) - -## Contributors/Thanks to - -* [ju1ius](https://github.com/ju1ius) for the specificity parsing code and the ability to expand/compact shorthand properties. -* [GaryJones](https://github.com/GaryJones) for lots of input and [http://css-specificity.info/](http://css-specificity.info/). -* [docteurklein](https://github.com/docteurklein) for output formatting and `CSSList->remove()` inspiration. - -## License - -PHP-CSS-Parser is freely distributable under the terms of an MIT-style license. - -Copyright (c) 2011 Raphael Schweikert, http://sabberworm.com/ - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/phpQuery/CSSParser/lib/CSSList.php b/phpQuery/CSSParser/lib/CSSList.php deleted file mode 100755 index b2a4b23..0000000 --- a/phpQuery/CSSParser/lib/CSSList.php +++ /dev/null @@ -1,236 +0,0 @@ -aContents = array(); - } - - public function append($oItem) { - $this->aContents[] = $oItem; - } - - /** - * Removes an item from the CSS list. - * @param CSSRuleSet|CSSImport|CSSCharset|CSSList $oItemToRemove May be a CSSRuleSet (most likely a CSSDeclarationBlock), a CSSImport, a CSSCharset or another CSSList (most likely a CSSMediaQuery) - */ - public function remove($oItemToRemove) { - $iKey = array_search($oItemToRemove, $this->aContents, true); - if($iKey !== false) { - unset($this->aContents[$iKey]); - } - } - - public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false) { - if($mSelector instanceof CSSDeclarationBlock) { - $mSelector = $mSelector->getSelectors(); - } - if(!is_array($mSelector)) { - $mSelector = explode(',', $mSelector); - } - foreach($mSelector as $iKey => &$mSel) { - if(!($mSel instanceof CSSSelector)) { - $mSel = new CSSSelector($mSel); - } - } - foreach($this->aContents as $iKey => $mItem) { - if(!($mItem instanceof CSSDeclarationBlock)) { - continue; - } - if($mItem->getSelectors() == $mSelector) { - unset($this->aContents[$iKey]); - if(!$bRemoveAll) { - return; - } - } - } - } - - public function __toString() { - $sResult = ''; - foreach($this->aContents as $oContent) { - $sResult .= $oContent->__toString(); - } - return $sResult; - } - - public function getContents() { - return $this->aContents; - } - - protected function allDeclarationBlocks(&$aResult) { - foreach($this->aContents as $mContent) { - if($mContent instanceof CSSDeclarationBlock) { - $aResult[] = $mContent; - } else if($mContent instanceof CSSList) { - $mContent->allDeclarationBlocks($aResult); - } - } - } - - protected function allRuleSets(&$aResult) { - foreach($this->aContents as $mContent) { - if($mContent instanceof CSSRuleSet) { - $aResult[] = $mContent; - } else if($mContent instanceof CSSList) { - $mContent->allRuleSets($aResult); - } - } - } - - protected function allValues($oElement, &$aResult, $sSearchString = null, $bSearchInFunctionArguments = false) { - if($oElement instanceof CSSList) { - foreach($oElement->getContents() as $oContent) { - $this->allValues($oContent, $aResult, $sSearchString, $bSearchInFunctionArguments); - } - } else if($oElement instanceof CSSRuleSet) { - foreach($oElement->getRules($sSearchString) as $oRule) { - $this->allValues($oRule, $aResult, $sSearchString, $bSearchInFunctionArguments); - } - } else if($oElement instanceof CSSRule) { - $this->allValues($oElement->getValue(), $aResult, $sSearchString, $bSearchInFunctionArguments); - } else if($oElement instanceof CSSValueList) { - if($bSearchInFunctionArguments || !($oElement instanceof CSSFunction)) { - foreach($oElement->getListComponents() as $mComponent) { - $this->allValues($mComponent, $aResult, $sSearchString, $bSearchInFunctionArguments); - } - } - } else { - //Non-List CSSValue or String (CSS identifier) - $aResult[] = $oElement; - } - } - - protected function allSelectors(&$aResult, $sSpecificitySearch = null) { - foreach($this->getAllDeclarationBlocks() as $oBlock) { - foreach($oBlock->getSelectors() as $oSelector) { - if($sSpecificitySearch === null) { - $aResult[] = $oSelector; - } else { - $sComparison = "\$bRes = {$oSelector->getSpecificity()} $sSpecificitySearch;"; - eval($sComparison); - if($bRes) { - $aResult[] = $oSelector; - } - } - } - } - } -} - -/** -* The root CSSList of a parsed file. Contains all top-level css contents, mostly declaration blocks, but also any @-rules encountered. -*/ -class CSSDocument extends CSSList { - /** - * Gets all CSSDeclarationBlock objects recursively. - */ - public function getAllDeclarationBlocks() { - $aResult = array(); - $this->allDeclarationBlocks($aResult); - return $aResult; - } - - /** - * @deprecated use getAllDeclarationBlocks() - */ - public function getAllSelectors() { - return $this->getAllDeclarationBlocks(); - } - - /** - * Returns all CSSRuleSet objects found recursively in the tree. - */ - public function getAllRuleSets() { - $aResult = array(); - $this->allRuleSets($aResult); - return $aResult; - } - - /** - * Returns all CSSValue objects found recursively in the tree. - * @param (object|string) $mElement the CSSList or CSSRuleSet to start the search from (defaults to the whole document). If a string is given, it is used as rule name filter (@see{CSSRuleSet->getRules()}). - * @param (bool) $bSearchInFunctionArguments whether to also return CSSValue objects used as CSSFunction arguments. - */ - public function getAllValues($mElement = null, $bSearchInFunctionArguments = false) { - $sSearchString = null; - if($mElement === null) { - $mElement = $this; - } else if(is_string($mElement)) { - $sSearchString = $mElement; - $mElement = $this; - } - $aResult = array(); - $this->allValues($mElement, $aResult, $sSearchString, $bSearchInFunctionArguments); - return $aResult; - } - - /** - * Returns all CSSSelector objects found recursively in the tree. - * Note that this does not yield the full CSSDeclarationBlock that the selector belongs to (and, currently, there is no way to get to that). - * @param $sSpecificitySearch An optional filter by specificity. May contain a comparison operator and a number or just a number (defaults to "=="). - * @example getSelectorsBySpecificity('>= 100') - */ - public function getSelectorsBySpecificity($sSpecificitySearch = null) { - if(is_numeric($sSpecificitySearch) || is_numeric($sSpecificitySearch[0])) { - $sSpecificitySearch = "== $sSpecificitySearch"; - } - $aResult = array(); - $this->allSelectors($aResult, $sSpecificitySearch); - return $aResult; - } - - /** - * Expands all shorthand properties to their long value - */ - public function expandShorthands() - { - foreach($this->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->expandShorthands(); - } - } - - /* - * Create shorthands properties whenever possible - */ - public function createShorthands() - { - foreach($this->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->createShorthands(); - } - } -} - -/** -* A CSSList consisting of the CSSList and CSSList objects found in a @media query. -*/ -class CSSMediaQuery extends CSSList { - private $sQuery; - - public function __construct() { - parent::__construct(); - $this->sQuery = null; - } - - public function setQuery($sQuery) { - $this->sQuery = $sQuery; - } - - public function getQuery() { - return $this->sQuery; - } - - public function __toString() { - $sResult = "@media {$this->sQuery} {"; - $sResult .= parent::__toString(); - $sResult .= '}'; - return $sResult; - } -} diff --git a/phpQuery/CSSParser/lib/CSSProperties.php b/phpQuery/CSSParser/lib/CSSProperties.php deleted file mode 100755 index 15c9edb..0000000 --- a/phpQuery/CSSParser/lib/CSSProperties.php +++ /dev/null @@ -1,124 +0,0 @@ -oLocation = $oLocation; - $this->sMediaQuery = $sMediaQuery; - } - - public function setLocation($oLocation) { - $this->oLocation = $oLocation; - } - - public function getLocation() { - return $this->oLocation; - } - - public function __toString() { - return "@import ".$this->oLocation->__toString().($this->sMediaQuery === null ? '' : ' '.$this->sMediaQuery).';'; - } -} - -/** -* Class representing an @charset rule. -* The following restrictions apply: -* • May not be found in any CSSList other than the CSSDocument. -* • May only appear at the very top of a CSSDocument’s contents. -* • Must not appear more than once. -*/ -class CSSCharset { - private $sCharset; - - public function __construct($sCharset) { - $this->sCharset = $sCharset; - } - - public function setCharset($sCharset) { - $this->sCharset = $sCharset; - } - - public function getCharset() { - return $this->sCharset; - } - - public function __toString() { - return "@charset {$this->sCharset->__toString()};"; - } -} - -/** -* Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this class. -*/ -class CSSSelector { - const - NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX = '/ - (\.[\w]+) # classes - | - \[(\w+) # attributes - | - (\:( # pseudo classes - link|visited|active - |hover|focus - |lang - |target - |enabled|disabled|checked|indeterminate - |root - |nth-child|nth-last-child|nth-of-type|nth-last-of-type - |first-child|last-child|first-of-type|last-of-type - |only-child|only-of-type - |empty|contains - )) - /ix', - ELEMENTS_AND_PSEUDO_ELEMENTS_RX = '/ - ((^|[\s\+\>\~]+)[\w]+ # elements - | - \:{1,2}( # pseudo-elements - after|before - |first-letter|first-line - |selection - ) - )/ix'; - - private $sSelector; - private $iSpecificity; - - public function __construct($sSelector, $bCalculateSpecificity = false) { - $this->setSelector($sSelector); - if($bCalculateSpecificity) { - $this->getSpecificity(); - } - } - - public function getSelector() { - return $this->sSelector; - } - - public function setSelector($sSelector) { - $this->sSelector = trim($sSelector); - $this->iSpecificity = null; - } - - public function __toString() { - return $this->getSelector(); - } - - public function getSpecificity() { - if($this->iSpecificity === null) { - $a = 0; - /// @todo should exclude \# as well as "#" - $aMatches; - $b = substr_count($this->sSelector, '#'); - $c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches); - $d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches); - $this->iSpecificity = ($a*1000) + ($b*100) + ($c*10) + $d; - } - return $this->iSpecificity; - } -} - diff --git a/phpQuery/CSSParser/lib/CSSRule.php b/phpQuery/CSSParser/lib/CSSRule.php deleted file mode 100755 index d6ab6ac..0000000 --- a/phpQuery/CSSParser/lib/CSSRule.php +++ /dev/null @@ -1,135 +0,0 @@ -sRule = $sRule; - $this->mValue = null; - $this->bIsImportant = false; - } - - public function setRule($sRule) { - $this->sRule = $sRule; - } - - public function getRule() { - return $this->sRule; - } - - public function getValue() { - return $this->mValue; - } - - public function setValue($mValue) { - $this->mValue = $mValue; - } - - /** - * @deprecated Old-Style 2-dimensional array given. Retained for (some) backwards-compatibility. Use setValue() instead and wrapp the value inside a CSSRuleValueList if necessary. - */ - public function setValues($aSpaceSeparatedValues) { - $oSpaceSeparatedList = null; - if(count($aSpaceSeparatedValues) > 1) { - $oSpaceSeparatedList = new CSSRuleValueList(' '); - } - foreach($aSpaceSeparatedValues as $aCommaSeparatedValues) { - $oCommaSeparatedList = null; - if(count($aCommaSeparatedValues) > 1) { - $oCommaSeparatedList = new CSSRuleValueList(','); - } - foreach($aCommaSeparatedValues as $mValue) { - if(!$oSpaceSeparatedList && !$oCommaSeparatedList) { - $this->mValue = $mValue; - return $mValue; - } - if($oCommaSeparatedList) { - $oCommaSeparatedList->addListComponent($mValue); - } else { - $oSpaceSeparatedList->addListComponent($mValue); - } - } - if(!$oSpaceSeparatedList) { - $this->mValue = $oCommaSeparatedList; - return $oCommaSeparatedList; - } else { - $oSpaceSeparatedList->addListComponent($oCommaSeparatedList); - } - } - $this->mValue = $oSpaceSeparatedList; - return $oSpaceSeparatedList; - } - - /** - * @deprecated Old-Style 2-dimensional array returned. Retained for (some) backwards-compatibility. Use getValue() instead and check for the existance of a (nested set of) CSSValueList object(s). - */ - public function getValues() { - if(!$this->mValue instanceof CSSRuleValueList) { - return array(array($this->mValue)); - } - if($this->mValue->getListSeparator() === ',') { - return array($this->mValue->getListComponents()); - } - $aResult = array(); - foreach($this->mValue->getListComponents() as $mValue) { - if(!$mValue instanceof CSSRuleValueList || $mValue->getListSeparator() !== ',') { - $aResult[] = array($mValue); - continue; - } - if($this->mValue->getListSeparator() === ' ' || count($aResult) === 0) { - $aResult[] = array(); - } - foreach($mValue->getListComponents() as $mValue) { - $aResult[count($aResult)-1][] = $mValue; - } - } - return $aResult; - } - - /** - * Adds a value to the existing value. Value will be appended if a CSSRuleValueList exists of the given type. Otherwise, the existing value will be wrapped by one. - */ - public function addValue($mValue, $sType = ' ') { - if(!is_array($mValue)) { - $mValue = array($mValue); - } - if(!$this->mValue instanceof CSSRuleValueList || $this->mValue->getListSeparator() !== $sType) { - $mCurrentValue = $this->mValue; - $this->mValue = new CSSRuleValueList($sType); - if($mCurrentValue) { - $this->mValue->addListComponent($mCurrentValue); - } - } - foreach($mValue as $mValueItem) { - $this->mValue->addListComponent($mValueItem); - } - } - - public function setIsImportant($bIsImportant) { - $this->bIsImportant = $bIsImportant; - } - - public function getIsImportant() { - return $this->bIsImportant; - } - - public function __toString() { - $sResult = "{$this->sRule}: "; - if($this->mValue instanceof CSSValue) { //Can also be a CSSValueList - $sResult .= $this->mValue->__toString(); - } else { - $sResult .= $this->mValue; - } - if($this->bIsImportant) { - $sResult .= ' !important'; - } - $sResult .= ';'; - return $sResult; - } -} diff --git a/phpQuery/CSSParser/lib/CSSRuleSet.php b/phpQuery/CSSParser/lib/CSSRuleSet.php deleted file mode 100755 index 2788f2f..0000000 --- a/phpQuery/CSSParser/lib/CSSRuleSet.php +++ /dev/null @@ -1,653 +0,0 @@ -aRules = array(); - } - - public function addRule(CSSRule $oRule) { - $this->aRules[$oRule->getRule()] = $oRule; - } - - /** - * Returns all rules matching the given pattern - * @param (null|string|CSSRule) $mRule pattern to search for. If null, returns all rules. if the pattern ends with a dash, all rules starting with the pattern are returned as well as one matching the pattern with the dash excluded. passing a CSSRule behaves like calling getRules($mRule->getRule()). - * @example $oRuleSet->getRules('font-') //returns an array of all rules either beginning with font- or matching font. - * @example $oRuleSet->getRules('font') //returns array('font' => $oRule) or array(). - */ - public function getRules($mRule = null) { - if($mRule === null) { - return $this->aRules; - } - $aResult = array(); - if($mRule instanceof CSSRule) { - $mRule = $mRule->getRule(); - } - if(strrpos($mRule, '-')===strlen($mRule)-strlen('-')) { - $sStart = substr($mRule, 0, -1); - foreach($this->aRules as $oRule) { - if($oRule->getRule() === $sStart || strpos($oRule->getRule(), $mRule) === 0) { - $aResult[$oRule->getRule()] = $this->aRules[$oRule->getRule()]; - } - } - } else if(isset($this->aRules[$mRule])) { - $aResult[$mRule] = $this->aRules[$mRule]; - } - return $aResult; - } - - public function removeRule($mRule) { - if($mRule instanceof CSSRule) { - $mRule = $mRule->getRule(); - } - if(strrpos($mRule, '-')===strlen($mRule)-strlen('-')) { - $sStart = substr($mRule, 0, -1); - foreach($this->aRules as $oRule) { - if($oRule->getRule() === $sStart || strpos($oRule->getRule(), $mRule) === 0) { - unset($this->aRules[$oRule->getRule()]); - } - } - } else if(isset($this->aRules[$mRule])) { - unset($this->aRules[$mRule]); - } - } - - public function __toString() { - $sResult = ''; - foreach($this->aRules as $oRule) { - $sResult .= $oRule->__toString(); - } - return $sResult; - } -} - -/** -* A CSSRuleSet constructed by an unknown @-rule. @font-face rules are rendered into CSSAtRule objects. -*/ -class CSSAtRule extends CSSRuleSet { - private $sType; - - public function __construct($sType) { - parent::__construct(); - $this->sType = $sType; - } - - public function __toString() { - $sResult = "@{$this->sType} {"; - $sResult .= parent::__toString(); - $sResult .= '}'; - return $sResult; - } -} - -/** -* Declaration blocks are the parts of a css file which denote the rules belonging to a selector. -* Declaration blocks usually appear directly inside a CSSDocument or another CSSList (mostly a CSSMediaQuery). -*/ -class CSSDeclarationBlock extends CSSRuleSet { - - private $aSelectors; - - public function __construct() { - parent::__construct(); - $this->aSelectors = array(); - } - - public function setSelectors($mSelector) { - if(is_array($mSelector)) { - $this->aSelectors = $mSelector; - } else { - $this->aSelectors = explode(',', $mSelector); - } - foreach($this->aSelectors as $iKey => $mSelector) { - if(!($mSelector instanceof CSSSelector)) { - $this->aSelectors[$iKey] = new CSSSelector($mSelector); - } - } - } - - /** - * @deprecated use getSelectors() - */ - public function getSelector() { - return $this->getSelectors(); - } - - /** - * @deprecated use setSelectors() - */ - public function setSelector($mSelector) { - $this->setSelectors($mSelector); - } - - public function getSelectors() { - return $this->aSelectors; - } - - /** - * Split shorthand declarations (e.g. +margin+ or +font+) into their constituent parts. - **/ - public function expandShorthands() { - // border must be expanded before dimensions - $this->expandBorderShorthand(); - $this->expandDimensionsShorthand(); - $this->expandFontShorthand(); - $this->expandBackgroundShorthand(); - $this->expandListStyleShorthand(); - } - - /** - * Create shorthand declarations (e.g. +margin+ or +font+) whenever possible. - **/ - public function createShorthands() { - $this->createBackgroundShorthand(); - $this->createDimensionsShorthand(); - // border must be shortened after dimensions - $this->createBorderShorthand(); - $this->createFontShorthand(); - $this->createListStyleShorthand(); - } - - /** - * Split shorthand border declarations (e.g. border: 1px red;) - * Additional splitting happens in expandDimensionsShorthand - * Multiple borders are not yet supported as of CSS3 - **/ - public function expandBorderShorthand() { - $aBorderRules = array( - 'border', 'border-left', 'border-right', 'border-top', 'border-bottom' - ); - $aBorderSizes = array( - 'thin', 'medium', 'thick' - ); - $aRules = $this->getRules(); - foreach ($aBorderRules as $sBorderRule) { - if(!isset($aRules[$sBorderRule])) continue; - $oRule = $aRules[$sBorderRule]; - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - foreach ($aValues as $mValue) { - if($mValue instanceof CSSValue) { - $mNewValue = clone $mValue; - } else { - $mNewValue = $mValue; - } - if($mValue instanceof CSSSize) { - $sNewRuleName = $sBorderRule."-width"; - } else if($mValue instanceof CSSColor) { - $sNewRuleName = $sBorderRule."-color"; - } else { - if(in_array($mValue, $aBorderSizes)) { - $sNewRuleName = $sBorderRule."-width"; - } else/* if(in_array($mValue, $aBorderStyles))*/ { - $sNewRuleName = $sBorderRule."-style"; - } - } - $oNewRule = new CSSRule($sNewRuleName); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $oNewRule->addValue(array($mNewValue)); - $this->addRule($oNewRule); - } - $this->removeRule($sBorderRule); - } - } - - /** - * Split shorthand dimensional declarations (e.g. margin: 0px auto;) - * into their constituent parts. - * Handles margin, padding, border-color, border-style and border-width. - **/ - public function expandDimensionsShorthand() { - $aExpansions = array( - 'margin' => 'margin-%s', - 'padding' => 'padding-%s', - 'border-color' => 'border-%s-color', - 'border-style' => 'border-%s-style', - 'border-width' => 'border-%s-width' - ); - $aRules = $this->getRules(); - foreach ($aExpansions as $sProperty => $sExpanded) { - if(!isset($aRules[$sProperty])) continue; - $oRule = $aRules[$sProperty]; - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - $top = $right = $bottom = $left = null; - switch(count($aValues)) { - case 1: - $top = $right = $bottom = $left = $aValues[0]; - break; - case 2: - $top = $bottom = $aValues[0]; - $left = $right = $aValues[1]; - break; - case 3: - $top = $aValues[0]; - $left = $right = $aValues[1]; - $bottom = $aValues[2]; - break; - case 4: - $top = $aValues[0]; - $right = $aValues[1]; - $bottom = $aValues[2]; - $left = $aValues[3]; - break; - } - foreach(array('top', 'right', 'bottom', 'left') as $sPosition) { - $oNewRule = new CSSRule(sprintf($sExpanded, $sPosition)); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $oNewRule->addValue(${$sPosition}); - $this->addRule($oNewRule); - } - $this->removeRule($sProperty); - } - } - - /** - * Convert shorthand font declarations - * (e.g. font: 300 italic 11px/14px verdana, helvetica, sans-serif;) - * into their constituent parts. - **/ - public function expandFontShorthand() { - $aRules = $this->getRules(); - if(!isset($aRules['font'])) return; - $oRule = $aRules['font']; - // reset properties to 'normal' per http://www.w3.org/TR/CSS21/fonts.html#font-shorthand - $aFontProperties = array( - 'font-style' => 'normal', - 'font-variant' => 'normal', - 'font-weight' => 'normal', - 'font-size' => 'normal', - 'line-height' => 'normal' - ); - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - foreach($aValues as $mValue) { - if(!$mValue instanceof CSSValue) { - $mValue = mb_strtolower($mValue); - } - if(in_array($mValue, array('normal', 'inherit'))) { - foreach (array('font-style', 'font-weight', 'font-variant') as $sProperty) { - if(!isset($aFontProperties[$sProperty])) { - $aFontProperties[$sProperty] = $mValue; - } - } - } else if(in_array($mValue, array('italic', 'oblique'))) { - $aFontProperties['font-style'] = $mValue; - } else if($mValue == 'small-caps') { - $aFontProperties['font-variant'] = $mValue; - } else if( - in_array($mValue, array('bold', 'bolder', 'lighter')) - || ($mValue instanceof CSSSize - && in_array($mValue->getSize(), range(100, 900, 100))) - ) { - $aFontProperties['font-weight'] = $mValue; - } else if($mValue instanceof CSSRuleValueList && $mValue->getListSeparator() == '/') { - list($oSize, $oHeight) = $mValue->getListComponents(); - $aFontProperties['font-size'] = $oSize; - $aFontProperties['line-height'] = $oHeight; - } else if($mValue instanceof CSSSize && $mValue->getUnit() !== null) { - $aFontProperties['font-size'] = $mValue; - } else { - $aFontProperties['font-family'] = $mValue; - } - } - foreach ($aFontProperties as $sProperty => $mValue) { - $oNewRule = new CSSRule($sProperty); - $oNewRule->addValue($mValue); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $this->addRule($oNewRule); - } - $this->removeRule('font'); - } - - /* - * Convert shorthand background declarations - * (e.g. background: url("chess.png") gray 50% repeat fixed;) - * into their constituent parts. - * @see http://www.w3.org/TR/CSS21/colors.html#propdef-background - **/ - public function expandBackgroundShorthand() { - $aRules = $this->getRules(); - if(!isset($aRules['background'])) return; - $oRule = $aRules['background']; - $aBgProperties = array( - 'background-color' => array('transparent'), 'background-image' => array('none'), - 'background-repeat' => array('repeat'), 'background-attachment' => array('scroll'), - 'background-position' => array(new CSSSize(0, '%'), new CSSSize(0, '%')) - ); - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - if(count($aValues) == 1 && $aValues[0] == 'inherit') { - foreach ($aBgProperties as $sProperty => $mValue) { - $oNewRule = new CSSRule($sProperty); - $oNewRule->addValue('inherit'); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $this->addRule($oNewRule); - } - $this->removeRule('background'); - return; - } - $iNumBgPos = 0; - foreach($aValues as $mValue) { - if(!$mValue instanceof CSSValue) { - $mValue = mb_strtolower($mValue); - } - if ($mValue instanceof CSSURL) { - $aBgProperties['background-image'] = $mValue; - } else if($mValue instanceof CSSColor) { - $aBgProperties['background-color'] = $mValue; - } else if(in_array($mValue, array('scroll', 'fixed'))) { - $aBgProperties['background-attachment'] = $mValue; - } else if(in_array($mValue, array('repeat','no-repeat', 'repeat-x', 'repeat-y'))) { - $aBgProperties['background-repeat'] = $mValue; - } else if(in_array($mValue, array('left','center','right','top','bottom')) - || $mValue instanceof CSSSize - ){ - if($iNumBgPos == 0) { - $aBgProperties['background-position'][0] = $mValue; - $aBgProperties['background-position'][1] = 'center'; - } else { - $aBgProperties['background-position'][$iNumBgPos] = $mValue; - } - $iNumBgPos++; - } - } - foreach ($aBgProperties as $sProperty => $mValue) { - $oNewRule = new CSSRule($sProperty); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $oNewRule->addValue($mValue); - $this->addRule($oNewRule); - } - $this->removeRule('background'); - } - - public function expandListStyleShorthand() { - $aListProperties = array( - 'list-style-type' => 'disc', - 'list-style-position' => 'outside', - 'list-style-image' => 'none' - ); - $aListStyleTypes = array( - 'none', 'disc', 'circle', 'square', 'decimal-leading-zero', 'decimal', - 'lower-roman', 'upper-roman', 'lower-greek', 'lower-alpha', 'lower-latin', - 'upper-alpha', 'upper-latin', 'hebrew', 'armenian', 'georgian', 'cjk-ideographic', - 'hiragana', 'hira-gana-iroha', 'katakana-iroha', 'katakana' - ); - $aListStylePositions = array( - 'inside', 'outside' - ); - $aRules = $this->getRules(); - if(!isset($aRules['list-style'])) return; - $oRule = $aRules['list-style']; - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - if(count($aValues) == 1 && $aValues[0] == 'inherit') { - foreach ($aListProperties as $sProperty => $mValue) { - $oNewRule = new CSSRule($sProperty); - $oNewRule->addValue('inherit'); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $this->addRule($oNewRule); - } - $this->removeRule('list-style'); - return; - } - foreach($aValues as $mValue) { - if(!$mValue instanceof CSSValue) { - $mValue = mb_strtolower($mValue); - } - if($mValue instanceof CSSUrl) { - $aListProperties['list-style-image'] = $mValue; - } else if(in_array($mValue, $aListStyleTypes)) { - $aListProperties['list-style-types'] = $mValue; - } else if(in_array($mValue, $aListStylePositions)) { - $aListProperties['list-style-position'] = $mValue; - } - } - foreach ($aListProperties as $sProperty => $mValue) { - $oNewRule = new CSSRule($sProperty); - $oNewRule->setIsImportant($oRule->getIsImportant()); - $oNewRule->addValue($mValue); - $this->addRule($oNewRule); - } - $this->removeRule('list-style'); - } - - public function createShorthandProperties(array $aProperties, $sShorthand) { - $aRules = $this->getRules(); - $aNewValues = array(); - foreach($aProperties as $sProperty) { - if(!isset($aRules[$sProperty])) continue; - $oRule = $aRules[$sProperty]; - if(!$oRule->getIsImportant()) { - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - foreach($aValues as $mValue) { - $aNewValues[] = $mValue; - } - $this->removeRule($sProperty); - } - } - if(count($aNewValues)) { - $oNewRule = new CSSRule($sShorthand); - foreach($aNewValues as $mValue) { - $oNewRule->addValue($mValue); - } - $this->addRule($oNewRule); - } - } - - public function createBackgroundShorthand() { - $aProperties = array( - 'background-color', 'background-image', 'background-repeat', - 'background-position', 'background-attachment' - ); - $this->createShorthandProperties($aProperties, 'background'); - } - - public function createListStyleShorthand() { - $aProperties = array( - 'list-style-type', 'list-style-position', 'list-style-image' - ); - $this->createShorthandProperties($aProperties, 'list-style'); - } - - /** - * Combine border-color, border-style and border-width into border - * Should be run after create_dimensions_shorthand! - **/ - public function createBorderShorthand() { - $aProperties = array( - 'border-width', 'border-style', 'border-color' - ); - $this->createShorthandProperties($aProperties, 'border'); - } - - /* - * Looks for long format CSS dimensional properties - * (margin, padding, border-color, border-style and border-width) - * and converts them into shorthand CSS properties. - **/ - public function createDimensionsShorthand() { - $aPositions = array('top', 'right', 'bottom', 'left'); - $aExpansions = array( - 'margin' => 'margin-%s', - 'padding' => 'padding-%s', - 'border-color' => 'border-%s-color', - 'border-style' => 'border-%s-style', - 'border-width' => 'border-%s-width' - ); - $aRules = $this->getRules(); - foreach ($aExpansions as $sProperty => $sExpanded) { - $aFoldable = array(); - foreach($aRules as $sRuleName => $oRule) { - foreach ($aPositions as $sPosition) { - if($sRuleName == sprintf($sExpanded, $sPosition)) { - $aFoldable[$sRuleName] = $oRule; - } - } - } - // All four dimensions must be present - if(count($aFoldable) == 4) { - $aValues = array(); - foreach ($aPositions as $sPosition) { - $oRule = $aRules[sprintf($sExpanded, $sPosition)]; - $mRuleValue = $oRule->getValue(); - $aRuleValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aRuleValues[] = $mRuleValue; - } else { - $aRuleValues = $mRuleValue->getListComponents(); - } - $aValues[$sPosition] = $aRuleValues; - } - $oNewRule = new CSSRule($sProperty); - if((string)$aValues['left'][0] == (string)$aValues['right'][0]) { - if((string)$aValues['top'][0] == (string)$aValues['bottom'][0]) { - if((string)$aValues['top'][0] == (string)$aValues['left'][0]) { - // All 4 sides are equal - $oNewRule->addValue($aValues['top']); - } else { - // Top and bottom are equal, left and right are equal - $oNewRule->addValue($aValues['top']); - $oNewRule->addValue($aValues['left']); - } - } else { - // Only left and right are equal - $oNewRule->addValue($aValues['top']); - $oNewRule->addValue($aValues['left']); - $oNewRule->addValue($aValues['bottom']); - } - } else { - // No sides are equal - $oNewRule->addValue($aValues['top']); - $oNewRule->addValue($aValues['left']); - $oNewRule->addValue($aValues['bottom']); - $oNewRule->addValue($aValues['right']); - } - $this->addRule($oNewRule); - foreach ($aPositions as $sPosition) - { - $this->removeRule(sprintf($sExpanded, $sPosition)); - } - } - } - } - - /** - * Looks for long format CSS font properties (e.g. font-weight) and - * tries to convert them into a shorthand CSS font property. - * At least font-size AND font-family must be present in order to create a shorthand declaration. - **/ - public function createFontShorthand() { - $aFontProperties = array( - 'font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family' - ); - $aRules = $this->getRules(); - if(!isset($aRules['font-size']) || !isset($aRules['font-family'])) { - return; - } - $oNewRule = new CSSRule('font'); - foreach(array('font-style', 'font-variant', 'font-weight') as $sProperty) { - if(isset($aRules[$sProperty])) { - $oRule = $aRules[$sProperty]; - $mRuleValue = $oRule->getValue(); - $aValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aValues[] = $mRuleValue; - } else { - $aValues = $mRuleValue->getListComponents(); - } - if($aValues[0] !== 'normal') { - $oNewRule->addValue($aValues[0]); - } - } - } - // Get the font-size value - $oRule = $aRules['font-size']; - $mRuleValue = $oRule->getValue(); - $aFSValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aFSValues[] = $mRuleValue; - } else { - $aFSValues = $mRuleValue->getListComponents(); - } - // But wait to know if we have line-height to add it - if(isset($aRules['line-height'])) { - $oRule = $aRules['line-height']; - $mRuleValue = $oRule->getValue(); - $aLHValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aLHValues[] = $mRuleValue; - } else { - $aLHValues = $mRuleValue->getListComponents(); - } - if($aLHValues[0] !== 'normal') { - $val = new CSSRuleValueList('/'); - $val->addListComponent($aFSValues[0]); - $val->addListComponent($aLHValues[0]); - $oNewRule->addValue($val); - } - } else { - $oNewRule->addValue($aFSValues[0]); - } - $oRule = $aRules['font-family']; - $mRuleValue = $oRule->getValue(); - $aFFValues = array(); - if(!$mRuleValue instanceof CSSRuleValueList) { - $aFFValues[] = $mRuleValue; - } else { - $aFFValues = $mRuleValue->getListComponents(); - } - $oFFValue = new CSSRuleValueList(','); - $oFFValue->setListComponents($aFFValues); - $oNewRule->addValue($oFFValue); - - $this->addRule($oNewRule); - foreach ($aFontProperties as $sProperty) { - $this->removeRule($sProperty); - } - } - - public function __toString() { - $sResult = implode(', ', $this->aSelectors).' {'; - $sResult .= parent::__toString(); - $sResult .= '}'."\n"; - return $sResult; - } -} diff --git a/phpQuery/CSSParser/lib/CSSValue.php b/phpQuery/CSSParser/lib/CSSValue.php deleted file mode 100755 index 6dc3fb9..0000000 --- a/phpQuery/CSSParser/lib/CSSValue.php +++ /dev/null @@ -1,110 +0,0 @@ -fSize = floatval($fSize); - $this->sUnit = $sUnit; - $this->bIsColorComponent = $bIsColorComponent; - } - - public function setUnit($sUnit) { - $this->sUnit = $sUnit; - } - - public function getUnit() { - return $this->sUnit; - } - - public function setSize($fSize) { - $this->fSize = floatval($fSize); - } - - public function getSize() { - return $this->fSize; - } - - public function isColorComponent() { - return $this->bIsColorComponent; - } - - /** - * Returns whether the number stored in this CSSSize really represents a size (as in a length of something on screen). - * @return false if the unit an angle, a duration, a frequency or the number is a component in a CSSColor object. - */ - public function isSize() { - $aNonSizeUnits = array('deg', 'grad', 'rad', 'turns', 's', 'ms', 'Hz', 'kHz'); - if(in_array($this->sUnit, $aNonSizeUnits)) { - return false; - } - return !$this->isColorComponent(); - } - - public function isRelative() { - if($this->sUnit === '%' || $this->sUnit === 'em' || $this->sUnit === 'ex') { - return true; - } - if($this->sUnit === null && $this->fSize != 0) { - return true; - } - return false; - } - - public function __toString() { - return $this->fSize.($this->sUnit === null ? '' : $this->sUnit); - } -} - -class CSSString extends CSSPrimitiveValue { - private $sString; - - public function __construct($sString) { - $this->sString = $sString; - } - - public function setString($sString) { - $this->sString = $sString; - } - - public function getString() { - return $this->sString; - } - - public function __toString() { - $sString = addslashes($this->sString); - $sString = str_replace("\n", '\A', $sString); - return '"'.$sString.'"'; - } -} - -class CSSURL extends CSSPrimitiveValue { - private $oURL; - - public function __construct(CSSString $oURL) { - $this->oURL = $oURL; - } - - public function setURL(CSSString $oURL) { - $this->oURL = $oURL; - } - - public function getURL() { - return $this->oURL; - } - - public function __toString() { - return "url({$this->oURL->__toString()})"; - } -} - diff --git a/phpQuery/CSSParser/lib/CSSValueList.php b/phpQuery/CSSParser/lib/CSSValueList.php deleted file mode 100755 index 35269e2..0000000 --- a/phpQuery/CSSParser/lib/CSSValueList.php +++ /dev/null @@ -1,92 +0,0 @@ -getListSeparator() === $sSeparator) { - $aComponents = $aComponents->getListComponents(); - } else if(!is_array($aComponents)) { - $aComponents = array($aComponents); - } - $this->aComponents = $aComponents; - $this->sSeparator = $sSeparator; - } - - public function addListComponent($mComponent) { - $this->aComponents[] = $mComponent; - } - - public function getListComponents() { - return $this->aComponents; - } - - public function setListComponents($aComponents) { - $this->aComponents = $aComponents; - } - - public function getListSeparator() { - return $this->sSeparator; - } - - public function setListSeparator($sSeparator) { - $this->sSeparator = $sSeparator; - } - - function __toString() { - return implode($this->sSeparator, $this->aComponents); - } -} - -class CSSRuleValueList extends CSSValueList { - public function __construct($sSeparator = ',') { - parent::__construct(array(), $sSeparator); - } -} - -class CSSFunction extends CSSValueList { - private $sName; - public function __construct($sName, $aArguments) { - $this->sName = $sName; - parent::__construct($aArguments); - } - - public function getName() { - return $this->sName; - } - - public function setName($sName) { - $this->sName = $sName; - } - - public function getArguments() { - return $this->aComponents; - } - - public function __toString() { - $aArguments = parent::__toString(); - return "{$this->sName}({$aArguments})"; - } -} - -class CSSColor extends CSSFunction { - public function __construct($aColor) { - parent::__construct(implode('', array_keys($aColor)), $aColor); - } - - public function getColor() { - return $this->aComponents; - } - - public function setColor($aColor) { - $this->setName(implode('', array_keys($aColor))); - $this->aComponents = $aColor; - } - - public function getColorDescription() { - return $this->getName(); - } -} - - diff --git a/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php b/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php deleted file mode 100755 index 0d311c7..0000000 --- a/phpQuery/CSSParser/tests/CSSDeclarationBlockTest.php +++ /dev/null @@ -1,223 +0,0 @@ -parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->expandBorderShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function expandBorderShorthandProvider() - { - return array( - array('body{ border: 2px solid rgb(0,0,0) }', 'body {border-width: 2px;border-style: solid;border-color: rgb(0,0,0);}'), - array('body{ border: none }', 'body {border-style: none;}'), - array('body{ border: 2px }', 'body {border-width: 2px;}'), - array('body{ border: rgb(255,0,0) }', 'body {border-color: rgb(255,0,0);}'), - array('body{ border: 1em solid }', 'body {border-width: 1em;border-style: solid;}'), - array('body{ margin: 1em; }', 'body {margin: 1em;}') - ); - } - - /** - * @dataProvider expandFontShorthandProvider - **/ - public function testExpandFontShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->expandFontShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function expandFontShorthandProvider() - { - return array( - array( - 'body{ margin: 1em; }', - 'body {margin: 1em;}' - ), - array( - 'body {font: 12px serif;}', - 'body {font-style: normal;font-variant: normal;font-weight: normal;font-size: 12px;line-height: normal;font-family: serif;}' - ), - array( - 'body {font: italic 12px serif;}', - 'body {font-style: italic;font-variant: normal;font-weight: normal;font-size: 12px;line-height: normal;font-family: serif;}' - ), - array( - 'body {font: italic bold 12px serif;}', - 'body {font-style: italic;font-variant: normal;font-weight: bold;font-size: 12px;line-height: normal;font-family: serif;}' - ), - array( - 'body {font: italic bold 12px/1.6 serif;}', - 'body {font-style: italic;font-variant: normal;font-weight: bold;font-size: 12px;line-height: 1.6;font-family: serif;}' - ), - array( - 'body {font: italic small-caps bold 12px/1.6 serif;}', - 'body {font-style: italic;font-variant: small-caps;font-weight: bold;font-size: 12px;line-height: 1.6;font-family: serif;}' - ), - ); - } - - /** - * @dataProvider expandBackgroundShorthandProvider - **/ - public function testExpandBackgroundShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->expandBackgroundShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function expandBackgroundShorthandProvider() - { - return array( - array('body {border: 1px;}', 'body {border: 1px;}'), - array('body {background: rgb(255,0,0);}','body {background-color: rgb(255,0,0);background-image: none;background-repeat: repeat;background-attachment: scroll;background-position: 0% 0%;}'), - array('body {background: rgb(255,0,0) url("foobar.png");}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: repeat;background-attachment: scroll;background-position: 0% 0%;}'), - array('body {background: rgb(255,0,0) url("foobar.png") no-repeat;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: 0% 0%;}'), - array('body {background: rgb(255,0,0) url("foobar.png") no-repeat center;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: center center;}'), - array('body {background: rgb(255,0,0) url("foobar.png") no-repeat top left;}','body {background-color: rgb(255,0,0);background-image: url("foobar.png");background-repeat: no-repeat;background-attachment: scroll;background-position: top left;}'), - ); - } - - /** - * @dataProvider expandDimensionsShorthandProvider - **/ - public function testExpandDimensionsShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->expandDimensionsShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function expandDimensionsShorthandProvider() - { - return array( - array('body {border: 1px;}', 'body {border: 1px;}'), - array('body {margin-top: 1px;}', 'body {margin-top: 1px;}'), - array('body {margin: 1em;}','body {margin-top: 1em;margin-right: 1em;margin-bottom: 1em;margin-left: 1em;}'), - array('body {margin: 1em 2em;}','body {margin-top: 1em;margin-right: 2em;margin-bottom: 1em;margin-left: 2em;}'), - array('body {margin: 1em 2em 3em;}','body {margin-top: 1em;margin-right: 2em;margin-bottom: 3em;margin-left: 2em;}'), - ); - } - - /** - * @dataProvider createBorderShorthandProvider - **/ - public function testCreateBorderShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->createBorderShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function createBorderShorthandProvider() - { - return array( - array('body {border-width: 2px;border-style: solid;border-color: rgb(0,0,0);}', 'body {border: 2px solid rgb(0,0,0);}'), - array('body {border-style: none;}', 'body {border: none;}'), - array('body {border-width: 1em;border-style: solid;}', 'body {border: 1em solid;}'), - array('body {margin: 1em;}', 'body {margin: 1em;}') - ); - } - - /** - * @dataProvider createFontShorthandProvider - **/ - public function testCreateFontShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->createFontShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function createFontShorthandProvider() - { - return array( - array('body {font-size: 12px; font-family: serif}', 'body {font: 12px serif;}'), - array('body {font-size: 12px; font-family: serif; font-style: italic;}', 'body {font: italic 12px serif;}'), - array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold;}', 'body {font: italic bold 12px serif;}'), - array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold; line-height: 1.6;}', 'body {font: italic bold 12px/1.6 serif;}'), - array('body {font-size: 12px; font-family: serif; font-style: italic; font-weight: bold; line-height: 1.6; font-variant: small-caps;}', 'body {font: italic small-caps bold 12px/1.6 serif;}'), - array('body {margin: 1em;}', 'body {margin: 1em;}') - ); - } - - /** - * @dataProvider createDimensionsShorthandProvider - **/ - public function testCreateDimensionsShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->createDimensionsShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function createDimensionsShorthandProvider() - { - return array( - array('body {border: 1px;}', 'body {border: 1px;}'), - array('body {margin-top: 1px;}', 'body {margin-top: 1px;}'), - array('body {margin-top: 1em; margin-right: 1em; margin-bottom: 1em; margin-left: 1em;}','body {margin: 1em;}'), - array('body {margin-top: 1em; margin-right: 2em; margin-bottom: 1em; margin-left: 2em;}','body {margin: 1em 2em;}'), - array('body {margin-top: 1em; margin-right: 2em; margin-bottom: 3em; margin-left: 2em;}','body {margin: 1em 2em 3em;}'), - ); - } - - /** - * @dataProvider createBackgroundShorthandProvider - **/ - public function testCreateBackgroundShorthand($sCss, $sExpected) - { - $oParser = new CSSParser($sCss); - $oDoc = $oParser->parse(); - foreach($oDoc->getAllDeclarationBlocks() as $oDeclaration) - { - $oDeclaration->createBackgroundShorthand(); - } - $this->assertSame(trim((string)$oDoc), $sExpected); - } - public function createBackgroundShorthandProvider() - { - return array( - array('body {border: 1px;}', 'body {border: 1px;}'), - array('body {background-color: rgb(255,0,0);}', 'body {background: rgb(255,0,0);}'), - array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);}', 'body {background: rgb(255,0,0) url("foobar.png");}'), - array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat;}'), - array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat;}'), - array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;background-position: center;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat center;}'), - array('body {background-color: rgb(255,0,0);background-image: url(foobar.png);background-repeat: no-repeat;background-position: top left;}', 'body {background: rgb(255,0,0) url("foobar.png") no-repeat top left;}'), - ); - } - -} diff --git a/phpQuery/CSSParser/tests/CSSParserTests.php b/phpQuery/CSSParser/tests/CSSParserTests.php deleted file mode 100755 index 66071c2..0000000 --- a/phpQuery/CSSParser/tests/CSSParserTests.php +++ /dev/null @@ -1,277 +0,0 @@ -assertNotEquals('', $oParser->parse()->__toString()); - } catch(Exception $e) { - $this->fail($e); - } - } - closedir($rHandle); - } - } - - /** - * @depends testCssFiles - */ - function testColorParsing() { - $oDoc = $this->parsedStructureForFile('colortest'); - foreach($oDoc->getAllRuleSets() as $oRuleSet) { - if(!$oRuleSet instanceof CSSDeclarationBlock) { - continue; - } - $sSelector = $oRuleSet->getSelectors(); - $sSelector = $sSelector[0]->getSelector(); - if($sSelector == '#mine') { - $aColorRule = $oRuleSet->getRules('color'); - $aValues = $aColorRule['color']->getValues(); - $this->assertSame('red', $aValues[0][0]); - $aColorRule = $oRuleSet->getRules('background-'); - $aValues = $aColorRule['background-color']->getValues(); - $this->assertEquals(array('r' => new CSSSize(35.0, null, true), 'g' => new CSSSize(35.0, null, true), 'b' => new CSSSize(35.0, null, true)), $aValues[0][0]->getColor()); - $aColorRule = $oRuleSet->getRules('border-color'); - $aValues = $aColorRule['border-color']->getValues(); - $this->assertEquals(array('r' => new CSSSize(10.0, null, true), 'g' => new CSSSize(100.0, null, true), 'b' => new CSSSize(230.0, null, true), 'a' => new CSSSize(0.3, null, true)), $aValues[0][0]->getColor()); - $aColorRule = $oRuleSet->getRules('outline-color'); - $aValues = $aColorRule['outline-color']->getValues(); - $this->assertEquals(array('r' => new CSSSize(34.0, null, true), 'g' => new CSSSize(34.0, null, true), 'b' => new CSSSize(34.0, null, true)), $aValues[0][0]->getColor()); - } - } - foreach($oDoc->getAllValues('background-') as $oColor) { - if($oColor->getColorDescription() === 'hsl') { - $this->assertEquals(array('h' => new CSSSize(220.0, null, true), 's' => new CSSSize(10.0, null, true), 'l' => new CSSSize(220.0, null, true)), $oColor->getColor()); - } - } - foreach($oDoc->getAllValues('color') as $sColor) { - $this->assertSame('red', $sColor); - } - } - - function testUnicodeParsing() { - $oDoc = $this->parsedStructureForFile('unicode'); - foreach($oDoc->getAllDeclarationBlocks() as $oRuleSet) { - $sSelector = $oRuleSet->getSelectors(); - $sSelector = $sSelector[0]->getSelector(); - if(substr($sSelector, 0, strlen('.test-')) !== '.test-') { - continue; - } - $aContentRules = $oRuleSet->getRules('content'); - $aContents = $aContentRules['content']->getValues(); - $sCssString = $aContents[0][0]->__toString(); - if($sSelector == '.test-1') { - $this->assertSame('" "', $sCssString); - } - if($sSelector == '.test-2') { - $this->assertSame('"é"', $sCssString); - } - if($sSelector == '.test-3') { - $this->assertSame('" "', $sCssString); - } - if($sSelector == '.test-4') { - $this->assertSame('"𝄞"', $sCssString); - } - if($sSelector == '.test-5') { - $this->assertSame('"水"', $sCssString); - } - if($sSelector == '.test-6') { - $this->assertSame('"¥"', $sCssString); - } - if($sSelector == '.test-7') { - $this->assertSame('"\A"', $sCssString); - } - if($sSelector == '.test-8') { - $this->assertSame('"\"\""', $sCssString); - } - if($sSelector == '.test-9') { - $this->assertSame('"\"\\\'"', $sCssString); - } - if($sSelector == '.test-10') { - $this->assertSame('"\\\'\\\\"', $sCssString); - } - if($sSelector == '.test-11') { - $this->assertSame('"test"', $sCssString); - } - } - } - - function testSpecificity() { - $oDoc = $this->parsedStructureForFile('specificity'); - $oDeclarationBlock = $oDoc->getAllDeclarationBlocks(); - $oDeclarationBlock = $oDeclarationBlock[0]; - $aSelectors = $oDeclarationBlock->getSelectors(); - foreach($aSelectors as $oSelector) { - switch($oSelector->getSelector()) { - case "#test .help": - $this->assertSame(110, $oSelector->getSpecificity()); - break; - case "#file": - $this->assertSame(100, $oSelector->getSpecificity()); - break; - case ".help:hover": - $this->assertSame(20, $oSelector->getSpecificity()); - break; - case "ol li::before": - $this->assertSame(3, $oSelector->getSpecificity()); - break; - case "li.green": - $this->assertSame(11, $oSelector->getSpecificity()); - break; - default: - $this->fail("specificity: untested selector ".$oSelector->getSelector()); - } - } - $this->assertEquals(array(new CSSSelector('#test .help', true)), $oDoc->getSelectorsBySpecificity('> 100')); - } - - function testManipulation() { - $oDoc = $this->parsedStructureForFile('atrules'); - $this->assertSame('@charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}html, body {font-size: 1.6em;}'."\n", $oDoc->__toString()); - foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { - foreach($oBlock->getSelectors() as $oSelector) { - //Loop over all selector parts (the comma-separated strings in a selector) and prepend the id - $oSelector->setSelector('#my_id '.$oSelector->getSelector()); - } - } - $this->assertSame('@charset "utf-8";@font-face {font-family: "CrassRoots";src: url("../media/cr.ttf");}#my_id html, #my_id body {font-size: 1.6em;}'."\n", $oDoc->__toString()); - - $oDoc = $this->parsedStructureForFile('values'); - $this->assertSame('#header {margin: 10px 2em 1cm 2%;font-family: Verdana,Helvetica,"Gill Sans",sans-serif;font-size: 10px;color: red !important;} -body {color: green;font: 75% "Lucida Grande","Trebuchet MS",Verdana,sans-serif;}'."\n", $oDoc->__toString()); - foreach($oDoc->getAllRuleSets() as $oRuleSet) { - $oRuleSet->removeRule('font-'); - } - $this->assertSame('#header {margin: 10px 2em 1cm 2%;color: red !important;} -body {color: green;}'."\n", $oDoc->__toString()); - } - - function testSlashedValues() { - $oDoc = $this->parsedStructureForFile('slashed'); - $this->assertSame('.test {font: 12px/1.5 Verdana,Arial,sans-serif;border-radius: 5px 10px 5px 10px/10px 5px 10px 5px;}'."\n", $oDoc->__toString()); - foreach($oDoc->getAllValues(null) as $mValue) { - if($mValue instanceof CSSSize && $mValue->isSize() && !$mValue->isRelative()) { - $mValue->setSize($mValue->getSize()*3); - } - } - foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { - $oRule = $oBlock->getRules('font'); - $oRule = $oRule['font']; - $oSpaceList = $oRule->getValue(); - $this->assertEquals(' ', $oSpaceList->getListSeparator()); - $oSlashList = $oSpaceList->getListComponents(); - $oCommaList = $oSlashList[1]; - $oSlashList = $oSlashList[0]; - $this->assertEquals(',', $oCommaList->getListSeparator()); - $this->assertEquals('/', $oSlashList->getListSeparator()); - $oRule = $oBlock->getRules('border-radius'); - $oRule = $oRule['border-radius']; - $oSlashList = $oRule->getValue(); - $this->assertEquals('/', $oSlashList->getListSeparator()); - $oSpaceList1 = $oSlashList->getListComponents(); - $oSpaceList2 = $oSpaceList1[1]; - $oSpaceList1 = $oSpaceList1[0]; - $this->assertEquals(' ', $oSpaceList1->getListSeparator()); - $this->assertEquals(' ', $oSpaceList2->getListSeparator()); - } - $this->assertSame('.test {font: 36px/1.5 Verdana,Arial,sans-serif;border-radius: 15px 30px 15px 30px/30px 15px 30px 15px;}'."\n", $oDoc->__toString()); - } - - function testFunctionSyntax() { - $oDoc = $this->parsedStructureForFile('functions'); - $sExpected = 'div.main {background-image: linear-gradient(rgb(0,0,0),rgb(255,255,255));} -.collapser::before, .collapser::-moz-before, .collapser::-webkit-before {content: "»";font-size: 1.2em;margin-right: 0.2em;-moz-transition-property: -moz-transform;-moz-transition-duration: 0.2s;-moz-transform-origin: center 60%;} -.collapser.expanded::before, .collapser.expanded::-moz-before, .collapser.expanded::-webkit-before {-moz-transform: rotate(90deg);} -.collapser + * {height: 0;overflow: hidden;-moz-transition-property: height;-moz-transition-duration: 0.3s;} -.collapser.expanded + * {height: auto;}'."\n"; - $this->assertSame($sExpected, $oDoc->__toString()); - - foreach($oDoc->getAllValues(null, true) as $mValue) { - if($mValue instanceof CSSSize && $mValue->isSize()) { - $mValue->setSize($mValue->getSize()*3); - } - } - $sExpected = str_replace(array('1.2em', '0.2em', '60%'), array('3.6em', '0.6em', '180%'), $sExpected); - $this->assertSame($sExpected, $oDoc->__toString()); - - foreach($oDoc->getAllValues(null, true) as $mValue) { - if($mValue instanceof CSSSize && !$mValue->isRelative() && !$mValue->isColorComponent()) { - $mValue->setSize($mValue->getSize()*2); - } - } - $sExpected = str_replace(array('0.2s', '0.3s', '90deg'), array('0.4s', '0.6s', '180deg'), $sExpected); - $this->assertSame($sExpected, $oDoc->__toString()); - } - - function testExpandShorthands() { - $oDoc = $this->parsedStructureForFile('expand-shorthands'); - $sExpected = 'body {font: italic 500 14px/1.618 "Trebuchet MS",Georgia,serif;border: 2px solid rgb(255,0,255);background: rgb(204,204,204) url("/images/foo.png") no-repeat left top;margin: 1em !important;padding: 2px 6px 3px;}'."\n"; - $this->assertSame($sExpected, $oDoc->__toString()); - $oDoc->expandShorthands(); - $sExpected = 'body {margin-top: 1em !important;margin-right: 1em !important;margin-bottom: 1em !important;margin-left: 1em !important;padding-top: 2px;padding-right: 6px;padding-bottom: 3px;padding-left: 6px;border-top-color: rgb(255,0,255);border-right-color: rgb(255,0,255);border-bottom-color: rgb(255,0,255);border-left-color: rgb(255,0,255);border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-width: 2px;border-right-width: 2px;border-bottom-width: 2px;border-left-width: 2px;font-style: italic;font-variant: normal;font-weight: 500;font-size: 14px;line-height: 1.618;font-family: "Trebuchet MS",Georgia,serif;background-color: rgb(204,204,204);background-image: url("/images/foo.png");background-repeat: no-repeat;background-attachment: scroll;background-position: left top;}'."\n"; - $this->assertSame($sExpected, $oDoc->__toString()); - } - - function testCreateShorthands() { - $oDoc = $this->parsedStructureForFile('create-shorthands'); - $sExpected = 'body {font-size: 2em;font-family: Helvetica,Arial,sans-serif;font-weight: bold;border-width: 2px;border-color: rgb(153,153,153);border-style: dotted;background-color: rgb(255,255,255);background-image: url("foobar.png");background-repeat: repeat-y;margin-top: 2px;margin-right: 3px;margin-bottom: 4px;margin-left: 5px;}'."\n"; - $this->assertSame($sExpected, $oDoc->__toString()); - $oDoc->createShorthands(); - $sExpected = 'body {background: rgb(255,255,255) url("foobar.png") repeat-y;margin: 2px 5px 4px 3px;border: 2px dotted rgb(153,153,153);font: bold 2em Helvetica,Arial,sans-serif;}'."\n"; - $this->assertSame($sExpected, $oDoc->__toString()); - } - - function testListValueRemoval() { - $oDoc = $this->parsedStructureForFile('atrules'); - foreach($oDoc->getContents() as $oItem) { - if($oItem instanceof CSSAtRule) { - $oDoc->remove($oItem); - break; - } - } - $this->assertSame('@charset "utf-8";html, body {font-size: 1.6em;}'."\n", $oDoc->__toString()); - - $oDoc = $this->parsedStructureForFile('nested'); - foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { - $oDoc->removeDeclarationBlockBySelector($oBlock, false); - break; - } - $this->assertSame('html {some-other: -test(val1);} -@media screen {html {some: -test(val2);} -}#unrelated {other: yes;}'."\n", $oDoc->__toString()); - - $oDoc = $this->parsedStructureForFile('nested'); - foreach($oDoc->getAllDeclarationBlocks() as $oBlock) { - $oDoc->removeDeclarationBlockBySelector($oBlock, true); - break; - } - $this->assertSame('@media screen {html {some: -test(val2);} -}#unrelated {other: yes;}'."\n", $oDoc->__toString()); - } - - function parsedStructureForFile($sFileName) { - $sFile = dirname(__FILE__).DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR."$sFileName.css"; - $oParser = new CSSParser(file_get_contents($sFile)); - return $oParser->parse(); - } - -} diff --git a/phpQuery/CSSParser/tests/files/-tobedone.css b/phpQuery/CSSParser/tests/files/-tobedone.css deleted file mode 100755 index 7ec1da9..0000000 --- a/phpQuery/CSSParser/tests/files/-tobedone.css +++ /dev/null @@ -1,7 +0,0 @@ -.some[selectors-may='contain-a-{'] { - -} - -.some { - filters: may(contain, a, ')'); -} diff --git a/phpQuery/CSSParser/tests/files/atrules.css b/phpQuery/CSSParser/tests/files/atrules.css deleted file mode 100755 index adfa9f9..0000000 --- a/phpQuery/CSSParser/tests/files/atrules.css +++ /dev/null @@ -1,10 +0,0 @@ -@charset "utf-8"; - -@font-face { - font-family: "CrassRoots"; - src: url("../media/cr.ttf") -} - -html, body { - font-size: 1.6em -} diff --git a/phpQuery/CSSParser/tests/files/colortest.css b/phpQuery/CSSParser/tests/files/colortest.css deleted file mode 100755 index 41fe2a2..0000000 --- a/phpQuery/CSSParser/tests/files/colortest.css +++ /dev/null @@ -1,10 +0,0 @@ -#mine { - color: red; - border-color: rgba(10, 100, 230, 0.3); - outline-color: #222; - background-color: #232323; -} - -#yours { - background-color: hsl(220, 10, 220); -} diff --git a/phpQuery/CSSParser/tests/files/create-shorthands.css b/phpQuery/CSSParser/tests/files/create-shorthands.css deleted file mode 100755 index c784d67..0000000 --- a/phpQuery/CSSParser/tests/files/create-shorthands.css +++ /dev/null @@ -1,7 +0,0 @@ -body -{ - font-size: 2em; font-family: Helvetica,Arial,sans-serif; font-weight: bold; - border-width: 2px; border-color: #999; border-style: dotted; - background-color: #fff; background-image: url('foobar.png'); background-repeat: repeat-y; - margin-top: 2px; margin-right: 3px; margin-bottom: 4px; margin-left: 5px; -} diff --git a/phpQuery/CSSParser/tests/files/expand-shorthands.css b/phpQuery/CSSParser/tests/files/expand-shorthands.css deleted file mode 100755 index 89aab1e..0000000 --- a/phpQuery/CSSParser/tests/files/expand-shorthands.css +++ /dev/null @@ -1,7 +0,0 @@ -body { - font: italic 500 14px/1.618 "Trebuchet MS", Georgia, serif; - border: 2px solid #f0f; - background: #ccc url("/images/foo.png") no-repeat left top; - margin: 1em !important; - padding: 2px 6px 3px; -} diff --git a/phpQuery/CSSParser/tests/files/functions.css b/phpQuery/CSSParser/tests/files/functions.css deleted file mode 100755 index eabbd24..0000000 --- a/phpQuery/CSSParser/tests/files/functions.css +++ /dev/null @@ -1,22 +0,0 @@ -div.main { background-image: linear-gradient(#000, #fff) } -.collapser::before, -.collapser::-moz-before, -.collapser::-webkit-before { - content: "»"; - font-size: 1.2em; - margin-right: .2em; - -moz-transition-property: -moz-transform; - -moz-transition-duration: .2s; - -moz-transform-origin: center 60%; -} -.collapser.expanded::before, -.collapser.expanded::-moz-before, -.collapser.expanded::-webkit-before { -moz-transform: rotate(90deg) } -.collapser + * { - height: 0; - overflow: hidden; - -moz-transition-property: height; - -moz-transition-duration: .3s; -} -.collapser.expanded + * { height: auto } - diff --git a/phpQuery/CSSParser/tests/files/ie.css b/phpQuery/CSSParser/tests/files/ie.css deleted file mode 100755 index 6c0fb38..0000000 --- a/phpQuery/CSSParser/tests/files/ie.css +++ /dev/null @@ -1,6 +0,0 @@ -.nav-thumb-wrapper:hover img, a.activeSlide img { - filter: alpha(opacity=100); - -moz-opacity: 1; - -khtml-opacity: 1; - opacity: 1; -} diff --git a/phpQuery/CSSParser/tests/files/important.css b/phpQuery/CSSParser/tests/files/important.css deleted file mode 100755 index edf24a8..0000000 --- a/phpQuery/CSSParser/tests/files/important.css +++ /dev/null @@ -1,8 +0,0 @@ -div.rating-cancel,div.star-rating{float:left;width:17px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden} -div.rating-cancel,div.rating-cancel a{background:url(images/delete.gif) no-repeat 0 -16px} -div.star-rating,div.star-rating a{background:url(images/star.gif) no-repeat 0 0px} -div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0} -div.star-rating-on a{background-position:0 -16px!important} -div.star-rating-hover a{background-position:0 -32px} -div.star-rating-readonly a{cursor:default !important} -div.star-rating{background:transparent!important; overflow:hidden!important} \ No newline at end of file diff --git a/phpQuery/CSSParser/tests/files/nested.css b/phpQuery/CSSParser/tests/files/nested.css deleted file mode 100755 index b59dc80..0000000 --- a/phpQuery/CSSParser/tests/files/nested.css +++ /dev/null @@ -1,17 +0,0 @@ -html { - some: -test(val1); -} - -html { - some-other: -test(val1); -} - -@media screen { - html { - some: -test(val2); - } -} - -#unrelated { - other: yes; -} diff --git a/phpQuery/CSSParser/tests/files/slashed.css b/phpQuery/CSSParser/tests/files/slashed.css deleted file mode 100755 index 5b629be..0000000 --- a/phpQuery/CSSParser/tests/files/slashed.css +++ /dev/null @@ -1,4 +0,0 @@ -.test { - font: 12px/1.5 Verdana, Arial, sans-serif; - border-radius: 5px 10px 5px 10px / 10px 5px 10px 5px; -} diff --git a/phpQuery/CSSParser/tests/files/specificity.css b/phpQuery/CSSParser/tests/files/specificity.css deleted file mode 100755 index 82a2939..0000000 --- a/phpQuery/CSSParser/tests/files/specificity.css +++ /dev/null @@ -1,7 +0,0 @@ -#test .help, -#file, -.help:hover, -li.green, -ol li::before { - font-family: Helvetica; -} diff --git a/phpQuery/CSSParser/tests/files/unicode.css b/phpQuery/CSSParser/tests/files/unicode.css deleted file mode 100755 index 2482320..0000000 --- a/phpQuery/CSSParser/tests/files/unicode.css +++ /dev/null @@ -1,12 +0,0 @@ -.test-1 { content: "\20"; } /* Same as " " */ -.test-2 { content: "\E9"; } /* Same as "é" */ -.test-3 { content: "\0020"; } /* Same as " " */ -.test-5 { content: "\6C34" } /* Same as "水" */ -.test-6 { content: "\00A5" } /* Same as "¥" */ -.test-7 { content: '\a' } /* Same as "\A" (Newline) */ -.test-8 { content: "\"\22" } /* Same as "\"\"" */ -.test-9 { content: "\"\27" } /* Same as ""\"\'"" */ -.test-10 { content: "\'\\" } /* Same as "'\" */ -.test-11 { content: "\test" } /* Same as "test" */ - -.test-4 { content: "\1D11E" } /* Beyond the Basic Multilingual Plane */ diff --git a/phpQuery/CSSParser/tests/files/values.css b/phpQuery/CSSParser/tests/files/values.css deleted file mode 100755 index 1f41863..0000000 --- a/phpQuery/CSSParser/tests/files/values.css +++ /dev/null @@ -1,11 +0,0 @@ -#header { - margin: 10px 2em 1cm 2%; - font-family: Verdana, Helvetica, "Gill Sans", sans-serif; - font-size: 10px; - color: red !important; -} - -body { - color: green; - font: 75% "Lucida Grande", "Trebuchet MS", Verdana, sans-serif; -} diff --git a/phpQuery/CSSParser/tests/files/whitespace.css b/phpQuery/CSSParser/tests/files/whitespace.css deleted file mode 100755 index 6b21c24..0000000 --- a/phpQuery/CSSParser/tests/files/whitespace.css +++ /dev/null @@ -1,3 +0,0 @@ -.test { - background-image : url ( 4px ) ; -} diff --git a/phpQuery/CSSParser/tests/quickdump.php b/phpQuery/CSSParser/tests/quickdump.php deleted file mode 100755 index 071a72b..0000000 --- a/phpQuery/CSSParser/tests/quickdump.php +++ /dev/null @@ -1,15 +0,0 @@ -parse(); - -echo '#### Structure (`var_dump()`)'."\n"; -var_dump($oDoc); - -echo '#### Output (`__toString()`)'."\n"; -print $oDoc->__toString(); -echo "\n"; - diff --git a/phpQuery/phpQuery.php b/phpQuery/phpQuery.php index 9f2b21c..1c08c45 100644 --- a/phpQuery/phpQuery.php +++ b/phpQuery/phpQuery.php @@ -24,7 +24,6 @@ require_once(dirname(__FILE__).'/phpQuery/Callback.php'); require_once(dirname(__FILE__).'/phpQuery/phpQueryObject.php'); require_once(dirname(__FILE__).'/phpQuery/compat/mbstring.php'); -require_once(dirname(__FILE__).'/CSSParser/CSSParser.php'); /** * Static namespace for phpQuery functions. * From b288208ce885a4d945b8480bee4b629773ace37c Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 15:19:49 -0600 Subject: [PATCH 33/59] Address errors when PHP is in strict mode. --- unit-tests/test.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unit-tests/test.php b/unit-tests/test.php index 6465ca0..03b914c 100644 --- a/unit-tests/test.php +++ b/unit-tests/test.php @@ -169,6 +169,7 @@ function testSimpleDataInsertion( $pq ) {

    paragraph after UL

    EOF; + $expected_pq = phpQuery::newDocumentHTML($testResult); $rows = array( array( 'title' => 'News 1 title', @@ -199,7 +200,8 @@ function testSimpleDataInsertion( $pq ) { $result = $pq->find('.articles')->htmlOuter(); // print htmlspecialchars("
    {$result}
    ").'
    '; - $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); + $this->assertEqualXMLStructure($expected_pq->find('.articles')->elements[0], $pq->find('.articles')->elements[0]); +// $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); } /** From 695184933a5060b8c493230325c9d47d5a694b86 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 7 Mar 2014 21:43:48 -0600 Subject: [PATCH 34/59] Closes #6. Shift the classes into PHP namespaces. --- {cli => bin}/phpquery | 0 composer.json | 6 +- .../phpQuery => docs}/bootstrap.example.php | 0 demo.php => docs/demo.php | 0 .../example.php => docs/plugin.example.php | 6 +- jQueryServer/jQueryServer.php | 107 - phpQuery/phpQuery.php | 1347 ------- phpQuery/phpQuery/DOMDocumentWrapper.php | 679 ---- phpQuery/phpQuery/DOMEvent.php | 107 - phpQuery/phpQuery/compat/mbstring.php | 88 - phpQuery/phpQuery/phpQueryEvents.php | 158 - phpQuery/phpQuery/phpQueryObject.php | 3379 ---------------- phpunit.xml.dist | 2 +- .../phpQuery => src/Callback}/Callback.php | 0 src/Dom/DomDocumentWrapper.php | 709 ++++ src/Dom/DomEvent.php | 110 + src/PhpQuery.php | 1365 +++++++ src/PhpQueryEvents.php | 161 + src/PhpQueryObject.php | 3449 +++++++++++++++++ .../plugins => src/Plugin}/Scripts.php | 18 +- .../Plugin}/Scripts/__config.example.php | 0 .../Plugin}/Scripts/example.php | 0 .../Plugin}/Scripts/fix_webroot.php | 0 .../Plugin}/Scripts/google_login.php | 0 .../Plugin}/Scripts/print_source.php | 2 +- .../Plugin}/Scripts/print_websafe.php | 2 +- .../plugins => src/Plugin}/WebBrowser.php | 16 +- {jQueryServer => src/Proxy}/demo/demo.htm | 0 {jQueryServer => src/Proxy}/demo/jquery.js | 0 .../Proxy}/jQueryServer.config.php.example | 0 {jQueryServer => src/Proxy}/jQueryServer.js | 0 src/Proxy/jQueryServer.php | 116 + .../phpQuery => src/Resources}/default.css | 0 src/Tests/BasicTest.php | 205 + .../document-fragment-utf8.html | 0 .../document-fragment-utf8.xhtml | 0 .../document-types/document-fragment-utf8.xml | 0 .../document-iso88592-nocharset.html | 0 .../document-iso88592-nocharset.xhtml | 0 .../document-iso88592-nocharset.xml | 0 .../document-types/document-iso88592.html | 0 .../document-types/document-iso88592.xhtml | 0 .../document-types/document-iso88592.xml | 0 .../document-utf8-nocharset.html | 0 .../document-utf8-nocharset.xhtml | 0 .../document-utf8-nocharset.xml | 0 .../document-types/document-utf8.html | 0 .../document-types/document-utf8.php | 0 .../document-types/document-utf8.xhtml | 0 .../document-types/document-utf8.xml | 0 .../Tests/_archive}/document_types.php | 0 {test-cases => src/Tests/_archive}/run.php | 0 {test-cases => src/Tests/_archive}/test.html | 0 {test-cases => src/Tests/_archive}/test_2.php | 0 {test-cases => src/Tests/_archive}/test_4.php | 0 {test-cases => src/Tests/_archive}/test_5.php | 0 .../Tests/_archive}/test_ajax.php | 0 .../Tests/_archive}/test_ajax_data_1 | 0 .../Tests/_archive}/test_arrayaccess.php | 0 .../Tests/_archive}/test_attr.php | 0 .../Tests/_archive}/test_callback.php | 2 +- .../Tests/_archive}/test_charset.php | 0 .../Tests/_archive}/test_document.php | 0 .../Tests/_archive}/test_events.php | 0 .../Tests/_archive}/test_insert.php | 0 .../Tests/_archive}/test_manipulation.php | 0 .../Tests/_archive}/test_manual.php | 0 .../Tests/_archive}/test_multidoc.php | 0 .../Tests/_archive}/test_php.php | 0 .../Tests/_archive}/test_replace.php | 0 .../Tests/_archive}/test_scripts.php | 0 .../Tests/_archive}/test_selectors.php | 0 .../Tests/_archive}/test_webbrowser.php | 4 +- .../Tests/_archive}/test_wrap.php | 0 {test-cases => src/Tests/_archive}/xpath.php | 0 {unit-tests => src/Tests}/test.html | 0 src/bootstrap.php | 97 + unit-tests/test.php | 231 -- 78 files changed, 6241 insertions(+), 6125 deletions(-) rename {cli => bin}/phpquery (100%) rename {phpQuery/phpQuery => docs}/bootstrap.example.php (100%) rename demo.php => docs/demo.php (100%) rename phpQuery/phpQuery/plugins/example.php => docs/plugin.example.php (92%) delete mode 100755 jQueryServer/jQueryServer.php delete mode 100644 phpQuery/phpQuery.php delete mode 100644 phpQuery/phpQuery/DOMDocumentWrapper.php delete mode 100644 phpQuery/phpQuery/DOMEvent.php delete mode 100644 phpQuery/phpQuery/compat/mbstring.php delete mode 100644 phpQuery/phpQuery/phpQueryEvents.php delete mode 100644 phpQuery/phpQuery/phpQueryObject.php rename {phpQuery/phpQuery => src/Callback}/Callback.php (100%) create mode 100644 src/Dom/DomDocumentWrapper.php create mode 100644 src/Dom/DomEvent.php create mode 100644 src/PhpQuery.php create mode 100644 src/PhpQueryEvents.php create mode 100644 src/PhpQueryObject.php rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts.php (75%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/__config.example.php (100%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/example.php (100%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/fix_webroot.php (100%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/google_login.php (100%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/print_source.php (87%) rename {phpQuery/phpQuery/plugins => src/Plugin}/Scripts/print_websafe.php (91%) rename {phpQuery/phpQuery/plugins => src/Plugin}/WebBrowser.php (95%) rename {jQueryServer => src/Proxy}/demo/demo.htm (100%) rename {jQueryServer => src/Proxy}/demo/jquery.js (100%) rename {jQueryServer => src/Proxy}/jQueryServer.config.php.example (100%) rename {jQueryServer => src/Proxy}/jQueryServer.js (100%) create mode 100755 src/Proxy/jQueryServer.php rename {phpQuery/phpQuery => src/Resources}/default.css (100%) create mode 100644 src/Tests/BasicTest.php rename {test-cases => src/Tests/_archive}/document-types/document-fragment-utf8.html (100%) rename {test-cases => src/Tests/_archive}/document-types/document-fragment-utf8.xhtml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-fragment-utf8.xml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592-nocharset.html (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592-nocharset.xhtml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592-nocharset.xml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592.html (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592.xhtml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-iso88592.xml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8-nocharset.html (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8-nocharset.xhtml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8-nocharset.xml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8.html (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8.php (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8.xhtml (100%) rename {test-cases => src/Tests/_archive}/document-types/document-utf8.xml (100%) rename {test-cases => src/Tests/_archive}/document_types.php (100%) rename {test-cases => src/Tests/_archive}/run.php (100%) rename {test-cases => src/Tests/_archive}/test.html (100%) rename {test-cases => src/Tests/_archive}/test_2.php (100%) rename {test-cases => src/Tests/_archive}/test_4.php (100%) rename {test-cases => src/Tests/_archive}/test_5.php (100%) rename {test-cases => src/Tests/_archive}/test_ajax.php (100%) rename {test-cases => src/Tests/_archive}/test_ajax_data_1 (100%) rename {test-cases => src/Tests/_archive}/test_arrayaccess.php (100%) rename {test-cases => src/Tests/_archive}/test_attr.php (100%) rename {test-cases => src/Tests/_archive}/test_callback.php (93%) rename {test-cases => src/Tests/_archive}/test_charset.php (100%) rename {test-cases => src/Tests/_archive}/test_document.php (100%) rename {test-cases => src/Tests/_archive}/test_events.php (100%) rename {test-cases => src/Tests/_archive}/test_insert.php (100%) rename {test-cases => src/Tests/_archive}/test_manipulation.php (100%) rename {test-cases => src/Tests/_archive}/test_manual.php (100%) rename {test-cases => src/Tests/_archive}/test_multidoc.php (100%) rename {test-cases => src/Tests/_archive}/test_php.php (100%) rename {test-cases => src/Tests/_archive}/test_replace.php (100%) rename {test-cases => src/Tests/_archive}/test_scripts.php (100%) rename {test-cases => src/Tests/_archive}/test_selectors.php (100%) rename {test-cases => src/Tests/_archive}/test_webbrowser.php (96%) rename {test-cases => src/Tests/_archive}/test_wrap.php (100%) rename {test-cases => src/Tests/_archive}/xpath.php (100%) rename {unit-tests => src/Tests}/test.html (100%) create mode 100644 src/bootstrap.php delete mode 100644 unit-tests/test.php diff --git a/cli/phpquery b/bin/phpquery similarity index 100% rename from cli/phpquery rename to bin/phpquery diff --git a/composer.json b/composer.json index f6819a0..0906c8d 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,8 @@ "sabberworm/php-css-parser":"5.1.*" }, "autoload":{ - "classmap":[ - "phpQuery/" - ] + "psr-4":{ + "PhpQuery\\": "src/" + } } } \ No newline at end of file diff --git a/phpQuery/phpQuery/bootstrap.example.php b/docs/bootstrap.example.php similarity index 100% rename from phpQuery/phpQuery/bootstrap.example.php rename to docs/bootstrap.example.php diff --git a/demo.php b/docs/demo.php similarity index 100% rename from demo.php rename to docs/demo.php diff --git a/phpQuery/phpQuery/plugins/example.php b/docs/plugin.example.php similarity index 92% rename from phpQuery/phpQuery/plugins/example.php rename to docs/plugin.example.php index 732f05c..c2270f4 100644 --- a/phpQuery/phpQuery/plugins/example.php +++ b/docs/plugin.example.php @@ -18,9 +18,9 @@ * phpQuery plugin class extending phpQuery object. * Methods from this class are callable on every phpQuery object. * - * Class name prefix 'phpQueryObjectPlugin_' must be preserved. + * Class name prefix '\PhpQuery\Plugin\' must be preserved. */ -abstract class phpQueryObjectPlugin_example { +abstract class \PhpQuery\Plugin\example { /** * Limit binded methods. * @@ -33,7 +33,7 @@ abstract class phpQueryObjectPlugin_example { /** * Enter description here... * - * @param phpQueryObject $self + * @param PhpQueryObject $self */ public static function example($self, $arg1) { // this method can be called on any phpQuery object, like this: diff --git a/jQueryServer/jQueryServer.php b/jQueryServer/jQueryServer.php deleted file mode 100755 index 75ff064..0000000 --- a/jQueryServer/jQueryServer.php +++ /dev/null @@ -1,107 +0,0 @@ -` - * @link http://code.google.com/p/phpquery/wiki/jQueryServer - * @link http://code.google.com/p/phpquery/ - * @todo local files support (safe...) - * @todo respond with proper HTTP code - * @todo persistant thread support (with timeout...) - * @todo 2.0: JSON RPC - Zend_Json_Server - * @todo 2.0: XML RPC ? - */ -class jQueryServer { - public $config = array( - 'allowedRefererHosts' => array('.'), - 'refererMustMatch' => true, - ); - public $calls = null; - public $options = null; - public $allowedHosts = null; - function __construct($data) { - $pq = null; - include_once(dirname(__FILE__).'/../phpQuery/phpQuery.php'); - if (file_exists(dirname(__FILE__).'/jQueryServer.config.php')) { - include_once(dirname(__FILE__).'/jQueryServer.config.php'); - if ($jQueryServerConfig) - $this->config = array_merge_recursive($this->config, $jQueryServerConfig); - } - if ($this->config['refererMustMatch']) { - foreach($this->config['allowedRefererHosts'] as $i => $host) - if ($host == '.') - $this->config['allowedRefererHosts'][$i] = $_SERVER['HTTP_HOST']; - $referer = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); - $authorized = $referer - && in_array($referer, $this->config['allowedRefererHosts']); - if (! $authorized) { - throw new Exception("Host '{$_SERVER['HTTP_REFERER']}' not authorized to make requests."); - return; - } - } -// phpQueryClass::$debug = true; -// if (! function_exists('json_decode')) { -// include_once(dirname(__FILE__).'/JSON.php'); -// $this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); -// } -// $data = $this->jsonDecode($data); - $data = phpQuery::parseJSON($data); - // load document (required for first $data element) - if (is_array($data[0]) && isset($data[0]['url'])) { - $this->options = $data[0]; - $ajax = $this->options; - $this->calls = array_slice($data, 1); - $ajax['success'] = array($this, 'success'); - phpQuery::ajax($ajax); - } else { - throw new Exception("URL needed to download content"); - } - } - public function success($response) { - $pq = phpQuery::newDocument($response); - foreach($this->calls as $k => $r) { - // check if method exists - if (! method_exists(get_class($pq), $r['method'])) { - throw new Exception("Method '{$r['method']}' not implemented in phpQuery, sorry..."); - // execute method - } else { - $pq = call_user_func_array( - array($pq, $r['method']), - $r['arguments'] - ); - } - } - if (! isset($this->options['dataType'])) - $this->options['dataType'] = ''; - switch(strtolower($this->options['dataType'])) { - case 'json': - if ( $pq instanceof PHPQUERYOBJECT ) { - $results = array(); - foreach($pq as $node) - $results[] = pq($node)->htmlOuter(); - print phpQuery::toJSON($results); - } else { - print phpQuery::toJSON($pq); - } - break; - default: - print $pq; - } - // output results - } -// public function jsonEncode($data) { -// return function_exists('json_encode') -// ? json_encode($data) -// : $this->json->encode($data); -// } -// public function jsonDecode($data) { -// return function_exists('json_decode') -// ? json_decode($data, true) -// : $this->json->decode($data); -// } -} -new jQueryServer($_POST['data']); -?> \ No newline at end of file diff --git a/phpQuery/phpQuery.php b/phpQuery/phpQuery.php deleted file mode 100644 index 1c08c45..0000000 --- a/phpQuery/phpQuery.php +++ /dev/null @@ -1,1347 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package phpQuery - */ - -// class names for instanceof -// TODO move them as class constants into phpQuery -define('DOMDOCUMENT', 'DOMDocument'); -define('DOMELEMENT', 'DOMElement'); -define('DOMNODELIST', 'DOMNodeList'); -define('DOMNODE', 'DOMNode'); -require_once(dirname(__FILE__).'/phpQuery/DOMEvent.php'); -require_once(dirname(__FILE__).'/phpQuery/DOMDocumentWrapper.php'); -require_once(dirname(__FILE__).'/phpQuery/phpQueryEvents.php'); -require_once(dirname(__FILE__).'/phpQuery/Callback.php'); -require_once(dirname(__FILE__).'/phpQuery/phpQueryObject.php'); -require_once(dirname(__FILE__).'/phpQuery/compat/mbstring.php'); -/** - * Static namespace for phpQuery functions. - * - * @author Tobiasz Cudnik - * @package phpQuery - */ -abstract class phpQuery { - /** - * XXX: Workaround for mbstring problems - * - * @var bool - */ - public static $mbstringSupport = true; - public static $debug = false; - public static $documents = array(); - public static $defaultDocumentID = null; -// public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"'; - /** - * Applies only to HTML. - * - * @var unknown_type - */ - public static $defaultDoctype = ''; - public static $defaultCharset = 'UTF-8'; - /** - * Static namespace for plugins. - * - * @var object - */ - public static $plugins = array(); - /** - * List of loaded plugins. - * - * @var unknown_type - */ - public static $pluginsLoaded = array(); - public static $pluginsMethods = array(); - public static $pluginsStaticMethods = array(); - public static $extendMethods = array(); - /** - * @TODO implement - */ - public static $extendStaticMethods = array(); - /** - * Hosts allowed for AJAX connections. - * Dot '.' means $_SERVER['HTTP_HOST'] (if any). - * - * @var array - */ - public static $ajaxAllowedHosts = array( - '.' - ); - /** - * AJAX settings. - * - * @var array - * XXX should it be static or not ? - */ - public static $ajaxSettings = array( - 'url' => '',//TODO - 'global' => true, - 'type' => "GET", - 'timeout' => null, - 'contentType' => "application/x-www-form-urlencoded", - 'processData' => true, -// 'async' => true, - 'data' => null, - 'username' => null, - 'password' => null, - 'dataType' => null, - 'ifModified' => null, - 'accepts' => array( - 'xml' => "application/xml, text/xml", - 'html' => "text/html", - 'script' => "text/javascript, application/javascript", - 'json' => "application/json, text/javascript", - 'text' => "text/plain", - '_default' => "*/*" - ) - ); - public static $lastModified = null; - public static $active = 0; - public static $dumpCount = 0; - public static $enableCssShorthand = FALSE; - - - /** - * Multi-purpose function. - * Use pq() as shortcut. - * - * In below examples, $pq is any result of pq(); function. - * - * 1. Import markup into existing document (without any attaching): - * - Import into selected document: - * pq('
    ') // DOESNT accept text nodes at beginning of input string ! - * - Import into document with ID from $pq->getDocumentID(): - * pq('
    ', $pq->getDocumentID()) - * - Import into same document as DOMNode belongs to: - * pq('
    ', DOMNode) - * - Import into document from phpQuery object: - * pq('
    ', $pq) - * - * 2. Run query: - * - Run query on last selected document: - * pq('div.myClass') - * - Run query on document with ID from $pq->getDocumentID(): - * pq('div.myClass', $pq->getDocumentID()) - * - Run query on same document as DOMNode belongs to and use node(s)as root for query: - * pq('div.myClass', DOMNode) - * - Run query on document from phpQuery object - * and use object's stack as root node(s) for query: - * pq('div.myClass', $pq) - * - * @param string|DOMNode|DOMNodeList|array $arg1 HTML markup, CSS Selector, DOMNode or array of DOMNodes - * @param string|phpQueryObject|DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or DOMNode (determines also query root) - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false - * phpQuery object or false in case of error. - */ - public static function pq($arg1, $context = null) { - if ($arg1 instanceof DOMNODE && ! isset($context)) { - foreach(phpQuery::$documents as $documentWrapper) { - $compare = $arg1 instanceof DOMDocument - ? $arg1 : $arg1->ownerDocument; - if ($documentWrapper->document->isSameNode($compare)) - $context = $documentWrapper->id; - } - } - if (! $context) { - $domId = self::$defaultDocumentID; - if (! $domId) - throw new Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); -// } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'phpQueryObject'))) - } else if (is_object($context) && $context instanceof phpQueryObject) - $domId = $context->getDocumentID(); - else if ($context instanceof DOMDOCUMENT) { - $domId = self::getDocumentID($context); - if (! $domId) { - //throw new Exception('Orphaned DOMDocument'); - $domId = self::newDocument($context)->getDocumentID(); - } - } else if ($context instanceof DOMNODE) { - $domId = self::getDocumentID($context); - if (! $domId) { - throw new Exception('Orphaned DOMNode'); -// $domId = self::newDocument($context->ownerDocument); - } - } else - $domId = $context; - if ($arg1 instanceof phpQueryObject) { -// if (is_object($arg1) && (get_class($arg1) == 'phpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'phpQueryObject'))) { - /** - * Return $arg1 or import $arg1 stack if document differs: - * pq(pq('
    ')) - */ - if ($arg1->getDocumentID() == $domId) - return $arg1; - $class = get_class($arg1); - // support inheritance by passing old object to overloaded constructor - $phpQuery = $class != 'phpQuery' - ? new $class($arg1, $domId) - : new phpQueryObject($domId); - $phpQuery->elements = array(); - foreach($arg1->elements as $node) - $phpQuery->elements[] = $phpQuery->document->importNode($node, true); - return $phpQuery; - } else if ($arg1 instanceof DOMNODE || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof DOMNODE)) { - /* - * Wrap DOM nodes with phpQuery object, import into document when needed: - * pq(array($domNode1, $domNode2)) - */ - $phpQuery = new phpQueryObject($domId); - if (!($arg1 instanceof DOMNODELIST) && ! is_array($arg1)) - $arg1 = array($arg1); - $phpQuery->elements = array(); - foreach($arg1 as $node) { - $sameDocument = $node->ownerDocument instanceof DOMDOCUMENT - && ! $node->ownerDocument->isSameNode($phpQuery->document); - $phpQuery->elements[] = $sameDocument - ? $phpQuery->document->importNode($node, true) - : $node; - } - return $phpQuery; - } else if (self::isMarkup($arg1)) { - /** - * Import HTML: - * pq('
    ') - */ - $phpQuery = new phpQueryObject($domId); - return $phpQuery->newInstance( - $phpQuery->documentWrapper->import($arg1) - ); - } else { - /** - * Run CSS query: - * pq('div.myClass') - */ - $phpQuery = new phpQueryObject($domId); -// if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'phpQueryObject'))) - if ($context && $context instanceof phpQueryObject) - $phpQuery->elements = $context->elements; - else if ($context && $context instanceof DOMNODELIST) { - $phpQuery->elements = array(); - foreach($context as $node) - $phpQuery->elements[] = $node; - } else if ($context && $context instanceof DOMNODE) - $phpQuery->elements = array($context); - return $phpQuery->find($arg1); - } - } - /** - * Sets default document to $id. Document has to be loaded prior - * to using this method. - * $id can be retrived via getDocumentID() or getDocumentIDRef(). - * - * @param unknown_type $id - */ - public static function selectDocument($id) { - $id = self::getDocumentID($id); - self::debug("Selecting document '$id' as default one"); - self::$defaultDocumentID = self::getDocumentID($id); - } - /** - * Returns document with id $id or last used as phpQueryObject. - * $id can be retrived via getDocumentID() or getDocumentIDRef(). - * Chainable. - * - * @see phpQuery::selectDocument() - * @param unknown_type $id - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function getDocument($id = null) { - if ($id) - phpQuery::selectDocument($id); - else - $id = phpQuery::$defaultDocumentID; - return new phpQueryObject($id); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocument($markup = null, $contentType = null) { - if (! $markup) - $markup = ''; - $documentID = phpQuery::createDocumentWrapper($markup, $contentType); - return new phpQueryObject($documentID); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentHTML($markup = null, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocument($markup, "text/html{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentXML($markup = null, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocument($markup, "text/xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentXHTML($markup = null, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocument($markup, "application/xhtml+xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentPHP($markup = null, $contentType = "text/html") { - // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function) - $markup = phpQuery::phpToMarkup($markup, self::$defaultCharset); - return self::newDocument($markup, $contentType); - } - public static function phpToMarkup($php, $charset = 'utf-8') { - $regexes = array( - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<'.'?php?(.*?)(?:\\?>)([^\']*)\'@s', - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<'.'?php?(.*?)(?:\\?>)([^"]*)"@s', - ); - foreach($regexes as $regex) - while (preg_match($regex, $php, $matches)) { - $php = preg_replace_callback( - $regex, -// create_function('$m, $charset = "'.$charset.'"', -// 'return $m[1].$m[2] -// .htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset) -// .$m[5].$m[2];' -// ), - array('phpQuery', '_phpToMarkupCallback'), - $php - ); - } - $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s'; -//preg_match_all($regex, $php, $matches); -//var_dump($matches); - $php = preg_replace($regex, '\\1', $php); - return $php; - } - public static function _phpToMarkupCallback($php, $charset = 'utf-8') { - return $m[1].$m[2] - .htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset) - .$m[5].$m[2]; - } - public static function _markupToPHPCallback($m) { - return "<"."?php ".htmlspecialchars_decode($m[1])." ?".">"; - } - /** - * Converts document markup containing PHP code generated by phpQuery::php() - * into valid (executable) PHP code syntax. - * - * @param string|phpQueryObject $content - * @return string PHP code. - */ - public static function markupToPHP($content) { - if ($content instanceof phpQueryObject) - $content = $content->markupOuter(); - /* ... to */ - $content = preg_replace_callback( - '@\s*\s*@s', -// create_function('$m', -// 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";' -// ), - array('phpQuery', '_markupToPHPCallback'), - $content - ); - /* extra space added to save highlighters */ - $regexes = array( - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^\']*)\'@s', - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^"]*)"@s', - ); - foreach($regexes as $regex) - while (preg_match($regex, $content)) - $content = preg_replace_callback( - $regex, - create_function('$m', - 'return $m[1].$m[2].$m[3]."", " ", "\n", " ", "{", "$", "}", \'"\', "[", "]"), - htmlspecialchars_decode($m[4]) - ) - ." ?>".$m[5].$m[2];' - ), - $content - ); - return $content; - } - /** - * Creates new document from file $file. - * Chainable. - * - * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources. - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFile($file, $contentType = null) { - $documentID = self::createDocumentWrapper( - file_get_contents($file), $contentType - ); - return new phpQueryObject($documentID); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileHTML($file, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocumentFile($file, "text/html{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileXML($file, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocumentFile($file, "text/xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileXHTML($file, $charset = null) { - $contentType = $charset - ? ";charset=$charset" - : ''; - return self::newDocumentFile($file, "application/xhtml+xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFilePHP($file, $contentType = null) { - return self::newDocumentPHP(file_get_contents($file), $contentType); - } - /** - * Reuses existing DOMDocument object. - * Chainable. - * - * @param $document DOMDocument - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support DOMDocument - */ - public static function loadDocument($document) { - // TODO - die('TODO loadDocument'); - } - /** - * Enter description here... - * - * @param unknown_type $html - * @param unknown_type $domId - * @return unknown New DOM ID - * @todo support PHP tags in input - * @todo support passing DOMDocument object from self::loadDocument - */ - protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) { - if (function_exists('domxml_open_mem')) - throw new Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); -// $id = $documentID -// ? $documentID -// : md5(microtime()); - $document = null; - if ($html instanceof DOMDOCUMENT) { - if (self::getDocumentID($html)) { - // document already exists in phpQuery::$documents, make a copy - $document = clone $html; - } else { - // new document, add it to phpQuery::$documents - $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); - } - } else { - $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); - } -// $wrapper->id = $id; - // bind document - phpQuery::$documents[$wrapper->id] = $wrapper; - // remember last loaded document - phpQuery::selectDocument($wrapper->id); - return $wrapper->id; - } - /** - * Extend class namespace. - * - * @param string|array $target - * @param array $source - * @TODO support string $source - * @return unknown_type - */ - public static function extend($target, $source) { - switch($target) { - case 'phpQueryObject': - $targetRef = &self::$extendMethods; - $targetRef2 = &self::$pluginsMethods; - break; - case 'phpQuery': - $targetRef = &self::$extendStaticMethods; - $targetRef2 = &self::$pluginsStaticMethods; - break; - default: - throw new Exception("Unsupported \$target type"); - } - if (is_string($source)) - $source = array($source => $source); - foreach($source as $method => $callback) { - if (isset($targetRef[$method])) { -// throw new Exception - self::debug("Duplicate method '{$method}', can\'t extend '{$target}'"); - continue; - } - if (isset($targetRef2[$method])) { -// throw new Exception - self::debug("Duplicate method '{$method}' from plugin '{$targetRef2[$method]}'," - ." can\'t extend '{$target}'"); - continue; - } - $targetRef[$method] = $callback; - } - return true; - } - /** - * Extend phpQuery with $class from $file. - * - * @param string $class Extending class name. Real class name can be prepended phpQuery_. - * @param string $file Filename to include. Defaults to "{$class}.php". - */ - public static function plugin($class, $file = null) { - // TODO $class checked agains phpQuery_$class -// if (strpos($class, 'phpQuery') === 0) -// $class = substr($class, 8); - if (in_array($class, self::$pluginsLoaded)) - return true; - if (! $file) - $file = $class.'.php'; - $objectClassExists = class_exists('phpQueryObjectPlugin_'.$class); - $staticClassExists = class_exists('phpQueryPlugin_'.$class); - if (! $objectClassExists && ! $staticClassExists) - require_once($file); - self::$pluginsLoaded[] = $class; - // static methods - if (class_exists('phpQueryPlugin_'.$class)) { - $realClass = 'phpQueryPlugin_'.$class; - $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && ! is_null($vars['phpQueryMethods']) - ? $vars['phpQueryMethods'] - : get_class_methods($realClass); - foreach($loop as $method) { - if ($method == '__initialize') - continue; - if (! is_callable(array($realClass, $method))) - continue; - if (isset(self::$pluginsStaticMethods[$method])) { - throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '".self::$pluginsStaticMethods[$method]."'"); - return; - } - self::$pluginsStaticMethods[$method] = $class; - } - if (method_exists($realClass, '__initialize')) - call_user_func_array(array($realClass, '__initialize'), array()); - } - // object methods - if (class_exists('phpQueryObjectPlugin_'.$class)) { - $realClass = 'phpQueryObjectPlugin_'.$class; - $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && ! is_null($vars['phpQueryMethods']) - ? $vars['phpQueryMethods'] - : get_class_methods($realClass); - foreach($loop as $method) { - if (! is_callable(array($realClass, $method))) - continue; - if (isset(self::$pluginsMethods[$method])) { - throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '".self::$pluginsMethods[$method]."'"); - continue; - } - self::$pluginsMethods[$method] = $class; - } - } - return true; - } - /** - * Unloades all or specified document from memory. - * - * @param mixed $documentID @see phpQuery::getDocumentID() for supported types. - */ - public static function unloadDocuments($id = null) { - if (isset($id)) { - if ($id = self::getDocumentID($id)) - unset(phpQuery::$documents[$id]); - } else { - foreach(phpQuery::$documents as $k => $v) { - unset(phpQuery::$documents[$k]); - } - } - } - /** - * Parses phpQuery object or HTML result against PHP tags and makes them active. - * - * @param phpQuery|string $content - * @deprecated - * @return string - */ - public static function unsafePHPTags($content) { - return self::markupToPHP($content); - } - public static function DOMNodeListToArray($DOMNodeList) { - $array = array(); - if (! $DOMNodeList) - return $array; - foreach($DOMNodeList as $node) - $array[] = $node; - return $array; - } - /** - * Checks if $input is HTML string, which has to start with '<'. - * - * @deprecated - * @param String $input - * @return Bool - * @todo still used ? - */ - public static function isMarkup($input) { - return ! is_array($input) && substr(trim($input), 0, 1) == '<'; - } - public static function debug($text) { - if (self::$debug) - print var_dump($text); - } - /** - * Make an AJAX request. - * - * @param array See $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions - * Additional options are: - * 'document' - document for global events, @see phpQuery::getDocumentID() - * 'referer' - implemented - * 'requested_with' - TODO; not implemented (X-Requested-With) - * @return Zend_Http_Client - * @link http://docs.jquery.com/Ajax/jQuery.ajax - * - * @TODO $options['cache'] - * @TODO $options['processData'] - * @TODO $options['xhr'] - * @TODO $options['data'] as string - * @TODO XHR interface - */ - public static function ajax($options = array(), $xhr = null) { - $options = array_merge( - self::$ajaxSettings, $options - ); - $documentID = isset($options['document']) - ? self::getDocumentID($options['document']) - : null; - if ($xhr) { - // reuse existing XHR object, but clean it up - $client = $xhr; -// $client->setParameterPost(null); -// $client->setParameterGet(null); - $client->setAuth(false); - $client->setHeaders("If-Modified-Since", null); - $client->setHeaders("Referer", null); - $client->resetParameters(); - } else { - // create new XHR object - require_once('Zend/Http/Client.php'); - $client = new Zend_Http_Client(); - $client->setCookieJar(); - } - if (isset($options['timeout'])) - $client->setConfig(array( - 'timeout' => $options['timeout'], - )); -// 'maxredirects' => 0, - foreach(self::$ajaxAllowedHosts as $k => $host) - if ($host == '.' && isset($_SERVER['HTTP_HOST'])) - self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST']; - $host = parse_url($options['url'], PHP_URL_HOST); - if (! in_array($host, self::$ajaxAllowedHosts)) { - throw new Exception("Request not permitted, host '$host' not present in " - ."phpQuery::\$ajaxAllowedHosts"); - } - // JSONP - $jsre = "/=\\?(&|$)/"; - if (isset($options['dataType']) && $options['dataType'] == 'jsonp') { - $jsonpCallbackParam = $options['jsonp'] - ? $options['jsonp'] : 'callback'; - if (strtolower($options['type']) == 'get') { - if (! preg_match($jsre, $options['url'])) { - $sep = strpos($options['url'], '?') - ? '&' : '?'; - $options['url'] .= "$sep$jsonpCallbackParam=?"; - } - } else if ($options['data']) { - $jsonp = false; - foreach($options['data'] as $n => $v) { - if ($v == '?') - $jsonp = true; - } - if (! $jsonp) { - $options['data'][$jsonpCallbackParam] = '?'; - } - } - $options['dataType'] = 'json'; - } - if (isset($options['dataType']) && $options['dataType'] == 'json') { - $jsonpCallback = 'json_'.md5(microtime()); - $jsonpData = $jsonpUrl = false; - if ($options['data']) { - foreach($options['data'] as $n => $v) { - if ($v == '?') - $jsonpData = $n; - } - } - if (preg_match($jsre, $options['url'])) - $jsonpUrl = true; - if ($jsonpData !== false || $jsonpUrl) { - // remember callback name for httpData() - $options['_jsonp'] = $jsonpCallback; - if ($jsonpData !== false) - $options['data'][$jsonpData] = $jsonpCallback; - if ($jsonpUrl) - $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']); - } - } - $client->setUri($options['url']); - $client->setMethod(strtoupper($options['type'])); - if (isset($options['referer']) && $options['referer']) - $client->setHeaders('Referer', $options['referer']); - $client->setHeaders(array( -// 'content-type' => $options['contentType'], - 'User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko' - .'/2008122010 Firefox/3.0.5', - // TODO custom charset - 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', -// 'Connection' => 'keep-alive', -// 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'Accept-Language' => 'en-us,en;q=0.5', - )); - if ($options['username']) - $client->setAuth($options['username'], $options['password']); - if (isset($options['ifModified']) && $options['ifModified']) - $client->setHeaders("If-Modified-Since", - self::$lastModified - ? self::$lastModified - : "Thu, 01 Jan 1970 00:00:00 GMT" - ); - $client->setHeaders("Accept", - isset($options['dataType']) - && isset(self::$ajaxSettings['accepts'][ $options['dataType'] ]) - ? self::$ajaxSettings['accepts'][ $options['dataType'] ].", */*" - : self::$ajaxSettings['accepts']['_default'] - ); - // TODO $options['processData'] - if ($options['data'] instanceof phpQueryObject) { - $serialized = $options['data']->serializeArray($options['data']); - $options['data'] = array(); - foreach($serialized as $r) - $options['data'][ $r['name'] ] = $r['value']; - } - if (strtolower($options['type']) == 'get') { - $client->setParameterGet($options['data']); - } else if (strtolower($options['type']) == 'post') { - $client->setEncType($options['contentType']); - $client->setParameterPost($options['data']); - } - if (self::$active == 0 && $options['global']) - phpQueryEvents::trigger($documentID, 'ajaxStart'); - self::$active++; - // beforeSend callback - if (isset($options['beforeSend']) && $options['beforeSend']) - phpQuery::callbackRun($options['beforeSend'], array($client)); - // ajaxSend event - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxSend', array($client, $options)); - if (phpQuery::$debug) { - self::debug("{$options['type']}: {$options['url']}\n"); - self::debug("Options:
    ".var_export($options, true)."
    \n"); -// if ($client->getCookieJar()) -// self::debug("Cookies:
    ".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."
    \n"); - } - // request - $response = $client->request(); - if (phpQuery::$debug) { - self::debug('Status: '.$response->getStatus().' / '.$response->getMessage()); - self::debug($client->getLastRequest()); - self::debug($response->getHeaders()); - } - if ($response->isSuccessful()) { - // XXX tempolary - self::$lastModified = $response->getHeader('Last-Modified'); - $data = self::httpData($response->getBody(), $options['dataType'], $options); - if (isset($options['success']) && $options['success']) - phpQuery::callbackRun($options['success'], array($data, $response->getStatus(), $options)); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxSuccess', array($client, $options)); - } else { - if (isset($options['error']) && $options['error']) - phpQuery::callbackRun($options['error'], array($client, $response->getStatus(), $response->getMessage())); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxError', array($client, /*$response->getStatus(),*/$response->getMessage(), $options)); - } - if (isset($options['complete']) && $options['complete']) - phpQuery::callbackRun($options['complete'], array($client, $response->getStatus())); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxComplete', array($client, $options)); - if ($options['global'] && ! --self::$active) - phpQueryEvents::trigger($documentID, 'ajaxStop'); - return $client; -// if (is_null($domId)) -// $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; -// return new phpQueryAjaxResponse($response, $domId); - } - protected static function httpData($data, $type, $options) { - if (isset($options['dataFilter']) && $options['dataFilter']) - $data = self::callbackRun($options['dataFilter'], array($data, $type)); - if (is_string($data)) { - if ($type == "json") { - if (isset($options['_jsonp']) && $options['_jsonp']) { - $data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data); - } - $data = self::parseJSON($data); - } - } - return $data; - } - /** - * Enter description here... - * - * @param array|phpQuery $data - * - */ - public static function param($data) { - return http_build_query($data, null, '&'); - } - public static function get($url, $data = null, $callback = null, $type = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; - } - // TODO some array_values on this shit - return phpQuery::ajax(array( - 'type' => 'GET', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => $type, - )); - } - public static function post($url, $data = null, $callback = null, $type = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; - } - return phpQuery::ajax(array( - 'type' => 'POST', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => $type, - )); - } - public static function getJSON($url, $data = null, $callback = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; - } - // TODO some array_values on this shit - return phpQuery::ajax(array( - 'type' => 'GET', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => 'json', - )); - } - public static function ajaxSetup($options) { - self::$ajaxSettings = array_merge( - self::$ajaxSettings, - $options - ); - } - public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) { - $loop = is_array($host1) - ? $host1 - : func_get_args(); - foreach($loop as $host) { - if ($host && ! in_array($host, phpQuery::$ajaxAllowedHosts)) { - phpQuery::$ajaxAllowedHosts[] = $host; - } - } - } - public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) { - $loop = is_array($url1) - ? $url1 - : func_get_args(); - foreach($loop as $url) - phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); - } - /** - * Returns JSON representation of $data. - * - * @static - * @param mixed $data - * @return string - */ - public static function toJSON($data) { - if (function_exists('json_encode')) - return json_encode($data); - require_once('Zend/Json/Encoder.php'); - return Zend_Json_Encoder::encode($data); - } - /** - * Parses JSON into proper PHP type. - * - * @static - * @param string $json - * @return mixed - */ - public static function parseJSON($json) { - if (function_exists('json_decode')) { - $return = json_decode(trim($json), true); - // json_decode and UTF8 issues - if (isset($return)) - return $return; - } - require_once('Zend/Json/Decoder.php'); - return Zend_Json_Decoder::decode($json); - } - /** - * Returns source's document ID. - * - * @param $source DOMNode|phpQueryObject - * @return string - */ - public static function getDocumentID($source) { - if ($source instanceof DOMDOCUMENT) { - foreach(phpQuery::$documents as $id => $document) { - if ($source->isSameNode($document->document)) - return $id; - } - } else if ($source instanceof DOMNODE) { - foreach(phpQuery::$documents as $id => $document) { - if ($source->ownerDocument->isSameNode($document->document)) - return $id; - } - } else if ($source instanceof phpQueryObject) - return $source->getDocumentID(); - else if (is_string($source) && isset(phpQuery::$documents[$source])) - return $source; - } - /** - * Get DOMDocument object related to $source. - * Returns null if such document doesn't exist. - * - * @param $source DOMNode|phpQueryObject|string - * @return string - */ - public static function getDOMDocument($source) { - if ($source instanceof DOMDOCUMENT) - return $source; - $source = self::getDocumentID($source); - return $source - ? self::$documents[$id]['document'] - : null; - } - - // UTILITIES - // http://docs.jquery.com/Utilities - - /** - * - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.makeArray - */ - public static function makeArray($object) { - $array = array(); - if (is_object($object) && $object instanceof DOMNODELIST) { - foreach($object as $value) - $array[] = $value; - } else if (is_object($object) && ! ($object instanceof Iterator)) { - foreach(get_object_vars($object) as $name => $value) - $array[0][$name] = $value; - } else { - foreach($object as $name => $value) - $array[0][$name] = $value; - } - return $array; - } - public static function inArray($value, $array) { - return in_array($value, $array); - } - /** - * - * @param $object - * @param $callback - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.each - */ - public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null) { - $paramStructure = null; - if (func_num_args() > 2) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 2); - } - if (is_object($object) && ! ($object instanceof Iterator)) { - foreach(get_object_vars($object) as $name => $value) - phpQuery::callbackRun($callback, array($name, $value), $paramStructure); - } else { - foreach($object as $name => $value) - phpQuery::callbackRun($callback, array($name, $value), $paramStructure); - } - } - /** - * - * @link http://docs.jquery.com/Utilities/jQuery.map - */ - public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null) { - $result = array(); - $paramStructure = null; - if (func_num_args() > 2) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 2); - } - foreach($array as $v) { - $vv = phpQuery::callbackRun($callback, array($v), $paramStructure); -// $callbackArgs = $args; -// foreach($args as $i => $arg) { -// $callbackArgs[$i] = $arg instanceof CallbackParam -// ? $v -// : $arg; -// } -// $vv = call_user_func_array($callback, $callbackArgs); - if (is_array($vv)) { - foreach($vv as $vvv) - $result[] = $vvv; - } else if ($vv !== null) { - $result[] = $vv; - } - } - return $result; - } - /** - * - * @param $callback Callback - * @param $params - * @param $paramStructure - * @return unknown_type - */ - public static function callbackRun($callback, $params = array(), $paramStructure = null) { - if (! $callback) - return; - if ($callback instanceof CallbackParameterToReference) { - // TODO support ParamStructure to select which $param push to reference - if (isset($params[0])) - $callback->callback = $params[0]; - return true; - } - if ($callback instanceof Callback) { - $paramStructure = $callback->params; - $callback = $callback->callback; - } - if (! $paramStructure) - return call_user_func_array($callback, $params); - $p = 0; - foreach($paramStructure as $i => $v) { - $paramStructure[$i] = $v instanceof CallbackParam - ? $params[$p++] - : $v; - } - return call_user_func_array($callback, $paramStructure); - } - /** - * Merge 2 phpQuery objects. - * @param array $one - * @param array $two - * @protected - * @todo node lists, phpQueryObject - */ - public static function merge($one, $two) { - $elements = $one->elements; - foreach($two->elements as $node) { - $exists = false; - foreach($elements as $node2) { - if ($node2->isSameNode($node)) - $exists = true; - } - if (! $exists) - $elements[] = $node; - } - return $elements; -// $one = $one->newInstance(); -// $one->elements = $elements; -// return $one; - } - /** - * - * @param $array - * @param $callback - * @param $invert - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.grep - */ - public static function grep($array, $callback, $invert = false) { - $result = array(); - foreach($array as $k => $v) { - $r = call_user_func_array($callback, array($v, $k)); - if ($r === !(bool)$invert) - $result[] = $v; - } - return $result; - } - public static function unique($array) { - return array_unique($array); - } - /** - * - * @param $function - * @return unknown_type - * @TODO there are problems with non-static methods, second parameter pass it - * but doesnt verify is method is really callable - */ - public static function isFunction($function) { - return is_callable($function); - } - public static function trim($str) { - return trim($str); - } - /* PLUGINS NAMESPACE */ - /** - * - * @param $url - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return phpQueryObject - */ - public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array(self::$plugins, 'browserGet'), $params); - } else { - self::debug('WebBrowser plugin not available...'); - } - } - /** - * - * @param $url - * @param $data - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return phpQueryObject - */ - public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array(self::$plugins, 'browserPost'), $params); - } else { - self::debug('WebBrowser plugin not available...'); - } - } - /** - * - * @param $ajaxSettings - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return phpQueryObject - */ - public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array(self::$plugins, 'browser'), $params); - } else { - self::debug('WebBrowser plugin not available...'); - } - } - /** - * - * @param $code - * @return string - */ - public static function php($code) { - return self::code('php', $code); - } - /** - * - * @param $type - * @param $code - * @return string - */ - public static function code($type, $code) { - return "<$type>"; - } - - public static function __callStatic($method, $params) { - return call_user_func_array( - array(phpQuery::$plugins, $method), - $params - ); - } - protected static function dataSetupNode($node, $documentID) { - // search are return if alredy exists - foreach(phpQuery::$documents[$documentID]->dataNodes as $dataNode) { - if ($node->isSameNode($dataNode)) - return $dataNode; - } - // if doesn't, add it - phpQuery::$documents[$documentID]->dataNodes[] = $node; - return $node; - } - protected static function dataRemoveNode($node, $documentID) { - // search are return if alredy exists - foreach(phpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { - if ($node->isSameNode($dataNode)) { - unset(self::$documents[$documentID]->dataNodes[$k]); - unset(self::$documents[$documentID]->data[ $dataNode->dataID ]); - } - } - } - public static function data($node, $name, $data, $documentID = null) { - if (! $documentID) - // TODO check if this works - $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; - $node = self::dataSetupNode($node, $documentID); - if (! isset($node->dataID)) - $node->dataID = ++phpQuery::$documents[$documentID]->uuid; - $id = $node->dataID; - if (! isset($document->data[$id])) - $document->data[$id] = array(); - if (! is_null($data)) - $document->data[$id][$name] = $data; - if ($name) { - if (isset($document->data[$id][$name])) - return $document->data[$id][$name]; - } else - return $id; - } - public static function removeData($node, $name, $documentID) { - if (! $documentID) - // TODO check if this works - $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; - $node = self::dataSetupNode($node, $documentID); - $id = $node->dataID; - if ($name) { - if (isset($document->data[$id][$name])) - unset($document->data[$id][$name]); - $name = null; - foreach($document->data[$id] as $name) - break; - if (! $name) - self::removeData($node, $name, $documentID); - } else { - self::dataRemoveNode($node, $documentID); - } - } -} -/** - * Plugins static namespace class. - * - * @author Tobiasz Cudnik - * @package phpQuery - * @todo move plugin methods here (as statics) - */ -class phpQueryPlugins { - public function __call($method, $args) { - if (isset(phpQuery::$extendStaticMethods[$method])) { - $return = call_user_func_array( - phpQuery::$extendStaticMethods[$method], - $args - ); - } else if (isset(phpQuery::$pluginsStaticMethods[$method])) { - $class = phpQuery::$pluginsStaticMethods[$method]; - $realClass = "phpQueryPlugin_$class"; - $return = call_user_func_array( - array($realClass, $method), - $args - ); - return isset($return) - ? $return - : $this; - } else - throw new Exception("Method '{$method}' doesnt exist"); - } -} -/** - * Shortcut to phpQuery::pq($arg1, $context) - * Chainable. - * - * @see phpQuery::pq() - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @author Tobiasz Cudnik - * @package phpQuery - */ -function pq($arg1, $context = null) { - $args = func_get_args(); - return call_user_func_array( - array('phpQuery', 'pq'), - $args - ); -} -// add plugins dir and Zend framework to include path -set_include_path( - get_include_path() - .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/' - .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/plugins/' -); -// why ? no __call nor __get for statics in php... -// XXX __callStatic will be available in PHP 5.3 -phpQuery::$plugins = new phpQueryPlugins(); -// include bootstrap file (personal library config) -if (file_exists(dirname(__FILE__).'/phpQuery/bootstrap.php')) - require_once dirname(__FILE__).'/phpQuery/bootstrap.php'; \ No newline at end of file diff --git a/phpQuery/phpQuery/DOMDocumentWrapper.php b/phpQuery/phpQuery/DOMDocumentWrapper.php deleted file mode 100644 index aae5ee0..0000000 --- a/phpQuery/phpQuery/DOMDocumentWrapper.php +++ /dev/null @@ -1,679 +0,0 @@ - changes to
    - * - * @todo check XML catalogs compatibility - * @author Tobiasz Cudnik - * @package phpQuery - */ -class DOMDocumentWrapper { - /** - * @var DOMDocument - */ - public $document; - public $id; - /** - * @todo Rewrite as method and quess if null. - * @var unknown_type - */ - public $contentType = ''; - public $xpath; - public $uuid = 0; - public $data = array(); - public $dataNodes = array(); - public $events = array(); - public $eventsNodes = array(); - public $eventsGlobal = array(); - /** - * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28 - * @var unknown_type - */ - public $frames = array(); - /** - * Document root, by default equals to document itself. - * Used by documentFragments. - * - * @var DOMNode - */ - public $root; - public $isDocumentFragment; - public $isXML = false; - public $isXHTML = false; - public $isHTML = false; - public $charset; - public function __construct($markup = null, $contentType = null, $newDocumentID = null) { - if (isset($markup)) - $this->load($markup, $contentType, $newDocumentID); - $this->id = $newDocumentID - ? $newDocumentID - : md5(microtime()); - } - public function load($markup, $contentType = null, $newDocumentID = null) { -// phpQuery::$documents[$id] = $this; - $this->contentType = strtolower($contentType); - if ($markup instanceof DOMDOCUMENT) { - $this->document = $markup; - $this->root = $this->document; - $this->charset = $this->document->encoding; - // TODO isDocumentFragment - $loaded = true; - } else { - $loaded = $this->loadMarkup($markup); - } - if ($loaded) { -// $this->document->formatOutput = true; - $this->document->preserveWhiteSpace = true; - $this->xpath = new DOMXPath($this->document); - $this->afterMarkupLoad(); - return true; - // remember last loaded document -// return phpQuery::selectDocument($id); - } - return false; - } - protected function afterMarkupLoad() { - if ($this->isXHTML) { - $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml"); - } - } - protected function loadMarkup($markup) { - $loaded = false; - if ($this->contentType) { - self::debug("Load markup for content type {$this->contentType}"); - // content determined by contentType - list($contentType, $charset) = $this->contentTypeToArray($this->contentType); - switch($contentType) { - case 'text/html': - phpQuery::debug("Loading HTML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupHTML($markup, $charset); - break; - case 'text/xml': - case 'application/xhtml+xml': - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupXML($markup, $charset); - break; - default: - // for feeds or anything that sometimes doesn't use text/xml - if (strpos('xml', $this->contentType) !== false) { - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupXML($markup, $charset); - } else - phpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); - } - } else { - // content type autodetection - if ($this->isXML($markup)) { - phpQuery::debug("Loading XML, isXML() == true"); - $loaded = $this->loadMarkupXML($markup); - if (! $loaded && $this->isXHTML) { - phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); - $loaded = $this->loadMarkupHTML($markup); - } - } else { - phpQuery::debug("Loading HTML, isXML() == false"); - $loaded = $this->loadMarkupHTML($markup); - } - } - return $loaded; - } - protected function loadMarkupReset() { - $this->isXML = $this->isXHTML = $this->isHTML = false; - } - protected function documentCreate($charset, $version = '1.0') { - if (! $version) - $version = '1.0'; - $this->document = new DOMDocument($version, $charset); - $this->charset = $this->document->encoding; -// $this->document->encoding = $charset; - $this->document->formatOutput = true; - $this->document->preserveWhiteSpace = true; - } - protected function loadMarkupHTML($markup, $requestedCharset = null) { - if (phpQuery::$debug) - phpQuery::debug('Full markup load (HTML): '.substr($markup, 0, 250)); - $this->loadMarkupReset(); - $this->isHTML = true; - if (!isset($this->isDocumentFragment)) - $this->isDocumentFragment = self::isDocumentFragmentHTML($markup); - $charset = null; - $documentCharset = $this->charsetFromHTML($markup); - $addDocumentCharset = false; - if ($documentCharset) { - $charset = $documentCharset; - $markup = $this->charsetFixHTML($markup); - } else if ($requestedCharset) { - $charset = $requestedCharset; - } - if (! $charset) - $charset = phpQuery::$defaultCharset; - // HTTP 1.1 says that the default charset is ISO-8859-1 - // @see http://www.w3.org/International/O-HTTP-charset - if (! $documentCharset) { - $documentCharset = 'ISO-8859-1'; - $addDocumentCharset = true; - } - // Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding' - // Worse, some pages can have mixed encodings... we'll try not to worry about that - $requestedCharset = strtoupper($requestedCharset); - $documentCharset = strtoupper($documentCharset); - phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); - if ($requestedCharset && $documentCharset && $requestedCharset !== $documentCharset) { - phpQuery::debug("CHARSET CONVERT"); - // Document Encoding Conversion - // http://code.google.com/p/phpquery/issues/detail?id=86 - if (function_exists('mb_detect_encoding')) { - $possibleCharsets = array($documentCharset, $requestedCharset, 'AUTO'); - $docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets)); - if (! $docEncoding) - $docEncoding = $documentCharset; // ok trust the document - phpQuery::debug("DETECTED '$docEncoding'"); - // Detected does not match what document says... - if ($docEncoding !== $documentCharset) { - // Tricky.. - } - if ($docEncoding !== $requestedCharset) { - phpQuery::debug("CONVERT $docEncoding => $requestedCharset"); - $markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding); - $markup = $this->charsetAppendToHTML($markup, $requestedCharset); - $charset = $requestedCharset; - } - } else { - phpQuery::debug("TODO: charset conversion without mbstring..."); - } - } - $return = false; - if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); - $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); - } else { - if ($addDocumentCharset) { - phpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); - $markup = $this->charsetAppendToHTML($markup, $charset); - } - phpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); - $this->documentCreate($charset); - $return = phpQuery::$debug === 2 - ? $this->document->loadHTML($markup) - : @$this->document->loadHTML($markup); - if ($return) - $this->root = $this->document; - } - if ($return && ! $this->contentType) - $this->contentType = 'text/html'; - return $return; - } - protected function loadMarkupXML($markup, $requestedCharset = null) { - if (phpQuery::$debug) - phpQuery::debug('Full markup load (XML): '.substr($markup, 0, 250)); - $this->loadMarkupReset(); - $this->isXML = true; - // check agains XHTML in contentType or markup - $isContentTypeXHTML = $this->isXHTML(); - $isMarkupXHTML = $this->isXHTML($markup); - if ($isContentTypeXHTML || $isMarkupXHTML) { - self::debug('Full markup load (XML), XHTML detected'); - $this->isXHTML = true; - } - // determine document fragment - if (! isset($this->isDocumentFragment)) - $this->isDocumentFragment = $this->isXHTML - ? self::isDocumentFragmentXHTML($markup) - : self::isDocumentFragmentXML($markup); - // this charset will be used - $charset = null; - // charset from XML declaration @var string - $documentCharset = $this->charsetFromXML($markup); - if (! $documentCharset) { - if ($this->isXHTML) { - // this is XHTML, try to get charset from content-type meta header - $documentCharset = $this->charsetFromHTML($markup); - if ($documentCharset) { - phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); - $this->charsetAppendToXML($markup, $documentCharset); - $charset = $documentCharset; - } - } - if (! $documentCharset) { - // if still no document charset... - $charset = $requestedCharset; - } - } else if ($requestedCharset) { - $charset = $requestedCharset; - } - if (! $charset) { - $charset = phpQuery::$defaultCharset; - } - if ($requestedCharset && $documentCharset && $requestedCharset != $documentCharset) { - // TODO place for charset conversion -// $charset = $requestedCharset; - } - $return = false; - if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); - $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); - } else { - // FIXME ??? - if ($isContentTypeXHTML && ! $isMarkupXHTML) - if (! $documentCharset) { - phpQuery::debug("Full markup load (XML), appending charset '$charset'"); - $markup = $this->charsetAppendToXML($markup, $charset); - } - // see http://pl2.php.net/manual/en/book.dom.php#78929 - // LIBXML_DTDLOAD (>= PHP 5.1) - // does XML ctalogues works with LIBXML_NONET - // $this->document->resolveExternals = true; - // TODO test LIBXML_COMPACT for performance improvement - // create document - $this->documentCreate($charset); - if (phpversion() < 5.1) { - $this->document->resolveExternals = true; - $return = phpQuery::$debug === 2 - ? $this->document->loadXML($markup) - : @$this->document->loadXML($markup); - } else { - /** @link http://pl2.php.net/manual/en/libxml.constants.php */ - $libxmlStatic = phpQuery::$debug === 2 - ? LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET - : LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOERROR; - $return = $this->document->loadXML($markup, $libxmlStatic); -// if (! $return) -// $return = $this->document->loadHTML($markup); - } - if ($return) - $this->root = $this->document; - } - if ($return) { - if (! $this->contentType) { - if ($this->isXHTML) - $this->contentType = 'application/xhtml+xml'; - else - $this->contentType = 'text/xml'; - } - return $return; - } else { - throw new Exception("Error loading XML markup"); - } - } - protected function isXHTML($markup = null) { - if (! isset($markup)) { - return strpos($this->contentType, 'xhtml') !== false; - } - // XXX ok ? - return strpos($markup, "doctype) && is_object($dom->doctype) -// ? $dom->doctype->publicId -// : self::$defaultDoctype; - } - protected function isXML($markup) { -// return strpos($markup, ']+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', - $markup, $matches - ); - if (! isset($matches[0])) - return array(null, null); - // get attr 'content' - preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches); - if (! isset($matches[0])) - return array(null, null); - return $this->contentTypeToArray($matches[2]); - } - protected function charsetFromHTML($markup) { - $contentType = $this->contentTypeFromHTML($markup); - return $contentType[1]; - } - protected function charsetFromXML($markup) { - $matches = array(); - // find declaration - preg_match('@<'.'?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', - $markup, $matches - ); - return isset($matches[2]) - ? strtolower($matches[2]) - : null; - } - /** - * Repositions meta[type=charset] at the start of head. Bypasses DOMDocument bug. - * - * @link http://code.google.com/p/phpquery/issues/detail?id=80 - * @param $html - */ - protected function charsetFixHTML($markup) { - $matches = array(); - // find meta tag - preg_match('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', - $markup, $matches, PREG_OFFSET_CAPTURE - ); - if (! isset($matches[0])) - return; - $metaContentType = $matches[0][0]; - $markup = substr($markup, 0, $matches[0][1]) - .substr($markup, $matches[0][1]+strlen($metaContentType)); - $headStart = stripos($markup, ''); - $markup = substr($markup, 0, $headStart+6).$metaContentType - .substr($markup, $headStart+6); - return $markup; - } - protected function charsetAppendToHTML($html, $charset, $xhtml = false) { - // remove existing meta[type=content-type] - $html = preg_replace('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html); - $meta = ''; - if (strpos($html, ')@s', - "{$meta}", - $html - ); - } - } else { - return preg_replace( - '@)@s', - ''.$meta, - $html - ); - } - } - protected function charsetAppendToXML($markup, $charset) { - $declaration = '<'.'?xml version="1.0" encoding="'.$charset.'"?'.'>'; - return $declaration.$markup; - } - public static function isDocumentFragmentHTML($markup) { - return stripos($markup, 'documentFragmentCreate($node, $sourceCharset); -// if ($fake === false) -// throw new Exception("Error loading documentFragment markup"); -// else -// $return = array_merge($return, -// $this->import($fake->root->childNodes) -// ); -// } else { -// $return[] = $this->document->importNode($node, true); -// } -// } -// return $return; -// } else { -// // string markup -// $fake = $this->documentFragmentCreate($source, $sourceCharset); -// if ($fake === false) -// throw new Exception("Error loading documentFragment markup"); -// else -// return $this->import($fake->root->childNodes); -// } - if (is_array($source) || $source instanceof DOMNODELIST) { - // dom nodes - self::debug('Importing nodes to document'); - foreach($source as $node) - $return[] = $this->document->importNode($node, true); - } else { - // string markup - $fake = $this->documentFragmentCreate($source, $sourceCharset); - if ($fake === false) - throw new Exception("Error loading documentFragment markup"); - else - return $this->import($fake->root->childNodes); - } - return $return; - } - /** - * Creates new document fragment. - * - * @param $source - * @return DOMDocumentWrapper - */ - protected function documentFragmentCreate($source, $charset = null) { - $fake = new DOMDocumentWrapper(); - $fake->contentType = $this->contentType; - $fake->isXML = $this->isXML; - $fake->isHTML = $this->isHTML; - $fake->isXHTML = $this->isXHTML; - $fake->root = $fake->document; - if (! $charset) - $charset = $this->charset; -// $fake->documentCreate($this->charset); - if ($source instanceof DOMNODE && !($source instanceof DOMNODELIST)) - $source = array($source); - if (is_array($source) || $source instanceof DOMNODELIST) { - // dom nodes - // load fake document - if (! $this->documentFragmentLoadMarkup($fake, $charset)) - return false; - $nodes = $fake->import($source); - foreach($nodes as $node) - $fake->root->appendChild($node); - } else { - // string markup - $this->documentFragmentLoadMarkup($fake, $charset, $source); - } - return $fake; - } - /** - * - * @param $document DOMDocumentWrapper - * @param $markup - * @return $document - */ - private function documentFragmentLoadMarkup($fragment, $charset, $markup = null) { - // TODO error handling - // TODO copy doctype - // tempolary turn off - $fragment->isDocumentFragment = false; - if ($fragment->isXML) { - if ($fragment->isXHTML) { - // add FAKE element to set default namespace - $fragment->loadMarkupXML('' - .'' - .''.$markup.''); - $fragment->root = $fragment->document->firstChild->nextSibling; - } else { - $fragment->loadMarkupXML(''.$markup.''); - $fragment->root = $fragment->document->firstChild; - } - } else { - $markup2 = phpQuery::$defaultDoctype.''; - $noBody = strpos($markup, 'loadMarkupHTML($markup2); - // TODO resolv body tag merging issue - $fragment->root = $noBody - ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling - : $fragment->document->firstChild->nextSibling->firstChild->nextSibling; - } - if (! $fragment->root) - return false; - $fragment->isDocumentFragment = true; - return true; - } - protected function documentFragmentToMarkup($fragment) { - phpQuery::debug('documentFragmentToMarkup'); - $tmp = $fragment->isDocumentFragment; - $fragment->isDocumentFragment = false; - $markup = $fragment->markup(); - if ($fragment->isXML) { - $markup = substr($markup, 0, strrpos($markup, '')); - if ($fragment->isXHTML) { - $markup = substr($markup, strpos($markup, '')+6); - } - } else { - $markup = substr($markup, strpos($markup, '')+6); - $markup = substr($markup, 0, strrpos($markup, '')); - } - $fragment->isDocumentFragment = $tmp; - if (phpQuery::$debug) - phpQuery::debug('documentFragmentToMarkup: '.substr($markup, 0, 150)); - return $markup; - } - /** - * Return document markup, starting with optional $nodes as root. - * - * @param $nodes DOMNode|DOMNodeList - * @return string - */ - public function markup($nodes = null, $innerMarkup = false) { - if (isset($nodes) && count($nodes) == 1 && $nodes[0] instanceof DOMDOCUMENT) - $nodes = null; - if (isset($nodes)) { - $markup = ''; - if (!is_array($nodes) && !($nodes instanceof DOMNODELIST) ) - $nodes = array($nodes); - if ($this->isDocumentFragment && ! $innerMarkup) - foreach($nodes as $i => $node) - if ($node->isSameNode($this->root)) { - // var_dump($node); - $nodes = array_slice($nodes, 0, $i) - + phpQuery::DOMNodeListToArray($node->childNodes) - + array_slice($nodes, $i+1); - } - if ($this->isXML && ! $innerMarkup) { - self::debug("Getting outerXML with charset '{$this->charset}'"); - // we need outerXML, so we can benefit from - // $node param support in saveXML() - foreach($nodes as $node) - $markup .= $this->document->saveXML($node); - } else { - $loop = array(); - if ($innerMarkup) - foreach($nodes as $node) { - if ($node->childNodes) - foreach($node->childNodes as $child) - $loop[] = $child; - else - $loop[] = $node; - } - else - $loop = $nodes; - self::debug("Getting markup, moving selected nodes (".count($loop).") to new DocumentFragment"); - $fake = $this->documentFragmentCreate($loop); - $markup = $this->documentFragmentToMarkup($fake); - } - if ($this->isXHTML) { - self::debug("Fixing XHTML"); - $markup = self::markupFixXHTML($markup); - } - self::debug("Markup: ".substr($markup, 0, 250)); - return $markup; - } else { - if ($this->isDocumentFragment) { - // documentFragment, html only... - self::debug("Getting markup, DocumentFragment detected"); -// return $this->markup( -//// $this->document->getElementsByTagName('body')->item(0) -// $this->document->root, true -// ); - $markup = $this->documentFragmentToMarkup($this); - // no need for markupFixXHTML, as it's done thought markup($nodes) method - return $markup; - } else { - self::debug("Getting markup (".($this->isXML?'XML':'HTML')."), final with charset '{$this->charset}'"); - $markup = $this->isXML - ? $this->document->saveXML() - : $this->document->saveHTML(); - if ($this->isXHTML) { - self::debug("Fixing XHTML"); - $markup = self::markupFixXHTML($markup); - } - self::debug("Markup: ".substr($markup, 0, 250)); - return $markup; - } - } - } - protected static function markupFixXHTML($markup) { - $markup = self::expandEmptyTag('script', $markup); - $markup = self::expandEmptyTag('select', $markup); - $markup = self::expandEmptyTag('textarea', $markup); - return $markup; - } - public static function debug($text) { - phpQuery::debug($text); - } - /** - * expandEmptyTag - * - * @param $tag - * @param $xml - * @return string - * @author mjaque at ilkebenson dot com - * @link http://php.net/manual/en/domdocument.savehtml.php#81256 - */ - public static function expandEmptyTag($tag, $xml){ - $indice = 0; - while ($indice< strlen($xml)){ - $pos = strpos($xml, "<$tag ", $indice); - if ($pos){ - $posCierre = strpos($xml, ">", $pos); - if ($xml[$posCierre-1] == "/"){ - $xml = substr_replace($xml, ">", $posCierre-1, 2); - } - $indice = $posCierre; - } - else break; - } - return $xml; - } -} diff --git a/phpQuery/phpQuery/DOMEvent.php b/phpQuery/phpQuery/DOMEvent.php deleted file mode 100644 index 0cb0c46..0000000 --- a/phpQuery/phpQuery/DOMEvent.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @package phpQuery - * @todo implement ArrayAccess ? - */ -class DOMEvent { - /** - * Returns a boolean indicating whether the event bubbles up through the DOM or not. - * - * @var unknown_type - */ - public $bubbles = true; - /** - * Returns a boolean indicating whether the event is cancelable. - * - * @var unknown_type - */ - public $cancelable = true; - /** - * Returns a reference to the currently registered target for the event. - * - * @var unknown_type - */ - public $currentTarget; - /** - * Returns detail about the event, depending on the type of event. - * - * @var unknown_type - * @link http://developer.mozilla.org/en/DOM/event.detail - */ - public $detail; // ??? - /** - * Used to indicate which phase of the event flow is currently being evaluated. - * - * NOT IMPLEMENTED - * - * @var unknown_type - * @link http://developer.mozilla.org/en/DOM/event.eventPhase - */ - public $eventPhase; // ??? - /** - * The explicit original target of the event (Mozilla-specific). - * - * NOT IMPLEMENTED - * - * @var unknown_type - */ - public $explicitOriginalTarget; // moz only - /** - * The original target of the event, before any retargetings (Mozilla-specific). - * - * NOT IMPLEMENTED - * - * @var unknown_type - */ - public $originalTarget; // moz only - /** - * Identifies a secondary target for the event. - * - * @var unknown_type - */ - public $relatedTarget; - /** - * Returns a reference to the target to which the event was originally dispatched. - * - * @var unknown_type - */ - public $target; - /** - * Returns the time that the event was created. - * - * @var unknown_type - */ - public $timeStamp; - /** - * Returns the name of the event (case-insensitive). - */ - public $type; - public $runDefault = true; - public $data = null; - public function __construct($data) { - foreach($data as $k => $v) { - $this->$k = $v; - } - if (! $this->timeStamp) - $this->timeStamp = time(); - } - /** - * Cancels the event (if it is cancelable). - * - */ - public function preventDefault() { - $this->runDefault = false; - } - /** - * Stops the propagation of events further along in the DOM. - * - */ - public function stopPropagation() { - $this->bubbles = false; - } -} diff --git a/phpQuery/phpQuery/compat/mbstring.php b/phpQuery/phpQuery/compat/mbstring.php deleted file mode 100644 index 409129e..0000000 --- a/phpQuery/phpQuery/compat/mbstring.php +++ /dev/null @@ -1,88 +0,0 @@ -document) - $pq->find('*')->add($pq->document) - ->trigger($type, $data); - } - } else { - if (isset($data[0]) && $data[0] instanceof DOMEvent) { - $event = $data[0]; - $event->relatedTarget = $event->target; - $event->target = $node; - $data = array_slice($data, 1); - } else { - $event = new DOMEvent(array( - 'type' => $type, - 'target' => $node, - 'timeStamp' => time(), - )); - } - $i = 0; - while($node) { - // TODO whois - phpQuery::debug("Triggering ".($i?"bubbled ":'')."event '{$type}' on " - ."node \n");//.phpQueryObject::whois($node)."\n"); - $event->currentTarget = $node; - $eventNode = self::getNode($documentID, $node); - if (isset($eventNode->eventHandlers)) { - foreach($eventNode->eventHandlers as $eventType => $handlers) { - $eventNamespace = null; - if (strpos($type, '.') !== false) - list($eventName, $eventNamespace) = explode('.', $eventType); - else - $eventName = $eventType; - if ($name != $eventName) - continue; - if ($namespace && $eventNamespace && $namespace != $eventNamespace) - continue; - foreach($handlers as $handler) { - phpQuery::debug("Calling event handler\n"); - $event->data = $handler['data'] - ? $handler['data'] - : null; - $params = array_merge(array($event), $data); - $return = phpQuery::callbackRun($handler['callback'], $params); - if ($return === false) { - $event->bubbles = false; - } - } - } - } - // to bubble or not to bubble... - if (! $event->bubbles) - break; - $node = $node->parentNode; - $i++; - } - } - } - /** - * Binds a handler to one or more events (like click) for each matched element. - * Can also bind custom events. - * - * @param DOMNode|phpQueryObject|string $document - * @param unknown_type $type - * @param unknown_type $data Optional - * @param unknown_type $callback - * - * @TODO support '!' (exclusive) events - * @TODO support more than event in $type (space-separated) - * @TODO support binding to global events - */ - public static function add($document, $node, $type, $data, $callback = null) { - phpQuery::debug("Binding '$type' event"); - $documentID = phpQuery::getDocumentID($document); -// if (is_null($callback) && is_callable($data)) { -// $callback = $data; -// $data = null; -// } - $eventNode = self::getNode($documentID, $node); - if (! $eventNode) - $eventNode = self::setNode($documentID, $node); - if (!isset($eventNode->eventHandlers[$type])) - $eventNode->eventHandlers[$type] = array(); - $eventNode->eventHandlers[$type][] = array( - 'callback' => $callback, - 'data' => $data, - ); - } - /** - * Enter description here... - * - * @param DOMNode|phpQueryObject|string $document - * @param unknown_type $type - * @param unknown_type $callback - * - * @TODO namespace events - * @TODO support more than event in $type (space-separated) - */ - public static function remove($document, $node, $type = null, $callback = null) { - $documentID = phpQuery::getDocumentID($document); - $eventNode = self::getNode($documentID, $node); - if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) { - if ($callback) { - foreach($eventNode->eventHandlers[$type] as $k => $handler) - if ($handler['callback'] == $callback) - unset($eventNode->eventHandlers[$type][$k]); - } else { - unset($eventNode->eventHandlers[$type]); - } - } - } - protected static function getNode($documentID, $node) { - foreach(phpQuery::$documents[$documentID]->eventsNodes as $eventNode) { - if ($node->isSameNode($eventNode)) - return $eventNode; - } - } - protected static function setNode($documentID, $node) { - phpQuery::$documents[$documentID]->eventsNodes[] = $node; - return phpQuery::$documents[$documentID]->eventsNodes[ - count(phpQuery::$documents[$documentID]->eventsNodes)-1 - ]; - } - protected static function issetGlobal($documentID, $type) { - return isset(phpQuery::$documents[$documentID]) - ? in_array($type, phpQuery::$documents[$documentID]->eventsGlobal) - : false; - } -} diff --git a/phpQuery/phpQuery/phpQueryObject.php b/phpQuery/phpQuery/phpQueryObject.php deleted file mode 100644 index 7adf53f..0000000 --- a/phpQuery/phpQuery/phpQueryObject.php +++ /dev/null @@ -1,3379 +0,0 @@ - - * @package phpQuery - * @method phpQueryObject clone() clone() - * @method phpQueryObject empty() empty() - * @method phpQueryObject next() next($selector = null) - * @method phpQueryObject prev() prev($selector = null) - * @property Int $length - */ -class phpQueryObject - implements Iterator, Countable, ArrayAccess { - public $documentID = null; - /** - * DOMDocument class. - * - * @var DOMDocument - */ - public $document = null; - public $charset = null; - /** - * - * @var DOMDocumentWrapper - */ - public $documentWrapper = null; - /** - * XPath interface. - * - * @var DOMXPath - */ - public $xpath = null; - /** - * Stack of selected elements. - * @TODO refactor to ->nodes - * @var array - */ - public $elements = array(); - /** - * @access private - */ - protected $elementsBackup = array(); - /** - * @access private - */ - protected $previous = null; - /** - * @access private - * @TODO deprecate - */ - protected $root = array(); - /** - * Indicated if doument is just a fragment (no tag). - * - * Every document is realy a full document, so even documentFragments can - * be queried against , but getDocument(id)->htmlOuter() will return - * only contents of . - * - * @var bool - */ - public $documentFragment = true; - /** - * Iterator interface helper - * @access private - */ - protected $elementsInterator = array(); - /** - * Iterator interface helper - * @access private - */ - protected $valid = false; - /** - * Iterator interface helper - * @access private - */ - protected $current = null; - - /** - * Indicates whether CSS has been parsed or not. We only parse CSS if needed. - * @access private - */ - protected $cssIsParsed = array(); - /** - * A collection of complete CSS selector strings. - * @access private; - */ - protected $cssString = array(); - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - - protected $attribute_css_mapping = array( - 'bgcolor' => 'background-color', - 'text' => 'color', - 'width' => 'width', - 'height' => 'height' - ); - - public function __construct($documentID) { -// if ($documentID instanceof self) -// var_dump($documentID->getDocumentID()); - $id = $documentID instanceof self - ? $documentID->getDocumentID() - : $documentID; -// var_dump($id); - if (! isset(phpQuery::$documents[$id] )) { -// var_dump(phpQuery::$documents); - throw new Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); - } - $this->documentID = $id; - $this->documentWrapper =& phpQuery::$documents[$id]; - $this->document =& $this->documentWrapper->document; - $this->xpath =& $this->documentWrapper->xpath; - $this->charset =& $this->documentWrapper->charset; - $this->documentFragment =& $this->documentWrapper->isDocumentFragment; - // TODO check $this->DOM->documentElement; -// $this->root = $this->document->documentElement; - $this->root =& $this->documentWrapper->root; -// $this->toRoot(); - $this->elements = array($this->root); - } - /** - * - * @access private - * @param $attr - * @return unknown_type - */ - public function __get($attr) { - switch($attr) { - // FIXME doesnt work at all ? - case 'length': - return $this->size(); - break; - default: - return $this->$attr; - } - } - /** - * Saves actual object to $var by reference. - * Useful when need to break chain. - * @param phpQueryObject $var - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toReference(&$var) { - return $var = $this; - } - public function documentFragment($state = null) { - if ($state) { - phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; - return $this; - } - return $this->documentFragment; - } - /** - * @access private - * @TODO documentWrapper - */ - protected function isRoot( $node) { -// return $node instanceof DOMDOCUMENT || $node->tagName == 'html'; - return $node instanceof DOMDOCUMENT - || ($node instanceof DOMELEMENT && $node->tagName == 'html') - || $this->root->isSameNode($node); - } - /** - * @access private - */ - protected function stackIsRoot() { - return $this->size() == 1 && $this->isRoot($this->elements[0]); - } - /** - * Enter description here... - * NON JQUERY METHOD - * - * Watch out, it doesn't creates new instance, can be reverted with end(). - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toRoot() { - $this->elements = array($this->root); - return $this; -// return $this->newInstance(array($this->root)); - } - /** - * Saves object's DocumentID to $var by reference. - * - * $myDocumentId; - * phpQuery::newDocument('
    ') - * ->getDocumentIDRef($myDocumentId) - * ->find('div')->... - * - * - * @param unknown_type $domId - * @see phpQuery::newDocument - * @see phpQuery::newDocumentFile - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocumentIDRef(&$documentID) { - $documentID = $this->getDocumentID(); - return $this; - } - /** - * Returns object with stack set to document root. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocument() { - return phpQuery::getDocument($this->getDocumentID()); - } - /** - * - * @return DOMDocument - */ - public function getDOMDocument() { - return $this->document; - } - /** - * Get object's Document ID. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocumentID() { - return $this->documentID; - } - /** - * Unloads whole document from memory. - * CAUTION! None further operations will be possible on this document. - * All objects refering to it will be useless. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function unloadDocument() { - phpQuery::unloadDocuments($this->getDocumentID()); - } - public function isHTML() { - return $this->documentWrapper->isHTML; - } - public function isXHTML() { - return $this->documentWrapper->isXHTML; - } - public function isXML() { - return $this->documentWrapper->isXML; - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/serialize - * @return string - */ - public function serialize() { - return phpQuery::param($this->serializeArray()); - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/serializeArray - * @return array - */ - public function serializeArray($submit = null) { - $source = $this->filter('form, input, select, textarea') - ->find('input, select, textarea') - ->andSelf() - ->not('form'); - $return = array(); -// $source->dumpDie(); - foreach($source as $input) { - $input = phpQuery::pq($input); - if ($input->is('[disabled]')) - continue; - if (!$input->is('[name]')) - continue; - if ($input->is('[type=checkbox]') && !$input->is('[checked]')) - continue; - // jquery diff - if ($submit && $input->is('[type=submit]')) { - if ($submit instanceof DOMELEMENT && ! $input->elements[0]->isSameNode($submit)) - continue; - else if (is_string($submit) && $input->attr('name') != $submit) - continue; - } - $return[] = array( - 'name' => $input->attr('name'), - 'value' => $input->val(), - ); - } - return $return; - } - /** - * @access private - */ - protected function debug($in) { - if (! phpQuery::$debug ) - return; - print('
    ');
    -		print_r($in);
    -		// file debug
    -//		file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
    -		// quite handy debug trace
    -//		if ( is_array($in))
    -//			print_r(array_slice(debug_backtrace(), 3));
    -		print("
    \n"); - } - /** - * @access private - */ - protected function isRegexp($pattern) { - return in_array( - $pattern[ mb_strlen($pattern)-1 ], - array('^','*','$') - ); - } - /** - * Determines if $char is really a char. - * - * @param string $char - * @return bool - * @todo rewrite me to charcode range ! ;) - * @access private - */ - protected function isChar($char) { - return extension_loaded('mbstring') && phpQuery::$mbstringSupport - ? mb_eregi('\w', $char) - : preg_match('@\w@', $char); - } - /** - * @access private - */ - protected function parseSelector($query) { - // clean spaces - // TODO include this inside parsing ? - $query = trim( - preg_replace('@\s+@', ' ', - preg_replace('@\s*(>|\\+|~)\s*@', '\\1', $query) - ) - ); - $queries = array(array()); - if (! $query) - return $queries; - $return =& $queries[0]; - $specialChars = array('>',' '); -// $specialCharsMapping = array('/' => '>'); - $specialCharsMapping = array(); - $strlen = mb_strlen($query); - $classChars = array('.', '-'); - $pseudoChars = array('-'); - $tagChars = array('*', '|', '-'); - // split multibyte string - // http://code.google.com/p/phpquery/issues/detail?id=76 - $_query = array(); - for ($i=0; $i<$strlen; $i++) - $_query[] = mb_substr($query, $i, 1); - $query = $_query; - // it works, but i dont like it... - $i = 0; - while( $i < $strlen) { - $c = $query[$i]; - $tmp = ''; - // TAG - if ($this->isChar($c) || in_array($c, $tagChars)) { - while(isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) { - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // IDs - } else if ( $c == '#') { - $i++; - while( isset($query[$i]) && ($this->isChar($query[$i]) || $query[$i] == '-')) { - $tmp .= $query[$i]; - $i++; - } - $return[] = '#'.$tmp; - // SPECIAL CHARS - } else if (in_array($c, $specialChars)) { - $return[] = $c; - $i++; - // MAPPED SPECIAL MULTICHARS -// } else if ( $c.$query[$i+1] == '//') { -// $return[] = ' '; -// $i = $i+2; - // MAPPED SPECIAL CHARS - } else if ( isset($specialCharsMapping[$c])) { - $return[] = $specialCharsMapping[$c]; - $i++; - // COMMA - } else if ( $c == ',') { - $queries[] = array(); - $return =& $queries[ count($queries)-1 ]; - $i++; - while( isset($query[$i]) && $query[$i] == ' ') - $i++; - // CLASSES - } else if ($c == '.') { - while( isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) { - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // ~ General Sibling Selector - } else if ($c == '~') { - $spaceAllowed = true; - $tmp .= $query[$i++]; - while( isset($query[$i]) - && ($this->isChar($query[$i]) - || in_array($query[$i], $classChars) - || $query[$i] == '*' - || ($query[$i] == ' ' && $spaceAllowed) - )) { - if ($query[$i] != ' ') - $spaceAllowed = false; - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // + Adjacent sibling selectors - } else if ($c == '+') { - $spaceAllowed = true; - $tmp .= $query[$i++]; - while( isset($query[$i]) - && ($this->isChar($query[$i]) - || in_array($query[$i], $classChars) - || $query[$i] == '*' - || ($spaceAllowed && $query[$i] == ' ') - )) { - if ($query[$i] != ' ') - $spaceAllowed = false; - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // ATTRS - } else if ($c == '[') { - $stack = 1; - $tmp .= $c; - while( isset($query[++$i])) { - $tmp .= $query[$i]; - if ( $query[$i] == '[') { - $stack++; - } else if ( $query[$i] == ']') { - $stack--; - if (! $stack ) - break; - } - } - $return[] = $tmp; - $i++; - // PSEUDO CLASSES - } else if ($c == ':') { - $stack = 1; - $tmp .= $query[$i++]; - while( isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) { - $tmp .= $query[$i]; - $i++; - } - // with arguments ? - if ( isset($query[$i]) && $query[$i] == '(') { - $tmp .= $query[$i]; - $stack = 1; - while( isset($query[++$i])) { - $tmp .= $query[$i]; - if ( $query[$i] == '(') { - $stack++; - } else if ( $query[$i] == ')') { - $stack--; - if (! $stack ) - break; - } - } - $return[] = $tmp; - $i++; - } else { - $return[] = $tmp; - } - } else { - $i++; - } - } - foreach($queries as $k => $q) { - if (isset($q[0])) { - if (isset($q[0][0]) && $q[0][0] == ':') - array_unshift($queries[$k], '*'); - if ($q[0] != '>') - array_unshift($queries[$k], ' '); - } - } - return $queries; - } - /** - * Return matched DOM nodes. - * - * @param int $index - * @return array|DOMElement Single DOMElement or array of DOMElement. - */ - public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $return = isset($index) - ? (isset($this->elements[$index]) ? $this->elements[$index] : null) - : $this->elements; - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - foreach($args as $callback) { - if (is_array($return)) - foreach($return as $k => $v) - $return[$k] = phpQuery::callbackRun($callback, array($v)); - else - $return = phpQuery::callbackRun($callback, array($return)); - } - return $return; - } - /** - * Return matched DOM nodes. - * jQuery difference. - * - * @param int $index - * @return array|string Returns string if $index != null - * @todo implement callbacks - * @todo return only arrays ? - * @todo maybe other name... - */ - public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (!is_null($index) && is_int($index)) - $return = $this->eq($index)->text(); - else { - $return = array(); - for($i = 0; $i < $this->size(); $i++) { - $return[] = $this->eq($i)->text(); - } - } - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - foreach($args as $callback) { - $return = phpQuery::callbackRun($callback, array($return)); - } - return $return; - } - /** - * Return matched DOM nodes. - * jQuery difference. - * - * @param int $index - * @return array|string Returns string if $index != null - * @todo implement callbacks - * @todo return only arrays ? - * @todo maybe other name... - */ - public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (!is_null($index) && is_int($index)) - $return = $this->eq($index)->text(); - else { - $return = array(); - for($i = 0; $i < $this->size(); $i++) { - $return[] = $this->eq($i)->text(); - } - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - } - foreach($args as $callback) { - if (is_array($return)) - foreach($return as $k => $v) - $return[$k] = phpQuery::callbackRun($callback, array($v)); - else - $return = phpQuery::callbackRun($callback, array($return)); - } - return $return; - } - /** - * Returns new instance of actual class. - * - * @param array $newStack Optional. Will replace old stack with new and move old one to history.c - */ - public function newInstance($newStack = null) { - $class = get_class($this); - // support inheritance by passing old object to overloaded constructor - $new = $class != 'phpQuery' - ? new $class($this, $this->getDocumentID()) - : new phpQueryObject($this->getDocumentID()); - $new->previous = $this; - if (is_null($newStack)) { - $new->elements = $this->elements; - if ($this->elementsBackup) - $this->elements = $this->elementsBackup; - } else if (is_string($newStack)) { - $new->elements = phpQuery::pq($newStack, $this->getDocumentID())->stack(); - } else { - $new->elements = $newStack; - } - return $new; - } - /** - * Enter description here... - * - * In the future, when PHP will support XLS 2.0, then we would do that this way: - * contains(tokenize(@class, '\s'), "something") - * @param unknown_type $class - * @param unknown_type $node - * @return boolean - * @access private - */ - protected function matchClasses($class, $node) { - // multi-class - if ( mb_strpos($class, '.', 1)) { - $classes = explode('.', substr($class, 1)); - $classesCount = count( $classes ); - $nodeClasses = explode(' ', $node->getAttribute('class') ); - $nodeClassesCount = count( $nodeClasses ); - if ( $classesCount > $nodeClassesCount ) - return false; - $diff = count( - array_diff( - $classes, - $nodeClasses - ) - ); - if (! $diff ) - return true; - // single-class - } else { - return in_array( - // strip leading dot from class name - substr($class, 1), - // get classes for element as array - explode(' ', $node->getAttribute('class') ) - ); - } - } - /** - * @access private - */ - protected function runQuery($XQuery, $selector = null, $compare = null) { - if ($compare && ! method_exists($this, $compare)) - return false; - $stack = array(); - if (! $this->elements) - $this->debug('Stack empty, skipping...'); -// var_dump($this->elements[0]->nodeType); - // element, document - foreach($this->stack(array(1, 9, 13)) as $k => $stackNode) { - $detachAfter = false; - // to work on detached nodes we need temporary place them somewhere - // thats because context xpath queries sucks ;] - $testNode = $stackNode; - while ($testNode) { - if (! $testNode->parentNode && ! $this->isRoot($testNode)) { - $this->root->appendChild($testNode); - $detachAfter = $testNode; - break; - } - $testNode = isset($testNode->parentNode) - ? $testNode->parentNode - : null; - } - // XXX tmp ? - $xpath = $this->documentWrapper->isXHTML - ? $this->getNodeXpath($stackNode, 'html') - : $this->getNodeXpath($stackNode); - // FIXME pseudoclasses-only query, support XML - $query = $XQuery == '//' && $xpath == '/html[1]' - ? '//*' - : $xpath.$XQuery; - $this->debug("XPATH: {$query}"); - // run query, get elements - $nodes = $this->xpath->query($query); - $this->debug("QUERY FETCHED"); - if (! $nodes->length ) - $this->debug('Nothing found'); - $debug = array(); - foreach($nodes as $node) { - $matched = false; - if ( $compare) { - phpQuery::$debug ? - $this->debug("Found: ".$this->whois( $node ).", comparing with {$compare}()") - : null; - $phpQueryDebug = phpQuery::$debug; - phpQuery::$debug = false; - // TODO ??? use phpQuery::callbackRun() - if (call_user_func_array(array($this, $compare), array($selector, $node))) - $matched = true; - phpQuery::$debug = $phpQueryDebug; - } else { - $matched = true; - } - if ( $matched) { - if (phpQuery::$debug) - $debug[] = $this->whois( $node ); - $stack[] = $node; - } - } - if (phpQuery::$debug) { - $this->debug("Matched ".count($debug).": ".implode(', ', $debug)); - } - if ($detachAfter) - $this->root->removeChild($detachAfter); - } - $this->elements = $stack; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function find($selectors, $context = null, $noHistory = false) { - if (!$noHistory) - // backup last stack /for end()/ - $this->elementsBackup = $this->elements; - // allow to define context - // TODO combine code below with phpQuery::pq() context guessing code - // as generic function - if ($context) { - if (! is_array($context) && $context instanceof DOMELEMENT) - $this->elements = array($context); - else if (is_array($context)) { - $this->elements = array(); - foreach ($context as $c) - if ($c instanceof DOMELEMENT) - $this->elements[] = $c; - } else if ( $context instanceof self ) - $this->elements = $context->elements; - } - $queries = $this->parseSelector($selectors); - $this->debug(array('FIND', $selectors, $queries)); - $XQuery = ''; - // remember stack state because of multi-queries - $oldStack = $this->elements; - // here we will be keeping found elements - $stack = array(); - foreach($queries as $selector) { - $this->elements = $oldStack; - $delimiterBefore = false; - foreach($selector as $s) { - // TAG - $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport - ? mb_ereg_match('^[\w|\||-]+$', $s) || $s == '*' - : preg_match('@^[\w|\||-]+$@', $s) || $s == '*'; - if ($isTag) { - if ($this->isXML()) { - // namespace support - if (mb_strpos($s, '|') !== false) { - $ns = $tag = null; - list($ns, $tag) = explode('|', $s); - $XQuery .= "$ns:$tag"; - } else if ($s == '*') { - $XQuery .= "*"; - } else { - $XQuery .= "*[local-name()='$s']"; - } - } else { - $XQuery .= $s; - } - // ID - } else if ($s[0] == '#') { - if ($delimiterBefore) - $XQuery .= '*'; - $XQuery .= "[@id='".substr($s, 1)."']"; - // ATTRIBUTES - } else if ($s[0] == '[') { - if ($delimiterBefore) - $XQuery .= '*'; - // strip side brackets - $attr = trim($s, ']['); - $execute = false; - // attr with specifed value - if (mb_strpos($s, '=')) { - $value = null; - list($attr, $value) = explode('=', $attr); - $value = trim($value, "'\""); - if ($this->isRegexp($attr)) { - // cut regexp character - $attr = substr($attr, 0, -1); - $execute = true; - $XQuery .= "[@{$attr}]"; - } else { - $XQuery .= "[@{$attr}='{$value}']"; - } - // attr without specified value - } else { - $XQuery .= "[@{$attr}]"; - } - if ($execute) { - $this->runQuery($XQuery, $s, 'is'); - $XQuery = ''; - if (! $this->length()) - break; - } - // CLASSES - } else if ($s[0] == '.') { - // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]"); - // thx wizDom ;) - if ($delimiterBefore) - $XQuery .= '*'; - $XQuery .= '[@class]'; - $this->runQuery($XQuery, $s, 'matchClasses'); - $XQuery = ''; - if (! $this->length() ) - break; - // ~ General Sibling Selector - } else if ($s[0] == '~') { - $this->runQuery($XQuery); - $XQuery = ''; - $this->elements = $this - ->siblings( - substr($s, 1) - )->elements; - if (! $this->length() ) - break; - // + Adjacent sibling selectors - } else if ($s[0] == '+') { - // TODO /following-sibling:: - $this->runQuery($XQuery); - $XQuery = ''; - $subSelector = substr($s, 1); - $subElements = $this->elements; - $this->elements = array(); - foreach($subElements as $node) { - // search first DOMElement sibling - $test = $node->nextSibling; - while($test && ! ($test instanceof DOMELEMENT)) - $test = $test->nextSibling; - if ($test && $this->is($subSelector, $test)) - $this->elements[] = $test; - } - if (! $this->length() ) - break; - // PSEUDO CLASSES - } else if ($s[0] == ':') { - // TODO optimization for :first :last - if ($XQuery) { - $this->runQuery($XQuery); - $XQuery = ''; - } - if (! $this->length()) - break; - $this->pseudoClasses($s); - if (! $this->length()) - break; - // DIRECT DESCENDANDS - } else if ($s == '>') { - $XQuery .= '/'; - $delimiterBefore = 2; - // ALL DESCENDANDS - } else if ($s == ' ') { - $XQuery .= '//'; - $delimiterBefore = 2; - // ERRORS - } else { - phpQuery::debug("Unrecognized token '$s'"); - } - $delimiterBefore = $delimiterBefore === 2; - } - // run query if any - if ($XQuery && $XQuery != '//') { - $this->runQuery($XQuery); - $XQuery = ''; - } - foreach($this->elements as $node) - if (! $this->elementsContainsNode($node, $stack)) - $stack[] = $node; - } - $this->elements = $stack; - return $this->newInstance(); - } - /** - * @todo create API for classes with pseudoselectors - * @access private - */ - protected function pseudoClasses($class) { - // TODO clean args parsing ? - $class = ltrim($class, ':'); - $haveArgs = mb_strpos($class, '('); - if ($haveArgs !== false) { - $args = substr($class, $haveArgs+1, -1); - $class = substr($class, 0, $haveArgs); - } - switch($class) { - case 'even': - case 'odd': - $stack = array(); - foreach($this->elements as $i => $node) { - if ($class == 'even' && ($i%2) == 0) - $stack[] = $node; - else if ( $class == 'odd' && $i % 2 ) - $stack[] = $node; - } - $this->elements = $stack; - break; - case 'eq': - $k = intval($args); - $this->elements = isset( $this->elements[$k] ) - ? array( $this->elements[$k] ) - : array(); - break; - case 'gt': - $this->elements = array_slice($this->elements, $args+1); - break; - case 'lt': - $this->elements = array_slice($this->elements, 0, $args+1); - break; - case 'first': - if (isset($this->elements[0])) - $this->elements = array($this->elements[0]); - break; - case 'last': - if ($this->elements) - $this->elements = array($this->elements[count($this->elements)-1]); - break; - /*case 'parent': - $stack = array(); - foreach($this->elements as $node) { - if ( $node->childNodes->length ) - $stack[] = $node; - } - $this->elements = $stack; - break;*/ - case 'contains': - $text = trim($args, "\"'"); - $stack = array(); - foreach($this->elements as $node) { - if (mb_stripos($node->textContent, $text) === false) - continue; - $stack[] = $node; - } - $this->elements = $stack; - break; - case 'not': - $selector = self::unQuote($args); - $this->elements = $this->not($selector)->stack(); - break; - case 'slice': - // TODO jQuery difference ? - $args = explode(',', - str_replace(', ', ',', trim($args, "\"'")) - ); - $start = $args[0]; - $end = isset($args[1]) - ? $args[1] - : null; - if ($end > 0) - $end = $end-$start; - $this->elements = array_slice($this->elements, $start, $end); - break; - case 'has': - $selector = trim($args, "\"'"); - $stack = array(); - foreach($this->stack(1) as $el) { - if ($this->find($selector, $el, true)->length) - $stack[] = $el; - } - $this->elements = $stack; - break; - case 'submit': - case 'reset': - $this->elements = phpQuery::merge( - $this->map(array($this, 'is'), - "input[type=$class]", new CallbackParam() - ), - $this->map(array($this, 'is'), - "button[type=$class]", new CallbackParam() - ) - ); - break; -// $stack = array(); -// foreach($this->elements as $node) -// if ($node->is('input[type=submit]') || $node->is('button[type=submit]')) -// $stack[] = $el; -// $this->elements = $stack; - case 'input': - $this->elements = $this->map( - array($this, 'is'), - 'input', new CallbackParam() - )->elements; - break; - case 'password': - case 'checkbox': - case 'radio': - case 'hidden': - case 'image': - case 'file': - $this->elements = $this->map( - array($this, 'is'), - "input[type=$class]", new CallbackParam() - )->elements; - break; - case 'parent': - $this->elements = $this->map( - create_function('$node', ' - return $node instanceof DOMELEMENT && $node->childNodes->length - ? $node : null;') - )->elements; - break; - case 'empty': - $this->elements = $this->map( - create_function('$node', ' - return $node instanceof DOMELEMENT && $node->childNodes->length - ? null : $node;') - )->elements; - break; - case 'disabled': - case 'selected': - case 'checked': - $this->elements = $this->map( - array($this, 'is'), - "[$class]", new CallbackParam() - )->elements; - break; - case 'enabled': - $this->elements = $this->map( - create_function('$node', ' - return pq($node)->not(":disabled") ? $node : null;') - )->elements; - break; - case 'header': - $this->elements = $this->map( - create_function('$node', - '$isHeader = isset($node->tagName) && in_array($node->tagName, array( - "h1", "h2", "h3", "h4", "h5", "h6", "h7" - )); - return $isHeader - ? $node - : null;') - )->elements; -// $this->elements = $this->map( -// create_function('$node', '$node = pq($node); -// return $node->is("h1") -// || $node->is("h2") -// || $node->is("h3") -// || $node->is("h4") -// || $node->is("h5") -// || $node->is("h6") -// || $node->is("h7") -// ? $node -// : null;') -// )->elements; - break; - case 'only-child': - $this->elements = $this->map( - create_function('$node', - 'return pq($node)->siblings()->size() == 0 ? $node : null;') - )->elements; - break; - case 'first-child': - $this->elements = $this->map( - create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;') - )->elements; - break; - case 'last-child': - $this->elements = $this->map( - create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;') - )->elements; - break; - case 'nth-child': - $param = trim($args, "\"'"); - if (! $param) - break; - // nth-child(n+b) to nth-child(1n+b) - if ($param{0} == 'n') - $param = '1'.$param; - // :nth-child(index/even/odd/equation) - if ($param == 'even' || $param == 'odd') - $mapped = $this->map( - create_function('$node, $param', - '$index = pq($node)->prevAll()->size()+1; - if ($param == "even" && ($index%2) == 0) - return $node; - else if ($param == "odd" && $index%2 == 1) - return $node; - else - return null;'), - new CallbackParam(), $param - ); - else if (mb_strlen($param) > 1 && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1) - // an+b - $mapped = $this->map( - create_function('$node, $param', - '$prevs = pq($node)->prevAll()->size(); - $index = 1+$prevs; - - preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches); - $a = intval($matches[1]); - $b = intval($matches[3]); - if( $matches[2] === "-" ) { - $b = -$b; - } - - if ($a > 0) { - return ($index-$b)%$a == 0 - ? $node - : null; - phpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs"); - return $a*floor($index/$a)+$b-1 == $prevs - ? $node - : null; - } else if ($a == 0) - return $index == $b - ? $node - : null; - else - // negative value - return $index <= $b - ? $node - : null; -// if (! $b) -// return $index%$a == 0 -// ? $node -// : null; -// else -// return ($index-$b)%$a == 0 -// ? $node -// : null; - '), - new CallbackParam(), $param - ); - else - // index - $mapped = $this->map( - create_function('$node, $index', - '$prevs = pq($node)->prevAll()->size(); - if ($prevs && $prevs == $index-1) - return $node; - else if (! $prevs && $index == 1) - return $node; - else - return null;'), - new CallbackParam(), $param - ); - $this->elements = $mapped->elements; - break; - default: - $this->debug("Unknown pseudoclass '{$class}', skipping..."); - } - } - /** - * @access private - */ - protected function __pseudoClassParam($paramsString) { - // TODO; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function is($selector, $nodes = null) { - phpQuery::debug(array("Is:", $selector)); - if (! $selector) - return false; - $oldStack = $this->elements; - $returnArray = false; - if ($nodes && is_array($nodes)) { - $this->elements = $nodes; - } else if ($nodes) - $this->elements = array($nodes); - $this->filter($selector, true); - $stack = $this->elements; - $this->elements = $oldStack; - if ($nodes) - return $stack ? $stack : null; - return (bool)count($stack); - } - /** - * Enter description here... - * jQuery difference. - * - * Callback: - * - $index int - * - $node DOMNode - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @link http://docs.jquery.com/Traversing/filter - */ - public function filterCallback($callback, $_skipHistory = false) { - if (! $_skipHistory) { - $this->elementsBackup = $this->elements; - $this->debug("Filtering by callback"); - } - $newStack = array(); - foreach($this->elements as $index => $node) { - $result = phpQuery::callbackRun($callback, array($index, $node)); - if (is_null($result) || (! is_null($result) && $result)) - $newStack[] = $node; - } - $this->elements = $newStack; - return $_skipHistory - ? $this - : $this->newInstance(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @link http://docs.jquery.com/Traversing/filter - */ - public function filter($selectors, $_skipHistory = false) { - if ($selectors instanceof Callback OR $selectors instanceof Closure) - return $this->filterCallback($selectors, $_skipHistory); - if (! $_skipHistory) - $this->elementsBackup = $this->elements; - $notSimpleSelector = array(' ', '>', '~', '+', '/'); - if (! is_array($selectors)) - $selectors = $this->parseSelector($selectors); - if (! $_skipHistory) - $this->debug(array("Filtering:", $selectors)); - $finalStack = array(); - foreach($selectors as $selector) { - $stack = array(); - if (! $selector) - break; - // avoid first space or / - if (in_array($selector[0], $notSimpleSelector)) - $selector = array_slice($selector, 1); - // PER NODE selector chunks - foreach($this->stack() as $node) { - $break = false; - foreach($selector as $s) { - if (!($node instanceof DOMELEMENT)) { - // all besides DOMElement - if ( $s[0] == '[') { - $attr = trim($s, '[]'); - if ( mb_strpos($attr, '=')) { - list( $attr, $val ) = explode('=', $attr); - if ($attr == 'nodeType' && $node->nodeType != $val) - $break = true; - } - } else - $break = true; - } else { - // DOMElement only - // ID - if ( $s[0] == '#') { - if ( $node->getAttribute('id') != substr($s, 1) ) - $break = true; - // CLASSES - } else if ( $s[0] == '.') { - if (! $this->matchClasses( $s, $node ) ) - $break = true; - // ATTRS - } else if ( $s[0] == '[') { - // strip side brackets - $attr = trim($s, '[]'); - if (mb_strpos($attr, '=')) { - list($attr, $val) = explode('=', $attr); - $val = self::unQuote($val); - if ($attr == 'nodeType') { - if ($val != $node->nodeType) - $break = true; - } else if ($this->isRegexp($attr)) { - $val = extension_loaded('mbstring') && phpQuery::$mbstringSupport - ? quotemeta(trim($val, '"\'')) - : preg_quote(trim($val, '"\''), '@'); - // switch last character - switch( substr($attr, -1)) { - // quotemeta used insted of preg_quote - // http://code.google.com/p/phpquery/issues/detail?id=76 - case '^': - $pattern = '^'.$val; - break; - case '*': - $pattern = '.*'.$val.'.*'; - break; - case '$': - $pattern = '.*'.$val.'$'; - break; - } - // cut last character - $attr = substr($attr, 0, -1); - $isMatch = extension_loaded('mbstring') && phpQuery::$mbstringSupport - ? mb_ereg_match($pattern, $node->getAttribute($attr)) - : preg_match("@{$pattern}@", $node->getAttribute($attr)); - if (! $isMatch) - $break = true; - } else if ($node->getAttribute($attr) != $val) - $break = true; - } else if (! $node->hasAttribute($attr)) - $break = true; - // PSEUDO CLASSES - } else if ( $s[0] == ':') { - // skip - // TAG - } else if (trim($s)) { - if ($s != '*') { - // TODO namespaces - if (isset($node->tagName)) { - if ($node->tagName != $s) - $break = true; - } else if ($s == 'html' && ! $this->isRoot($node)) - $break = true; - } - // AVOID NON-SIMPLE SELECTORS - } else if (in_array($s, $notSimpleSelector)) { - $break = true; - $this->debug(array('Skipping non simple selector', $selector)); - } - } - if ($break) - break; - } - // if element passed all chunks of selector - add it to new stack - if (! $break ) - $stack[] = $node; - } - $tmpStack = $this->elements; - $this->elements = $stack; - // PER ALL NODES selector chunks - foreach($selector as $s) - // PSEUDO CLASSES - if ($s[0] == ':') - $this->pseudoClasses($s); - foreach($this->elements as $node) - // XXX it should be merged without duplicates - // but jQuery doesnt do that - $finalStack[] = $node; - $this->elements = $tmpStack; - } - $this->elements = $finalStack; - if ($_skipHistory) { - return $this; - } else { - $this->debug("Stack length after filter(): ".count($finalStack)); - return $this->newInstance(); - } - } - /** - * - * @param $value - * @return unknown_type - * @TODO implement in all methods using passed parameters - */ - protected static function unQuote($value) { - return $value[0] == '\'' || $value[0] == '"' - ? substr($value, 1, -1) - : $value; - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/load - * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo Support $selector - */ - public function load($url, $data = null, $callback = null) { - if ($data && ! is_array($data)) { - $callback = $data; - $data = null; - } - if (mb_strpos($url, ' ') !== false) { - $matches = null; - if (extension_loaded('mbstring') && phpQuery::$mbstringSupport) - mb_ereg('^([^ ]+) (.*)$', $url, $matches); - else - preg_match('@^([^ ]+) (.*)$@', $url, $matches); - $url = $matches[1]; - $selector = $matches[2]; - // FIXME this sucks, pass as callback param - $this->_loadSelector = $selector; - } - $ajax = array( - 'url' => $url, - 'type' => $data ? 'POST' : 'GET', - 'data' => $data, - 'complete' => $callback, - 'success' => array($this, '__loadSuccess') - ); - phpQuery::ajax($ajax); - return $this; - } - /** - * @access private - * @param $html - * @return unknown_type - */ - public function __loadSuccess($html) { - if ($this->_loadSelector) { - $html = phpQuery::newDocument($html)->find($this->_loadSelector); - unset($this->_loadSelector); - } - foreach($this->stack(1) as $node) { - phpQuery::pq($node, $this->getDocumentID()) - ->markup($html); - } - } - - /** - * Allows users to enter strings of CSS selectors. Useful - * when the CSS is loaded via style or @imports that phpQuery can't load - * because it doesn't know the URL context of the request. - */ - public function addCSS($string) { - if(!isset($this->cssString[$this->getDocumentID()])) { - $this->cssString[$this->getDocumentID()] = ''; - } - $this->cssString[$this->getDocumentID()] .= $string; - $this->parseCSS(); - } - /** - * Either sets the CSS property of an object or retrieves the - * CSS property of a proejct. - * - * @return string of css property value - * @todo - */ - public function css($property_name, $value = FALSE) { - if (!isset($this->cssIsParsed[$this->getDocumentID()]) - || $this->cssIsParsed[$this->getDocumentID()] = false) { - $this->parseCSS(); - } - $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); - if (!$value) { - if (isset($data[$property_name])) { - return $data[$property_name]['value']; - } - return null; - } - $specificity = (isset($data[$property_name])) ? $data[$property_name]['specificity'] - + 1 : 1000; - $data[$property_name] = array( - 'specificity' => $specificity, - 'value' => $value - ); - phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); - $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); - - if ($specificity >= 1000) { - $styles = array(); - foreach ($this->data('phpquery_css') as $k => $v) { - if ($v['specificity'] >= 1000) { - $styles[$k] = trim($k) . ':' . trim($v['value']); - } - } - ksort($styles); - if (empty($styles)) { - $this->removeAttr('style'); - } - elseif (phpQuery::$enableCssShorthand) { - $parser = new Sabberworm\CSS\Parser('{' . join(';', $styles) . '}'); - $doc = $parser->parse(); - $doc->createShorthands(); - $style = trim($doc->__toString(), "\n\r\t {}"); - } - else { - $style = join(';', $styles); - } - $this->attr('style', $style); - } - } - - public function parseCSS() { - if (!isset($this->cssString[$this->getDocumentID()])) { - $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) - . '/default.css'); - } - foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) { - $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); - } - - $CssParser = new CssParser($this->cssString[$this->getDocumentID()]); - $CssDocument = $CssParser->parse(); - foreach ($CssDocument->getAllRuleSets() as $ruleset) { - foreach ($ruleset->getSelector() as $selector) { - $specificity = $selector->getSpecificity(); - foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - if (phpQuery::$enableCssShorthand) { - $ruleset->expandShorthands(); - } - foreach ($ruleset->getRules() as $value) { - $rule = $value->getRule(); - if (!isset($existing[$rule]) - || $existing[$rule]['specificity'] <= $specificity) { - $value = $value->getValue(); - $value = (is_object($value)) ? $value->__toString() : $value; - $existing[$rule] = array( - 'specificity' => $specificity, - 'value' => $value - ); - } - } - phpQuery::pq($el)->data('phpquery_css', $existing); - $this->bubbleCSS(phpQuery::pq($el)); - } - } - } - foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - $style = pq($el)->attr('style'); - $style = strlen($style) ? explode(';', $style) : array(); - foreach ($this->attribute_css_mapping as $map => $css_equivalent) { - if ($el->hasAttribute($map)) { - $style[] = $css_equivalent . ':' . pq($el)->attr($map); - } - } - if (count($style)) { - $CssParser = new CssParser('#ruleset {' . implode(';', $style) . '}'); - $CssDocument = $CssParser->parse(); - $ruleset = $CssDocument->getAllRulesets(); - $ruleset = reset($ruleset); - if (phpQuery::$enableCssShorthand) { - $ruleset->expandShorthands(); - } - foreach ($ruleset->getRules() as $value) { - $rule = $value->getRule(); - if (!isset($existing[$rule]) - || 1000 >= $existing[$rule]['specificity']) { - $value = $value->getValue(); - $value = (is_object($value)) ? $value->__toString() : $value; - $existing[$rule] = array( - 'specificity' => 1000, - 'value' => $value - ); - } - } - phpQuery::pq($el)->data('phpquery_css', $existing); - $this->bubbleCSS(phpQuery::pq($el)); - } - } - } - - protected function bubbleCSS($element) { - $style = $element->data('phpquery_css'); - foreach($element->children() as $element_child) { - $existing = phpQuery::pq($element_child)->data('phpquery_css'); - foreach($style as $rule => $value) { - if(!isset($existing[$rule]) || $value['specificity'] > $existing[$rule]['specificity']) { - $existing[$rule] = $value; - } - } - phpQuery::pq($element_child)->data('phpquery_css', $existing); - if(phpQuery::pq($element_child)->children()->length) { - $this->bubbleCSS(phpQuery::pq($element_child)); - } - } - } - - /** - * @todo - * - */ - public function show(){ - $display = ($this->data('phpquery_display_state')) - ? $this->data('phpquery_display_state') - : 'block'; - $this->css('display', $display); - return $this; - } - /** - * @todo - * - */ - public function hide(){ - $this->data('phpquery_display_state', $this->css('display')); - $this->css('display', 'none'); - return $this; - } - /** - * Trigger a type of event on every matched element. - * - * @param unknown_type $type - * @param unknown_type $data - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support more than event in $type (space-separated) - */ - public function trigger($type, $data = array()) { - foreach($this->elements as $node) - phpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node); - return $this; - } - /** - * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. - * - * @param unknown_type $type - * @param unknown_type $data - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO - */ - public function triggerHandler($type, $data = array()) { - // TODO; - } - /** - * Binds a handler to one or more events (like click) for each matched element. - * Can also bind custom events. - * - * @param unknown_type $type - * @param unknown_type $data Optional - * @param unknown_type $callback - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support '!' (exclusive) events - * @TODO support more than event in $type (space-separated) - */ - public function bind($type, $data, $callback = null) { - // TODO check if $data is callable, not using is_callable - if (! isset($callback)) { - $callback = $data; - $data = null; - } - foreach($this->elements as $node) - phpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback); - return $this; - } - /** - * Enter description here... - * - * @param unknown_type $type - * @param unknown_type $callback - * @return unknown - * @TODO namespace events - * @TODO support more than event in $type (space-separated) - */ - public function unbind($type = null, $callback = null) { - foreach($this->elements as $node) - phpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback); - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function change($callback = null) { - if ($callback) - return $this->bind('change', $callback); - return $this->trigger('change'); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function submit($callback = null) { - if ($callback) - return $this->bind('submit', $callback); - return $this->trigger('submit'); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function click($callback = null) { - if ($callback) - return $this->bind('click', $callback); - return $this->trigger('click'); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAllOld($wrapper) { - $wrapper = pq($wrapper)->_clone(); - if (! $wrapper->length() || ! $this->length() ) - return $this; - $wrapper->insertBefore($this->elements[0]); - $deepest = $wrapper->elements[0]; - while($deepest->firstChild && $deepest->firstChild instanceof DOMELEMENT) - $deepest = $deepest->firstChild; - pq($deepest)->append($this); - return $this; - } - /** - * Enter description here... - * - * TODO testme... - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAll($wrapper) { - if (! $this->length()) - return $this; - return phpQuery::pq($wrapper, $this->getDocumentID()) - ->clone() - ->insertBefore($this->get(0)) - ->map(array($this, '___wrapAllCallback')) - ->append($this); - } - /** - * - * @param $node - * @return unknown_type - * @access private - */ - public function ___wrapAllCallback($node) { - $deepest = $node; - while($deepest->firstChild && $deepest->firstChild instanceof DOMELEMENT) - $deepest = $deepest->firstChild; - return $deepest; - } - /** - * Enter description here... - * NON JQUERY METHOD - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAllPHP($codeBefore, $codeAfter) { - return $this - ->slice(0, 1) - ->beforePHP($codeBefore) - ->end() - ->slice(-1) - ->afterPHP($codeAfter) - ->end(); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrap($wrapper) { - foreach($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapPHP($codeBefore, $codeAfter) { - foreach($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapInner($wrapper) { - foreach($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapInnerPHP($codeBefore, $codeAfter) { - foreach($this->stack(1) as $node) - phpQuery::pq($node, $this->getDocumentID())->contents() - ->wrapAllPHP($codeBefore, $codeAfter); - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @testme Support for text nodes - */ - public function contents() { - $stack = array(); - foreach($this->stack(1) as $el) { - // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56 -// if (! isset($el->childNodes)) -// continue; - foreach($el->childNodes as $node) { - $stack[] = $node; - } - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * jQuery difference. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function contentsUnwrap() { - foreach($this->stack(1) as $node) { - if (! $node->parentNode ) - continue; - $childNodes = array(); - // any modification in DOM tree breaks childNodes iteration, so cache them first - foreach($node->childNodes as $chNode ) - $childNodes[] = $chNode; - foreach($childNodes as $chNode ) -// $node->parentNode->appendChild($chNode); - $node->parentNode->insertBefore($chNode, $node); - $node->parentNode->removeChild($node); - } - return $this; - } - /** - * Enter description here... - * - * jQuery difference. - */ - public function switchWith($markup) { - $markup = pq($markup, $this->getDocumentID()); - $content = null; - foreach($this->stack(1) as $node) { - pq($node) - ->contents()->toReference($content)->end() - ->replaceWith($markup->clone()->append($content)); - } - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function eq($num) { - $oldStack = $this->elements; - $this->elementsBackup = $this->elements; - $this->elements = array(); - if ( isset($oldStack[$num]) ) - $this->elements[] = $oldStack[$num]; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function size() { - return count($this->elements); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @deprecated Use length as attribute - */ - public function length() { - return $this->size(); - } - public function count() { - return $this->size(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo $level - */ - public function end($level = 1) { -// $this->elements = array_pop( $this->history ); -// return $this; -// $this->previous->DOM = $this->DOM; -// $this->previous->XPath = $this->XPath; - return $this->previous - ? $this->previous - : $this; - } - /** - * Enter description here... - * Normal use ->clone() . - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _clone() { - $newStack = array(); - //pr(array('copy... ', $this->whois())); - //$this->dumpHistory('copy'); - $this->elementsBackup = $this->elements; - foreach($this->elements as $node) { - $newStack[] = $node->cloneNode(true); - } - $this->elements = $newStack; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function replaceWithPHP($code) { - return $this->replaceWith(phpQuery::php($code)); - } - /** - * Enter description here... - * - * @param String|phpQuery $content - * @link http://docs.jquery.com/Manipulation/replaceWith#content - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function replaceWith($content) { - return $this->after($content)->remove(); - } - /** - * Enter description here... - * - * @param String $selector - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo this works ? - */ - public function replaceAll($selector) { - foreach(phpQuery::pq($selector, $this->getDocumentID()) as $node) - phpQuery::pq($node, $this->getDocumentID()) - ->after($this->_clone()) - ->remove(); - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function remove($selector = null) { - $loop = $selector - ? $this->filter($selector)->elements - : $this->elements; - foreach($loop as $node) { - if (! $node->parentNode ) - continue; - if (isset($node->tagName)) - $this->debug("Removing '{$node->tagName}'"); - $node->parentNode->removeChild($node); - // Mutation event - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'DOMNodeRemoved' - )); - phpQueryEvents::trigger($this->getDocumentID(), - $event->type, array($event), $node - ); - } - return $this; - } - protected function markupEvents($newMarkup, $oldMarkup, $node) { - if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - phpQueryEvents::trigger($this->getDocumentID(), - $event->type, array($event), $node - ); - } - } - /** - * jQuey difference - * - * @param $markup - * @return unknown_type - * @TODO trigger change event for textarea - */ - public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - if ($this->documentWrapper->isXML) - return call_user_func_array(array($this, 'xml'), $args); - else - return call_user_func_array(array($this, 'html'), $args); - } - /** - * jQuey difference - * - * @param $markup - * @return unknown_type - */ - public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - if ($this->documentWrapper->isXML) - return call_user_func_array(array($this, 'xmlOuter'), $args); - else - return call_user_func_array(array($this, 'htmlOuter'), $args); - } - /** - * Enter description here... - * - * @param unknown_type $html - * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO force html result - */ - public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (isset($html)) { - // INSERT - $nodes = $this->documentWrapper->import($html); - $this->empty(); - foreach($this->stack(1) as $alreadyAdded => $node) { - // for now, limit events for textarea - if (($this->isXHTML() || $this->isHTML()) && $node->tagName == 'textarea') - $oldHtml = pq($node, $this->getDocumentID())->markup(); - foreach($nodes as $newNode) { - $node->appendChild($alreadyAdded - ? $newNode->cloneNode(true) - : $newNode - ); - } - // for now, limit events for textarea - if (($this->isXHTML() || $this->isHTML()) && $node->tagName == 'textarea') - $this->markupEvents($html, $oldHtml, $node); - } - return $this; - } else { - // FETCH - $return = $this->documentWrapper->markup($this->elements, true); - $args = func_get_args(); - foreach(array_slice($args, 1) as $callback) { - $return = phpQuery::callbackRun($callback, array($return)); - } - return $return; - } - } - /** - * @TODO force xml result - */ - public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - return call_user_func_array(array($this, 'html'), $args); - } - /** - * Enter description here... - * @TODO force html result - * - * @return String - */ - public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $markup = $this->documentWrapper->markup($this->elements); - // pass thou callbacks - $args = func_get_args(); - foreach($args as $callback) { - $markup = phpQuery::callbackRun($callback, array($markup)); - } - return $markup; - } - /** - * @TODO force xml result - */ - public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - return call_user_func_array(array($this, 'htmlOuter'), $args); - } - public function __toString() { - return $this->markupOuter(); - } - /** - * Just like html(), but returns markup with VALID (dangerous) PHP tags. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo support returning markup with PHP tags when called without param - */ - public function php($code = null) { - return $this->markupPHP($code); - } - /** - * Enter description here... - * - * @param $code - * @return unknown_type - */ - public function markupPHP($code = null) { - return isset($code) - ? $this->markup(phpQuery::php($code)) - : phpQuery::markupToPHP($this->markup()); - } - /** - * Enter description here... - * - * @param $code - * @return unknown_type - */ - public function markupOuterPHP() { - return phpQuery::markupToPHP($this->markupOuter()); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function children($selector = null) { - $stack = array(); - foreach($this->stack(1) as $node) { -// foreach($node->getElementsByTagName('*') as $newNode) { - foreach($node->childNodes as $newNode) { - if ($newNode->nodeType != 1) - continue; - if ($selector && ! $this->is($selector, $newNode)) - continue; - if ($this->elementsContainsNode($newNode, $stack)) - continue; - $stack[] = $newNode; - } - } - $this->elementsBackup = $this->elements; - $this->elements = $stack; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function ancestors($selector = null) { - return $this->children( $selector ); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function append( $content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function appendPHP( $content) { - return $this->insert("", 'append'); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function appendTo( $seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prepend( $content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @todo accept many arguments, which are joined, arrays maybe also - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prependPHP( $content) { - return $this->insert("", 'prepend'); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prependTo( $seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function before($content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function beforePHP( $content) { - return $this->insert("", 'before'); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function insertBefore( $seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function after( $content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function afterPHP( $content) { - return $this->insert("", 'after'); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function insertAfter( $seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Internal insert method. Don't use it. - * - * @param unknown_type $target - * @param unknown_type $type - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function insert($target, $type) { - $this->debug("Inserting data with '{$type}'"); - $to = false; - switch( $type) { - case 'appendTo': - case 'prependTo': - case 'insertBefore': - case 'insertAfter': - $to = true; - } - switch(gettype($target)) { - case 'string': - $insertFrom = $insertTo = array(); - if ($to) { - // INSERT TO - $insertFrom = $this->elements; - if (phpQuery::isMarkup($target)) { - // $target is new markup, import it - $insertTo = $this->documentWrapper->import($target); - // insert into selected element - } else { - // $tagret is a selector - $thisStack = $this->elements; - $this->toRoot(); - $insertTo = $this->find($target)->elements; - $this->elements = $thisStack; - } - } else { - // INSERT FROM - $insertTo = $this->elements; - $insertFrom = $this->documentWrapper->import($target); - } - break; - case 'object': - $insertFrom = $insertTo = array(); - // phpQuery - if ($target instanceof self) { - if ($to) { - $insertTo = $target->elements; - if ($this->documentFragment && $this->stackIsRoot()) - // get all body children -// $loop = $this->find('body > *')->elements; - // TODO test it, test it hard... -// $loop = $this->newInstance($this->root)->find('> *')->elements; - $loop = $this->root->childNodes; - else - $loop = $this->elements; - // import nodes if needed - $insertFrom = $this->getDocumentID() == $target->getDocumentID() - ? $loop - : $target->documentWrapper->import($loop); - } else { - $insertTo = $this->elements; - if ( $target->documentFragment && $target->stackIsRoot() ) - // get all body children -// $loop = $target->find('body > *')->elements; - $loop = $target->root->childNodes; - else - $loop = $target->elements; - // import nodes if needed - $insertFrom = $this->getDocumentID() == $target->getDocumentID() - ? $loop - : $this->documentWrapper->import($loop); - } - // DOMNODE - } elseif ($target instanceof DOMNODE) { - // import node if needed -// if ( $target->ownerDocument != $this->DOM ) -// $target = $this->DOM->importNode($target, true); - if ( $to) { - $insertTo = array($target); - if ($this->documentFragment && $this->stackIsRoot()) - // get all body children - $loop = $this->root->childNodes; -// $loop = $this->find('body > *')->elements; - else - $loop = $this->elements; - foreach($loop as $fromNode) - // import nodes if needed - $insertFrom[] = ! $fromNode->ownerDocument->isSameNode($target->ownerDocument) - ? $target->ownerDocument->importNode($fromNode, true) - : $fromNode; - } else { - // import node if needed - if (! $target->ownerDocument->isSameNode($this->document)) - $target = $this->document->importNode($target, true); - $insertTo = $this->elements; - $insertFrom[] = $target; - } - } - break; - } - phpQuery::debug("From ".count($insertFrom)."; To ".count($insertTo)." nodes"); - foreach($insertTo as $insertNumber => $toNode) { - // we need static relative elements in some cases - switch( $type) { - case 'prependTo': - case 'prepend': - $firstChild = $toNode->firstChild; - break; - case 'insertAfter': - case 'after': - $nextSibling = $toNode->nextSibling; - break; - } - foreach($insertFrom as $fromNode) { - // clone if inserted already before - $insert = $insertNumber - ? $fromNode->cloneNode(true) - : $fromNode; - switch($type) { - case 'appendTo': - case 'append': -// $toNode->insertBefore( -// $fromNode, -// $toNode->lastChild->nextSibling -// ); - $toNode->appendChild($insert); - $eventTarget = $insert; - break; - case 'prependTo': - case 'prepend': - $toNode->insertBefore( - $insert, - $firstChild - ); - break; - case 'insertBefore': - case 'before': - if (! $toNode->parentNode) - throw new Exception("No parentNode, can't do {$type}()"); - else - $toNode->parentNode->insertBefore( - $insert, - $toNode - ); - break; - case 'insertAfter': - case 'after': - if (! $toNode->parentNode) - throw new Exception("No parentNode, can't do {$type}()"); - else - $toNode->parentNode->insertBefore( - $insert, - $nextSibling - ); - break; - } - // Mutation event - $event = new DOMEvent(array( - 'target' => $insert, - 'type' => 'DOMNodeInserted' - )); - phpQueryEvents::trigger($this->getDocumentID(), - $event->type, array($event), $insert - ); - } - } - return $this; - } - /** - * Enter description here... - * - * @return Int - */ - public function index($subject) { - $index = -1; - $subject = $subject instanceof phpQueryObject - ? $subject->elements[0] - : $subject; - foreach($this->newInstance() as $k => $node) { - if ($node->isSameNode($subject)) - $index = $k; - } - return $index; - } - /** - * Enter description here... - * - * @param unknown_type $start - * @param unknown_type $end - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @testme - */ - public function slice($start, $end = null) { -// $last = count($this->elements)-1; -// $end = $end -// ? min($end, $last) -// : $last; -// if ($start < 0) -// $start = $last+$start; -// if ($start > $last) -// return array(); - if ($end > 0) - $end = $end-$start; - return $this->newInstance( - array_slice($this->elements, $start, $end) - ); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function reverse() { - $this->elementsBackup = $this->elements; - $this->elements = array_reverse($this->elements); - return $this->newInstance(); - } - /** - * Return joined text content. - * @return String - */ - public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (isset($text)) - return $this->html(htmlspecialchars($text)); - $args = func_get_args(); - $args = array_slice($args, 1); - $return = ''; - foreach($this->elements as $node) { - $text = $node->textContent; - if (count($this->elements) > 1 && $text) - $text .= "\n"; - foreach($args as $callback) { - $text = phpQuery::callbackRun($callback, array($text)); - } - $return .= $text; - } - return $return; - } - - /** - * @return The text content of each matching element, like - * text() but returns an array with one entry per matched element. - * Read only. - */ - public function texts($attr = null) { - $results = array(); - foreach($this->elements as $node) { - $results[] = $node->textContent; - } - return $results; - } - - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function plugin($class, $file = null) { - phpQuery::plugin($class, $file); - return $this; - } - /** - * Deprecated, use $pq->plugin() instead. - * - * @deprecated - * @param $class - * @param $file - * @return unknown_type - */ - public static function extend($class, $file = null) { - return $this->plugin($class, $file); - } - /** - * - * @access private - * @param $method - * @param $args - * @return unknown_type - */ - public function __call($method, $args) { - $aliasMethods = array('clone', 'empty'); - if (isset(phpQuery::$extendMethods[$method])) { - array_unshift($args, $this); - return phpQuery::callbackRun( - phpQuery::$extendMethods[$method], $args - ); - } else if (isset(phpQuery::$pluginsMethods[$method])) { - array_unshift($args, $this); - $class = phpQuery::$pluginsMethods[$method]; - $realClass = "phpQueryObjectPlugin_$class"; - $return = call_user_func_array( - array($realClass, $method), - $args - ); - // XXX deprecate ? - return is_null($return) - ? $this - : $return; - } else if (in_array($method, $aliasMethods)) { - return call_user_func_array(array($this, '_'.$method), $args); - } else - throw new Exception("Method '{$method}' doesnt exist"); - } - /** - * Safe rename of next(). - * - * Use it ONLY when need to call next() on an iterated object (in same time). - * Normaly there is no need to do such thing ;) - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _next($selector = null) { - return $this->newInstance( - $this->getElementSiblings('nextSibling', $selector, true) - ); - } - /** - * Use prev() and next(). - * - * @deprecated - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _prev($selector = null) { - return $this->prev($selector); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prev($selector = null) { - return $this->newInstance( - $this->getElementSiblings('previousSibling', $selector, true) - ); - } - /** - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo - */ - public function prevAll($selector = null) { - return $this->newInstance( - $this->getElementSiblings('previousSibling', $selector) - ); - } - /** - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo FIXME: returns source elements insted of next siblings - */ - public function nextAll($selector = null) { - return $this->newInstance( - $this->getElementSiblings('nextSibling', $selector) - ); - } - /** - * @access private - */ - protected function getElementSiblings($direction, $selector = null, $limitToOne = false) { - $stack = array(); - $count = 0; - foreach($this->stack() as $node) { - $test = $node; - while( isset($test->{$direction}) && $test->{$direction}) { - $test = $test->{$direction}; - if (! $test instanceof DOMELEMENT) - continue; - $stack[] = $test; - if ($limitToOne) - break; - } - } - if ($selector) { - $stackOld = $this->elements; - $this->elements = $stack; - $stack = $this->filter($selector, true)->stack(); - $this->elements = $stackOld; - } - return $stack; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function siblings($selector = null) { - $stack = array(); - $siblings = array_merge( - $this->getElementSiblings('previousSibling', $selector), - $this->getElementSiblings('nextSibling', $selector) - ); - foreach($siblings as $node) { - if (! $this->elementsContainsNode($node, $stack)) - $stack[] = $node; - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function not($selector = null) { - if (is_string($selector)) - phpQuery::debug(array('not', $selector)); - else - phpQuery::debug('not'); - $stack = array(); - if ($selector instanceof self || $selector instanceof DOMNODE) { - foreach($this->stack() as $node) { - if ($selector instanceof self) { - $matchFound = false; - foreach($selector->stack() as $notNode) { - if ($notNode->isSameNode($node)) - $matchFound = true; - } - if (! $matchFound) - $stack[] = $node; - } else if ($selector instanceof DOMNODE) { - if (! $selector->isSameNode($node)) - $stack[] = $node; - } else { - if (! $this->is($selector)) - $stack[] = $node; - } - } - } else { - $orgStack = $this->stack(); - $matched = $this->filter($selector, true)->stack(); -// $matched = array(); -// // simulate OR in filter() instead of AND 5y -// foreach($this->parseSelector($selector) as $s) { -// $matched = array_merge($matched, -// $this->filter(array($s))->stack() -// ); -// } - foreach($orgStack as $node) - if (! $this->elementsContainsNode($node, $matched)) - $stack[] = $node; - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * @param string|phpQueryObject - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function add($selector = null) { - if (! $selector) - return $this; - $stack = array(); - $this->elementsBackup = $this->elements; - $found = phpQuery::pq($selector, $this->getDocumentID()); - $this->merge($found->elements); - return $this->newInstance(); - } - /** - * @access private - */ - protected function merge() { - foreach(func_get_args() as $nodes) - foreach($nodes as $newNode ) - if (! $this->elementsContainsNode($newNode) ) - $this->elements[] = $newNode; - } - /** - * @access private - * TODO refactor to stackContainsNode - */ - protected function elementsContainsNode($nodeToCheck, $elementsStack = null) { - $loop = ! is_null($elementsStack) - ? $elementsStack - : $this->elements; - foreach($loop as $node) { - if ( $node->isSameNode( $nodeToCheck ) ) - return true; - } - return false; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function parent($selector = null) { - $stack = array(); - foreach($this->elements as $node ) - if ( $node->parentNode && ! $this->elementsContainsNode($node->parentNode, $stack) ) - $stack[] = $node->parentNode; - $this->elementsBackup = $this->elements; - $this->elements = $stack; - if ( $selector ) - $this->filter($selector, true); - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function parents($selector = null) { - $stack = array(); - if (! $this->elements ) - $this->debug('parents() - stack empty'); - foreach($this->elements as $node) { - $test = $node; - while( $test->parentNode) { - $test = $test->parentNode; - if ($this->isRoot($test)) - break; - if (! $this->elementsContainsNode($test, $stack)) { - $stack[] = $test; - continue; - } - } - } - $this->elementsBackup = $this->elements; - $this->elements = $stack; - if ( $selector ) - $this->filter($selector, true); - return $this->newInstance(); - } - /** - * Internal stack iterator. - * - * @access private - * @return {Array.} - */ - public function stack($nodeTypes = null) { - if (!isset($nodeTypes)) - return $this->elements; - if (!is_array($nodeTypes)) - $nodeTypes = array($nodeTypes); - $return = array(); - foreach($this->elements as $node) { - if (in_array($node->nodeType, $nodeTypes)) - $return[] = $node; - } - return $return; - } - // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes - protected function attrEvents($attr, $oldAttr, $oldValue, $node) { - // skip events for XML documents - if (! $this->isXHTML() && ! $this->isHTML()) - return; - $event = null; - // identify - $isInputValue = $node->tagName == 'input' - && ( - in_array($node->getAttribute('type'), - array('text', 'password', 'hidden')) - || !$node->getAttribute('type') - ); - $isRadio = $node->tagName == 'input' - && $node->getAttribute('type') == 'radio'; - $isCheckbox = $node->tagName == 'input' - && $node->getAttribute('type') == 'checkbox'; - $isOption = $node->tagName == 'option'; - if ($isInputValue && $attr == 'value' && $oldValue != $node->getAttribute($attr)) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - } else if (($isRadio || $isCheckbox) && $attr == 'checked' && ( - // check - (! $oldAttr && $node->hasAttribute($attr)) - // un-check - || (! $node->hasAttribute($attr) && $oldAttr) - )) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - } else if ($isOption && $node->parentNode && $attr == 'selected' && ( - // select - (! $oldAttr && $node->hasAttribute($attr)) - // un-select - || (! $node->hasAttribute($attr) && $oldAttr) - )) { - $event = new DOMEvent(array( - 'target' => $node->parentNode, - 'type' => 'change' - )); - } - if ($event) { - phpQueryEvents::trigger($this->getDocumentID(), - $event->type, array($event), $node - ); - } - } - public function attr($attr = null, $value = null) { - foreach($this->stack(1) as $node) { - if (! is_null($value)) { - $loop = $attr == '*' - ? $this->getNodeAttrs($node) - : array($attr); - foreach($loop as $a) { - $oldValue = $node->getAttribute($a); - $oldAttr = $node->hasAttribute($a); - // TODO raises an error when charset other than UTF-8 - // while document's charset is also not UTF-8 - @$node->setAttribute($a, $value); - $this->attrEvents($a, $oldAttr, $oldValue, $node); - } - } else if ($attr == '*') { - // jQuery difference - $return = array(); - foreach($node->attributes as $n => $v) - $return[$n] = $v->value; - return $return; - } else - return $node->hasAttribute($attr) - ? $node->getAttribute($attr) - : null; - } - return is_null($value) - ? '' : $this; - } - - /** - * @return The same attribute of each matching element, like - * attr() but returns an array with one entry per matched element. - * Read only. - */ - public function attrs($attr = null) { - $results = array(); - foreach($this->stack(1) as $node) { - $results[] = $node->hasAttribute($attr) - ? $node->getAttribute($attr) - : null; - } - return $results; - } - - /** - * @access private - */ - protected function getNodeAttrs($node) { - $return = array(); - foreach($node->attributes as $n => $o) - $return[] = $n; - return $return; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo check CDATA ??? - */ - public function attrPHP($attr, $code) { - if (! is_null($code)) { - $value = '<'.'?php '.$code.' ?'.'>'; - // TODO tempolary solution - // http://code.google.com/p/phpquery/issues/detail?id=17 -// if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII') -// $value = mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES'); - } - foreach($this->stack(1) as $node) { - if (! is_null($code)) { -// $attrNode = $this->DOM->createAttribute($attr); - $node->setAttribute($attr, $value); -// $attrNode->value = $value; -// $node->appendChild($attrNode); - } else if ( $attr == '*') { - // jQuery diff - $return = array(); - foreach($node->attributes as $n => $v) - $return[$n] = $v->value; - return $return; - } else - return $node->getAttribute($attr); - } - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function removeAttr($attr) { - foreach($this->stack(1) as $node) { - $loop = $attr == '*' - ? $this->getNodeAttrs($node) - : array($attr); - foreach($loop as $a) { - $oldValue = $node->getAttribute($a); - $node->removeAttribute($a); - $this->attrEvents($a, $oldValue, null, $node); - } - } - return $this; - } - /** - * Return form element value. - * - * @return String Fields value. - */ - public function val($val = null) { - if (! isset($val)) { - if ($this->eq(0)->is('select')) { - $selected = $this->eq(0)->find('option[selected=selected]'); - if ($selected->is('[value]')) - return $selected->attr('value'); - else - return $selected->text(); - } else if ($this->eq(0)->is('textarea')) - return $this->eq(0)->markup(); - else - return $this->eq(0)->attr('value'); - } else { - $_val = null; - foreach($this->stack(1) as $node) { - $node = pq($node, $this->getDocumentID()); - if (is_array($val) && in_array($node->attr('type'), array('checkbox', 'radio'))) { - $isChecked = in_array($node->attr('value'), $val) - || in_array($node->attr('name'), $val); - if ($isChecked) - $node->attr('checked', 'checked'); - else - $node->removeAttr('checked'); - } else if ($node->get(0)->tagName == 'select') { - if (! isset($_val)) { - $_val = array(); - if (! is_array($val)) - $_val = array((string)$val); - else - foreach($val as $v) - $_val[] = $v; - } - foreach($node['option']->stack(1) as $option) { - $option = pq($option, $this->getDocumentID()); - $selected = false; - // XXX: workaround for string comparsion, see issue #96 - // http://code.google.com/p/phpquery/issues/detail?id=96 - $selected = is_null($option->attr('value')) - ? in_array($option->markup(), $_val) - : in_array($option->attr('value'), $_val); -// $optionValue = $option->attr('value'); -// $optionText = $option->text(); -// $optionTextLenght = mb_strlen($optionText); -// foreach($_val as $v) -// if ($optionValue == $v) -// $selected = true; -// else if ($optionText == $v && $optionTextLenght == mb_strlen($v)) -// $selected = true; - if ($selected) - $option->attr('selected', 'selected'); - else - $option->removeAttr('selected'); - } - } else if ($node->get(0)->tagName == 'textarea') - $node->markup($val); - else - $node->attr('value', $val); - } - } - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function andSelf() { - if ( $this->previous ) - $this->elements = array_merge($this->elements, $this->previous->elements); - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function addClass( $className) { - if (! $className) - return $this; - foreach($this->stack(1) as $node) { - if (! $this->is(".$className", $node)) - $node->setAttribute( - 'class', - trim($node->getAttribute('class').' '.$className) - ); - } - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function addClassPHP( $className) { - foreach($this->stack(1) as $node) { - $classes = $node->getAttribute('class'); - $newValue = $classes - ? $classes.' <'.'?php '.$className.' ?'.'>' - : '<'.'?php '.$className.' ?'.'>'; - $node->setAttribute('class', $newValue); - } - return $this; - } - /** - * Enter description here... - * - * @param string $className - * @return bool - */ - public function hasClass($className) { - foreach($this->stack(1) as $node) { - if ( $this->is(".$className", $node)) - return true; - } - return false; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function removeClass($className) { - foreach($this->stack(1) as $node) { - $classes = explode( ' ', $node->getAttribute('class')); - if ( in_array($className, $classes)) { - $classes = array_diff($classes, array($className)); - if ( $classes ) - $node->setAttribute('class', implode(' ', $classes)); - else - $node->removeAttribute('class'); - } - } - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toggleClass($className) { - foreach($this->stack(1) as $node) { - if ( $this->is( $node, '.'.$className )) - $this->removeClass($className); - else - $this->addClass($className); - } - return $this; - } - /** - * Proper name without underscore (just ->empty()) also works. - * - * Removes all child nodes from the set of matched elements. - * - * Example: - * pq("p")._empty() - * - * HTML: - *

    Hello, Person and person

    - * - * Result: - * [

    ] - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _empty() { - foreach($this->stack(1) as $node) { - // thx to 'dave at dgx dot cz' - $node->nodeValue = ''; - } - return $this; - } - /** - * Enter description here... - * - * @param array|string $callback Expects $node as first param, $index as second - * @param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope) - * @param array $arg1 Will ba passed as third and futher args to callback. - * @param array $arg2 Will ba passed as fourth and futher args to callback, and so on... - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function each($callback, $param1 = null, $param2 = null, $param3 = null) { - $paramStructure = null; - if (func_num_args() > 1) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 1); - } - foreach($this->elements as $v) - phpQuery::callbackRun($callback, array($v), $paramStructure); - return $this; - } - /** - * Run callback on actual object. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function callback($callback, $param1 = null, $param2 = null, $param3 = null) { - $params = func_get_args(); - $params[0] = $this; - phpQuery::callbackRun($callback, $params); - return $this; - } - /** - * Enter description here... - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo add $scope and $args as in each() ??? - */ - public function map($callback, $param1 = null, $param2 = null, $param3 = null) { -// $stack = array(); -//// foreach($this->newInstance() as $node) { -// foreach($this->newInstance() as $node) { -// $result = call_user_func($callback, $node); -// if ($result) -// $stack[] = $result; -// } - $params = func_get_args(); - array_unshift($params, $this->elements); - return $this->newInstance( - call_user_func_array(array('phpQuery', 'map'), $params) -// phpQuery::map($this->elements, $callback) - ); - } - /** - * Enter description here... - * - * @param $key - * @param $value - */ - public function data($key, $value = null) { - if (! isset($value)) { - // TODO? implement specific jQuery behavior od returning parent values - // is child which we look up doesn't exist - return phpQuery::data($this->get(0), $key, $value, $this->getDocumentID()); - } else { - foreach($this as $node) - phpQuery::data($node, $key, $value, $this->getDocumentID()); - return $this; - } - } - /** - * Enter description here... - * - * @param $key - */ - public function removeData($key) { - foreach($this as $node) - phpQuery::removeData($node, $key, $this->getDocumentID()); - return $this; - } - // INTERFACE IMPLEMENTATIONS - - // ITERATOR INTERFACE - /** - * @access private - */ - public function rewind(){ - $this->debug('iterating foreach'); -// phpQuery::selectDocument($this->getDocumentID()); - $this->elementsBackup = $this->elements; - $this->elementsInterator = $this->elements; - $this->valid = isset( $this->elements[0] ) - ? 1 : 0; -// $this->elements = $this->valid -// ? array($this->elements[0]) -// : array(); - $this->current = 0; - } - /** - * @access private - */ - public function current(){ - return $this->elementsInterator[ $this->current ]; - } - /** - * @access private - */ - public function key(){ - return $this->current; - } - /** - * Double-function method. - * - * First: main iterator interface method. - * Second: Returning next sibling, alias for _next(). - * - * Proper functionality is choosed automagicaly. - * - * @see phpQueryObject::_next() - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function next($cssSelector = null){ -// if ($cssSelector || $this->valid) -// return $this->_next($cssSelector); - $this->valid = isset( $this->elementsInterator[ $this->current+1 ] ) - ? true - : false; - if (! $this->valid && $this->elementsInterator) { - $this->elementsInterator = null; - } else if ($this->valid) { - $this->current++; - } else { - return $this->_next($cssSelector); - } - } - /** - * @access private - */ - public function valid(){ - return $this->valid; - } - // ITERATOR INTERFACE END - // ARRAYACCESS INTERFACE - /** - * @access private - */ - public function offsetExists($offset) { - return $this->find($offset)->size() > 0; - } - /** - * @access private - */ - public function offsetGet($offset) { - return $this->find($offset); - } - /** - * @access private - */ - public function offsetSet($offset, $value) { -// $this->find($offset)->replaceWith($value); - $this->find($offset)->html($value); - } - /** - * @access private - */ - public function offsetUnset($offset) { - // empty - throw new Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); - } - // ARRAYACCESS INTERFACE END - /** - * Returns node's XPath. - * - * @param unknown_type $oneNode - * @return string - * @TODO use native getNodePath is avaible - * @access private - */ - protected function getNodeXpath($oneNode = null, $namespace = null) { - $return = array(); - $loop = $oneNode - ? array($oneNode) - : $this->elements; -// if ($namespace) -// $namespace .= ':'; - foreach($loop as $node) { - if ($node instanceof DOMDOCUMENT) { - $return[] = ''; - continue; - } - $xpath = array(); - while(! ($node instanceof DOMDOCUMENT)) { - $i = 1; - $sibling = $node; - while($sibling->previousSibling) { - $sibling = $sibling->previousSibling; - $isElement = $sibling instanceof DOMELEMENT; - if ($isElement && $sibling->tagName == $node->tagName) - $i++; - } - $xpath[] = $this->isXML() - ? "*[local-name()='{$node->tagName}'][{$i}]" - : "{$node->tagName}[{$i}]"; - $node = $node->parentNode; - } - $xpath = implode('/', array_reverse($xpath)); - $return[] = '/'.$xpath; - } - return $oneNode - ? $return[0] - : $return; - } - // HELPERS - public function whois($oneNode = null) { - $return = array(); - $loop = $oneNode - ? array( $oneNode ) - : $this->elements; - foreach($loop as $node) { - if (isset($node->tagName)) { - $tag = in_array($node->tagName, array('php', 'js')) - ? strtoupper($node->tagName) - : $node->tagName; - $return[] = $tag - .($node->getAttribute('id') - ? '#'.$node->getAttribute('id'):'') - .($node->getAttribute('class') - ? '.'.implode('.', explode(' ', $node->getAttribute('class'))):'') - .($node->getAttribute('name') - ? '[name="'.$node->getAttribute('name').'"]':'') - .($node->getAttribute('value') && strpos($node->getAttribute('value'), '<'.'?php') === false - ? '[value="'.substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15).'"]':'') - .($node->getAttribute('value') && strpos($node->getAttribute('value'), '<'.'?php') !== false - ? '[value=PHP]':'') - .($node->getAttribute('selected') - ? '[selected]':'') - .($node->getAttribute('checked') - ? '[checked]':'') - ; - } else if ($node instanceof DOMTEXT) { - if (trim($node->textContent)) - $return[] = 'Text:'.substr(str_replace("\n", ' ', $node->textContent), 0, 15); - } else { - - } - } - return $oneNode && isset($return[0]) - ? $return[0] - : $return; - } - /** - * Dump htmlOuter and preserve chain. Usefull for debugging. - * - * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * - */ - public function dump() { - print 'DUMP #'.(phpQuery::$dumpCount++).' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; -// print __FILE__.':'.__LINE__."\n"; - var_dump($this->htmlOuter()); - return $this; - } - public function dumpWhois() { - print 'DUMP #'.(phpQuery::$dumpCount++).' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; -// print __FILE__.':'.__LINE__."\n"; - var_dump('whois', $this->whois()); - phpQuery::$debug = $debug; - return $this; - } - public function dumpLength() { - print 'DUMP #'.(phpQuery::$dumpCount++).' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; -// print __FILE__.':'.__LINE__."\n"; - var_dump('length', $this->length()); - phpQuery::$debug = $debug; - return $this; - } - public function dumpTree($html = true, $title = true) { - $output = $title - ? 'DUMP #'.(phpQuery::$dumpCount++)." \n" : ''; - $debug = phpQuery::$debug; - phpQuery::$debug = false; - foreach($this->stack() as $node) - $output .= $this->__dumpTree($node); - phpQuery::$debug = $debug; - print $html - ? nl2br(str_replace(' ', ' ', $output)) - : $output; - return $this; - } - private function __dumpTree($node, $intend = 0) { - $whois = $this->whois($node); - $return = ''; - if ($whois) - $return .= str_repeat(' - ', $intend).$whois."\n"; - if (isset($node->childNodes)) - foreach($node->childNodes as $chNode) - $return .= $this->__dumpTree($chNode, $intend+1); - return $return; - } - /** - * Dump htmlOuter and stop script execution. Usefull for debugging. - * - */ - public function dumpDie() { - print __FILE__.':'.__LINE__; - var_dump($this->htmlOuter()); - die(); - } -} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2a493cb..8840bd9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -19,7 +19,7 @@ - ./unit-tests/test.php + ./src/Tests/ diff --git a/phpQuery/phpQuery/Callback.php b/src/Callback/Callback.php similarity index 100% rename from phpQuery/phpQuery/Callback.php rename to src/Callback/Callback.php diff --git a/src/Dom/DomDocumentWrapper.php b/src/Dom/DomDocumentWrapper.php new file mode 100644 index 0000000..f2a468b --- /dev/null +++ b/src/Dom/DomDocumentWrapper.php @@ -0,0 +1,709 @@ + changes to
    + * + * @todo check XML catalogs compatibility + * @author Tobiasz Cudnik + * @package phpQuery + */ +class DOMDocumentWrapper { + /** + * @var \DOMDocument + */ + public $document; + public $id; + /** + * @todo Rewrite as method and quess if null. + * @var unknown_type + */ + public $contentType = ''; + public $xpath; + public $uuid = 0; + public $data = array(); + public $dataNodes = array(); + public $events = array(); + public $eventsNodes = array(); + public $eventsGlobal = array(); + /** + * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28 + * @var unknown_type + */ + public $frames = array(); + /** + * Document root, by default equals to document itself. + * Used by documentFragments. + * + * @var \DOMNode + */ + public $root; + public $isDocumentFragment; + public $isXML = false; + public $isXHTML = false; + public $isHTML = false; + public $charset; + public function __construct($markup = null, $contentType = null, $newDocumentID = null) { + if (isset($markup)) + $this->load($markup, $contentType, $newDocumentID); + $this->id = $newDocumentID ? $newDocumentID : md5(microtime()); + } + public function load($markup, $contentType = null, $newDocumentID = null) { + // phpQuery::$documents[$id] = $this; + $this->contentType = strtolower($contentType); + if ($markup instanceof \DOMDocument) { + $this->document = $markup; + $this->root = $this->document; + $this->charset = $this->document->encoding; + // TODO isDocumentFragment + $loaded = true; + } + else { + $loaded = $this->loadMarkup($markup); + } + if ($loaded) { + // $this->document->formatOutput = true; + $this->document->preserveWhiteSpace = true; + $this->xpath = new \DOMXPath($this->document); + $this->afterMarkupLoad(); + return true; + // remember last loaded document + // return phpQuery::selectDocument($id); + } + return false; + } + protected function afterMarkupLoad() { + if ($this->isXHTML) { + $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml"); + } + } + protected function loadMarkup($markup) { + $loaded = false; + if ($this->contentType) { + self::debug("Load markup for content type {$this->contentType}"); + // content determined by contentType + list($contentType, $charset) = $this->contentTypeToArray($this->contentType); + switch ($contentType) { + case 'text/html': + phpQuery::debug("Loading HTML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupHTML($markup, $charset); + break; + case 'text/xml': + case 'application/xhtml+xml': + phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupXML($markup, $charset); + break; + default: + // for feeds or anything that sometimes doesn't use text/xml + if (strpos('xml', $this->contentType) !== false) { + phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupXML($markup, $charset); + } + else + phpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); + } + } + else { + // content type autodetection + if ($this->isXML($markup)) { + phpQuery::debug("Loading XML, isXML() == true"); + $loaded = $this->loadMarkupXML($markup); + if (!$loaded && $this->isXHTML) { + phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); + $loaded = $this->loadMarkupHTML($markup); + } + } + else { + phpQuery::debug("Loading HTML, isXML() == false"); + $loaded = $this->loadMarkupHTML($markup); + } + } + return $loaded; + } + protected function loadMarkupReset() { + $this->isXML = $this->isXHTML = $this->isHTML = false; + } + protected function documentCreate($charset, $version = '1.0') { + if (!$version) + $version = '1.0'; + $this->document = new \DOMDocument($version, $charset); + $this->charset = $this->document->encoding; + // $this->document->encoding = $charset; + $this->document->formatOutput = true; + $this->document->preserveWhiteSpace = true; + } + protected function loadMarkupHTML($markup, $requestedCharset = null) { + if (phpQuery::$debug) + phpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250)); + $this->loadMarkupReset(); + $this->isHTML = true; + if (!isset($this->isDocumentFragment)) + $this->isDocumentFragment = self::isDocumentFragmentHTML($markup); + $charset = null; + $documentCharset = $this->charsetFromHTML($markup); + $addDocumentCharset = false; + if ($documentCharset) { + $charset = $documentCharset; + $markup = $this->charsetFixHTML($markup); + } + else if ($requestedCharset) { + $charset = $requestedCharset; + } + if (!$charset) + $charset = phpQuery::$defaultCharset; + // HTTP 1.1 says that the default charset is ISO-8859-1 + // @see http://www.w3.org/International/O-HTTP-charset + if (!$documentCharset) { + $documentCharset = 'ISO-8859-1'; + $addDocumentCharset = true; + } + // Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding' + // Worse, some pages can have mixed encodings... we'll try not to worry about that + $requestedCharset = strtoupper($requestedCharset); + $documentCharset = strtoupper($documentCharset); + phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); + if ($requestedCharset && $documentCharset + && $requestedCharset !== $documentCharset) { + phpQuery::debug("CHARSET CONVERT"); + // Document Encoding Conversion + // http://code.google.com/p/phpquery/issues/detail?id=86 + if (function_exists('mb_detect_encoding')) { + $possibleCharsets = array( + $documentCharset, + $requestedCharset, + 'AUTO' + ); + $docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets)); + if (!$docEncoding) + $docEncoding = $documentCharset; + // ok trust the document + phpQuery::debug("DETECTED '$docEncoding'"); + // Detected does not match what document says... + if ($docEncoding !== $documentCharset) { + // Tricky.. + } + if ($docEncoding !== $requestedCharset) { + phpQuery::debug("CONVERT $docEncoding => $requestedCharset"); + $markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding); + $markup = $this->charsetAppendToHTML($markup, $requestedCharset); + $charset = $requestedCharset; + } + } + else { + phpQuery::debug("TODO: charset conversion without mbstring..."); + } + } + $return = false; + if ($this->isDocumentFragment) { + phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); + $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + } + else { + if ($addDocumentCharset) { + phpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); + $markup = $this->charsetAppendToHTML($markup, $charset); + } + phpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); + $this->documentCreate($charset); + $return = phpQuery::$debug === 2 ? $this->document->loadHTML($markup) + : @$this->document->loadHTML($markup); + if ($return) + $this->root = $this->document; + } + if ($return && !$this->contentType) + $this->contentType = 'text/html'; + return $return; + } + protected function loadMarkupXML($markup, $requestedCharset = null) { + if (phpQuery::$debug) + phpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250)); + $this->loadMarkupReset(); + $this->isXML = true; + // check agains XHTML in contentType or markup + $isContentTypeXHTML = $this->isXHTML(); + $isMarkupXHTML = $this->isXHTML($markup); + if ($isContentTypeXHTML || $isMarkupXHTML) { + self::debug('Full markup load (XML), XHTML detected'); + $this->isXHTML = true; + } + // determine document fragment + if (!isset($this->isDocumentFragment)) + $this->isDocumentFragment = $this->isXHTML ? self::isDocumentFragmentXHTML($markup) + : self::isDocumentFragmentXML($markup); + // this charset will be used + $charset = null; + // charset from XML declaration @var string + $documentCharset = $this->charsetFromXML($markup); + if (!$documentCharset) { + if ($this->isXHTML) { + // this is XHTML, try to get charset from content-type meta header + $documentCharset = $this->charsetFromHTML($markup); + if ($documentCharset) { + phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); + $this->charsetAppendToXML($markup, $documentCharset); + $charset = $documentCharset; + } + } + if (!$documentCharset) { + // if still no document charset... + $charset = $requestedCharset; + } + } + else if ($requestedCharset) { + $charset = $requestedCharset; + } + if (!$charset) { + $charset = phpQuery::$defaultCharset; + } + if ($requestedCharset && $documentCharset + && $requestedCharset != $documentCharset) { + // TODO place for charset conversion + // $charset = $requestedCharset; + } + $return = false; + if ($this->isDocumentFragment) { + phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); + $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + } + else { + // FIXME ??? + if ($isContentTypeXHTML && !$isMarkupXHTML) + if (!$documentCharset) { + phpQuery::debug("Full markup load (XML), appending charset '$charset'"); + $markup = $this->charsetAppendToXML($markup, $charset); + } + // see http://pl2.php.net/manual/en/book.dom.php#78929 + // LIBXML_DTDLOAD (>= PHP 5.1) + // does XML ctalogues works with LIBXML_NONET + // $this->document->resolveExternals = true; + // TODO test LIBXML_COMPACT for performance improvement + // create document + $this->documentCreate($charset); + if (phpversion() < 5.1) { + $this->document->resolveExternals = true; + $return = phpQuery::$debug === 2 ? $this->document->loadXML($markup) + : @$this->document->loadXML($markup); + } + else { + /** @link http://pl2.php.net/manual/en/libxml.constants.php */ + $libxmlStatic = phpQuery::$debug === 2 ? LIBXML_DTDLOAD + | LIBXML_DTDATTR | LIBXML_NONET + : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING + | LIBXML_NOERROR; + $return = $this->document->loadXML($markup, $libxmlStatic); + // if (! $return) + // $return = $this->document->loadHTML($markup); + } + if ($return) + $this->root = $this->document; + } + if ($return) { + if (!$this->contentType) { + if ($this->isXHTML) + $this->contentType = 'application/xhtml+xml'; + else + $this->contentType = 'text/xml'; + } + return $return; + } + else { + throw new Exception("Error loading XML markup"); + } + } + protected function isXHTML($markup = null) { + if (!isset($markup)) { + return strpos($this->contentType, 'xhtml') !== false; + } + // XXX ok ? + return strpos($markup, "doctype) && is_object($dom->doctype) + // ? $dom->doctype->publicId + // : self::$defaultDoctype; + } + protected function isXML($markup) { + // return strpos($markup, ']+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches); + if (!isset($matches[0])) + return array( + null, + null + ); + // get attr 'content' + preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches); + if (!isset($matches[0])) + return array( + null, + null + ); + return $this->contentTypeToArray($matches[2]); + } + protected function charsetFromHTML($markup) { + $contentType = $this->contentTypeFromHTML($markup); + return $contentType[1]; + } + protected function charsetFromXML($markup) { + $matches; + // find declaration + preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches); + return isset($matches[2]) ? strtolower($matches[2]) : null; + } + /** + * Repositions meta[type=charset] at the start of head. Bypasses \DOMDocument bug. + * + * @link http://code.google.com/p/phpquery/issues/detail?id=80 + * @param $html + */ + protected function charsetFixHTML($markup) { + $matches = array(); + // find meta tag + preg_match('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches, PREG_OFFSET_CAPTURE); + if (!isset($matches[0])) + return; + $metaContentType = $matches[0][0]; + $markup = substr($markup, 0, $matches[0][1]) + . substr($markup, $matches[0][1] + strlen($metaContentType)); + $headStart = stripos($markup, ''); + $markup = substr($markup, 0, $headStart + 6) . $metaContentType + . substr($markup, $headStart + 6); + return $markup; + } + protected function charsetAppendToHTML($html, $charset, $xhtml = false) { + // remove existing meta[type=content-type] + $html = preg_replace('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html); + $meta = ''; + if (strpos($html, ')@s', "{$meta}", $html); + } + } + else { + return preg_replace('@)@s', '' . $meta, $html); + } + } + protected function charsetAppendToXML($markup, $charset) { + $declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?' + . '>'; + return $declaration . $markup; + } + public static function isDocumentFragmentHTML($markup) { + return stripos($markup, 'documentFragmentCreate($node, $sourceCharset); + // if ($fake === false) + // throw new Exception("Error loading documentFragment markup"); + // else + // $return = array_merge($return, + // $this->import($fake->root->childNodes) + // ); + // } else { + // $return[] = $this->document->importNode($node, true); + // } + // } + // return $return; + // } else { + // // string markup + // $fake = $this->documentFragmentCreate($source, $sourceCharset); + // if ($fake === false) + // throw new Exception("Error loading documentFragment markup"); + // else + // return $this->import($fake->root->childNodes); + // } + if (is_array($source) || $source instanceof \DOMNodeList) { + // dom nodes + self::debug('Importing nodes to document'); + foreach ($source as $node) + $return[] = $this->document->importNode($node, true); + } + else { + // string markup + $fake = $this->documentFragmentCreate($source, $sourceCharset); + if ($fake === false) + throw new Exception("Error loading documentFragment markup"); + else + return $this->import($fake->root->childNodes); + } + return $return; + } + /** + * Creates new document fragment. + * + * @param $source + * @return DOMDocumentWrapper + */ + protected function documentFragmentCreate($source, $charset = null) { + $fake = new DOMDocumentWrapper(); + $fake->contentType = $this->contentType; + $fake->isXML = $this->isXML; + $fake->isHTML = $this->isHTML; + $fake->isXHTML = $this->isXHTML; + $fake->root = $fake->document; + if (!$charset) + $charset = $this->charset; + // $fake->documentCreate($this->charset); + if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) + $source = array( + $source + ); + if (is_array($source) || $source instanceof \DOMNodeList) { + // dom nodes + // load fake document + if (!$this->documentFragmentLoadMarkup($fake, $charset)) + return false; + $nodes = $fake->import($source); + foreach ($nodes as $node) + $fake->root->appendChild($node); + } + else { + // string markup + $this->documentFragmentLoadMarkup($fake, $charset, $source); + } + return $fake; + } + /** + * + * @param $document DOMDocumentWrapper + * @param $markup + * @return $document + */ + private function documentFragmentLoadMarkup($fragment, $charset, $markup = null) { + // TODO error handling + // TODO copy doctype + // tempolary turn off + $fragment->isDocumentFragment = false; + if ($fragment->isXML) { + if ($fragment->isXHTML) { + // add FAKE element to set default namespace + $fragment->loadMarkupXML('' + . '' + . '' . $markup . ''); + $fragment->root = $fragment->document->firstChild->nextSibling; + } + else { + $fragment->loadMarkupXML('' . $markup . ''); + $fragment->root = $fragment->document->firstChild; + } + } + else { + $markup2 = phpQuery::$defaultDoctype + . ''; + $noBody = strpos($markup, 'loadMarkupHTML($markup2); + // TODO resolv body tag merging issue + $fragment->root = $noBody ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling + : $fragment->document->firstChild->nextSibling->firstChild->nextSibling; + } + if (!$fragment->root) + return false; + $fragment->isDocumentFragment = true; + return true; + } + protected function documentFragmentToMarkup($fragment) { + phpQuery::debug('documentFragmentToMarkup'); + $tmp = $fragment->isDocumentFragment; + $fragment->isDocumentFragment = false; + $markup = $fragment->markup(); + if ($fragment->isXML) { + $markup = substr($markup, 0, strrpos($markup, '')); + if ($fragment->isXHTML) { + $markup = substr($markup, strpos($markup, '') + 6); + } + } + else { + $markup = substr($markup, strpos($markup, '') + 6); + $markup = substr($markup, 0, strrpos($markup, '')); + } + $fragment->isDocumentFragment = $tmp; + if (phpQuery::$debug) + phpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150)); + return $markup; + } + /** + * Return document markup, starting with optional $nodes as root. + * + * @param $nodes \DOMNode|\DOMNodeList + * @return string + */ + public function markup($nodes = null, $innerMarkup = false) { + if (isset($nodes) && count($nodes) == 1 + && $nodes[0] instanceof \DOMDocument) + $nodes = null; + if (isset($nodes)) { + $markup = ''; + if (!is_array($nodes) && !($nodes instanceof \DOMNodeList)) + $nodes = array( + $nodes + ); + if ($this->isDocumentFragment && !$innerMarkup) + foreach ($nodes as $i => $node) + if ($node->isSameNode($this->root)) { + // var_dump($node); + $nodes = array_slice($nodes, 0, $i) + + phpQuery::DOMNodeListToArray($node->childNodes) + + array_slice($nodes, $i + 1); + } + if ($this->isXML && !$innerMarkup) { + self::debug("Getting outerXML with charset '{$this->charset}'"); + // we need outerXML, so we can benefit from + // $node param support in saveXML() + foreach ($nodes as $node) + $markup .= $this->document->saveXML($node); + } + else { + $loop = array(); + if ($innerMarkup) + foreach ($nodes as $node) { + if ($node->childNodes) + foreach ($node->childNodes as $child) + $loop[] = $child; + else + $loop[] = $node; + } + else + $loop = $nodes; + self::debug("Getting markup, moving selected nodes (" . count($loop) + . ") to new DocumentFragment"); + $fake = $this->documentFragmentCreate($loop); + $markup = $this->documentFragmentToMarkup($fake); + } + if ($this->isXHTML) { + self::debug("Fixing XHTML"); + $markup = self::markupFixXHTML($markup); + } + self::debug("Markup: " . substr($markup, 0, 250)); + return $markup; + } + else { + if ($this->isDocumentFragment) { + // documentFragment, html only... + self::debug("Getting markup, DocumentFragment detected"); + // return $this->markup( + //// $this->document->getElementsByTagName('body')->item(0) + // $this->document->root, true + // ); + $markup = $this->documentFragmentToMarkup($this); + // no need for markupFixXHTML, as it's done thought markup($nodes) method + return $markup; + } + else { + self::debug("Getting markup (" . ($this->isXML ? 'XML' : 'HTML') + . "), final with charset '{$this->charset}'"); + $markup = $this->isXML ? $this->document->saveXML() + : $this->document->saveHTML(); + if ($this->isXHTML) { + self::debug("Fixing XHTML"); + $markup = self::markupFixXHTML($markup); + } + self::debug("Markup: " . substr($markup, 0, 250)); + return $markup; + } + } + } + protected static function markupFixXHTML($markup) { + $markup = self::expandEmptyTag('script', $markup); + $markup = self::expandEmptyTag('select', $markup); + $markup = self::expandEmptyTag('textarea', $markup); + return $markup; + } + public static function debug($text) { + phpQuery::debug($text); + } + /** + * expandEmptyTag + * + * @param $tag + * @param $xml + * @return string + * @author mjaque at ilkebenson dot com + * @link http://php.net/manual/en/domdocument.savehtml.php#81256 + */ + public static function expandEmptyTag($tag, $xml) { + $indice = 0; + while ($indice < strlen($xml)) { + $pos = strpos($xml, "<$tag ", $indice); + if ($pos) { + $posCierre = strpos($xml, ">", $pos); + if ($xml[$posCierre - 1] == "/") { + $xml = substr_replace($xml, ">", $posCierre - 1, 2); + } + $indice = $posCierre; + } + else + break; + } + return $xml; + } +} diff --git a/src/Dom/DomEvent.php b/src/Dom/DomEvent.php new file mode 100644 index 0000000..f69e9de --- /dev/null +++ b/src/Dom/DomEvent.php @@ -0,0 +1,110 @@ + + * @package phpQuery + * @todo implement ArrayAccess ? + */ +class DOMEvent { + /** + * Returns a boolean indicating whether the event bubbles up through the DOM or not. + * + * @var unknown_type + */ + public $bubbles = true; + /** + * Returns a boolean indicating whether the event is cancelable. + * + * @var unknown_type + */ + public $cancelable = true; + /** + * Returns a reference to the currently registered target for the event. + * + * @var unknown_type + */ + public $currentTarget; + /** + * Returns detail about the event, depending on the type of event. + * + * @var unknown_type + * @link http://developer.mozilla.org/en/DOM/event.detail + */ + public $detail; // ??? + /** + * Used to indicate which phase of the event flow is currently being evaluated. + * + * NOT IMPLEMENTED + * + * @var unknown_type + * @link http://developer.mozilla.org/en/DOM/event.eventPhase + */ + public $eventPhase; // ??? + /** + * The explicit original target of the event (Mozilla-specific). + * + * NOT IMPLEMENTED + * + * @var unknown_type + */ + public $explicitOriginalTarget; // moz only + /** + * The original target of the event, before any retargetings (Mozilla-specific). + * + * NOT IMPLEMENTED + * + * @var unknown_type + */ + public $originalTarget; // moz only + /** + * Identifies a secondary target for the event. + * + * @var unknown_type + */ + public $relatedTarget; + /** + * Returns a reference to the target to which the event was originally dispatched. + * + * @var unknown_type + */ + public $target; + /** + * Returns the time that the event was created. + * + * @var unknown_type + */ + public $timeStamp; + /** + * Returns the name of the event (case-insensitive). + */ + public $type; + public $runDefault = true; + public $data = null; + public function __construct($data) { + foreach ($data as $k => $v) { + $this->$k = $v; + } + if (!$this->timeStamp) + $this->timeStamp = time(); + } + /** + * Cancels the event (if it is cancelable). + * + */ + public function preventDefault() { + $this->runDefault = false; + } + /** + * Stops the propagation of events further along in the DOM. + * + */ + public function stopPropagation() { + $this->bubbles = false; + } +} diff --git a/src/PhpQuery.php b/src/PhpQuery.php new file mode 100644 index 0000000..85f04bf --- /dev/null +++ b/src/PhpQuery.php @@ -0,0 +1,1365 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @package phpQuery + */ + +namespace PhpQuery; +use PhpQuery\Dom\DomDocumentWrapper as DOMDocumentWrapper; +require_once __DIR__ . '/bootstrap.php'; + +/** + * Static namespace for phpQuery functions. + * + * @author Tobiasz Cudnik + * @package phpQuery + */ +abstract class phpQuery { + /** + * XXX: Workaround for mbstring problems + * + * @var bool + */ + public static $mbstringSupport = true; + public static $debug = false; + public static $documents = array(); + public static $defaultDocumentID = null; + // public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"'; + /** + * Applies only to HTML. + * + * @var unknown_type + */ + public static $defaultDoctype = ''; + public static $defaultCharset = 'UTF-8'; + /** + * Static namespace for plugins. + * + * @var object + */ + public static $plugins = array(); + /** + * List of loaded plugins. + * + * @var unknown_type + */ + public static $pluginsLoaded = array(); + public static $pluginsMethods = array(); + public static $pluginsStaticMethods = array(); + public static $extendMethods = array(); + /** + * @TODO implement + */ + public static $extendStaticMethods = array(); + /** + * Hosts allowed for AJAX connections. + * Dot '.' means $_SERVER['HTTP_HOST'] (if any). + * + * @var array + */ + public static $ajaxAllowedHosts = array( + '.' + ); + /** + * AJAX settings. + * + * @var array + * XXX should it be static or not ? + */ + public static $ajaxSettings = array( + 'url' => '', + //TODO + 'global' => true, + 'type' => "GET", + 'timeout' => null, + 'contentType' => "application/x-www-form-urlencoded", + 'processData' => true, + // 'async' => true, + 'data' => null, + 'username' => null, + 'password' => null, + 'dataType' => null, + 'ifModified' => null, + 'accepts' => array( + 'xml' => "application/xml, text/xml", + 'html' => "text/html", + 'script' => "text/javascript, application/javascript", + 'json' => "application/json, text/javascript", + 'text' => "text/plain", + '_default' => "*/*" + ) + ); + public static $lastModified = null; + public static $active = 0; + public static $dumpCount = 0; + public static $enableCssShorthand = FALSE; + + /** + * Multi-purpose function. + * Use pq() as shortcut. + * + * In below examples, $pq is any result of pq(); function. + * + * 1. Import markup into existing document (without any attaching): + * - Import into selected document: + * pq('
    ') // DOESNT accept text nodes at beginning of input string ! + * - Import into document with ID from $pq->getDocumentID(): + * pq('
    ', $pq->getDocumentID()) + * - Import into same document as \DOMNode belongs to: + * pq('
    ', \DOMNode) + * - Import into document from phpQuery object: + * pq('
    ', $pq) + * + * 2. Run query: + * - Run query on last selected document: + * pq('div.myClass') + * - Run query on document with ID from $pq->getDocumentID(): + * pq('div.myClass', $pq->getDocumentID()) + * - Run query on same document as \DOMNode belongs to and use node(s)as root for query: + * pq('div.myClass', \DOMNode) + * - Run query on document from phpQuery object + * and use object's stack as root node(s) for query: + * pq('div.myClass', $pq) + * + * @param string|\DOMNode|\DOMNodeList|array $arg1 HTML markup, CSS Selector, \DOMNode or array of \DOMNodes + * @param string|PhpQueryObject|\DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or \DOMNode (determines also query root) + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false + * phpQuery object or false in case of error. + */ + public static function pq($arg1, $context = null) { + if ($arg1 instanceof \DOMNode && !isset($context)) { + foreach (phpQuery::$documents as $documentWrapper) { + $compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument; + if ($documentWrapper->document->isSameNode($compare)) + $context = $documentWrapper->id; + } + } + if (!$context) { + $domId = self::$defaultDocumentID; + if (!$domId) + throw new Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); + // } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) + } + else if (is_object($context) && $context instanceof PhpQueryObject) + $domId = $context->getDocumentID(); + else if ($context instanceof \DOMDocument) { + $domId = self::getDocumentID($context); + if (!$domId) { + //throw new Exception('Orphaned \DOMDocument'); + $domId = self::newDocument($context)->getDocumentID(); + } + } + else if ($context instanceof \DOMNode) { + $domId = self::getDocumentID($context); + if (!$domId) { + throw new Exception('Orphaned DOMNode'); + // $domId = self::newDocument($context->ownerDocument); + } + } + else + $domId = $context; + if ($arg1 instanceof PhpQueryObject) { + // if (is_object($arg1) && (get_class($arg1) == 'PhpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'PhpQueryObject'))) { + /** + * Return $arg1 or import $arg1 stack if document differs: + * pq(pq('
    ')) + */ + if ($arg1->getDocumentID() == $domId) + return $arg1; + $class = get_class($arg1); + // support inheritance by passing old object to overloaded constructor + $phpQuery = $class != 'phpQuery' ? new $class($arg1, $domId) + : new PhpQueryObject($domId); + $phpQuery->elements = array(); + foreach ($arg1->elements as $node) + $phpQuery->elements[] = $phpQuery->document->importNode($node, true); + return $phpQuery; + } + else if ($arg1 instanceof \DOMNode + || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode)) { + /* + * Wrap DOM nodes with phpQuery object, import into document when needed: + * pq(array($domNode1, $domNode2)) + */ + $phpQuery = new PhpQueryObject($domId); + if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) + $arg1 = array( + $arg1 + ); + $phpQuery->elements = array(); + foreach ($arg1 as $node) { + $sameDocument = $node->ownerDocument instanceof \DOMDocument + && !$node->ownerDocument->isSameNode($phpQuery->document); + $phpQuery->elements[] = $sameDocument ? $phpQuery->document->importNode($node, true) + : $node; + } + return $phpQuery; + } + else if (self::isMarkup($arg1)) { + /** + * Import HTML: + * pq('
    ') + */ + $phpQuery = new PhpQueryObject($domId); + return $phpQuery->newInstance($phpQuery->documentWrapper->import($arg1)); + } + else { + /** + * Run CSS query: + * pq('div.myClass') + */ + $phpQuery = new PhpQueryObject($domId); + // if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) + if ($context && $context instanceof PhpQueryObject) + $phpQuery->elements = $context->elements; + else if ($context && $context instanceof \DOMNodeList) { + $phpQuery->elements = array(); + foreach ($context as $node) + $phpQuery->elements[] = $node; + } + else if ($context && $context instanceof \DOMNode) + $phpQuery->elements = array( + $context + ); + return $phpQuery->find($arg1); + } + } + /** + * Sets default document to $id. Document has to be loaded prior + * to using this method. + * $id can be retrived via getDocumentID() or getDocumentIDRef(). + * + * @param unknown_type $id + */ + public static function selectDocument($id) { + $id = self::getDocumentID($id); + self::debug("Selecting document '$id' as default one"); + self::$defaultDocumentID = self::getDocumentID($id); + } + /** + * Returns document with id $id or last used as PhpQueryObject. + * $id can be retrived via getDocumentID() or getDocumentIDRef(). + * Chainable. + * + * @see phpQuery::selectDocument() + * @param unknown_type $id + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function getDocument($id = null) { + if ($id) + phpQuery::selectDocument($id); + else + $id = phpQuery::$defaultDocumentID; + return new PhpQueryObject($id); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocument($markup = null, $contentType = null) { + if (!$markup) + $markup = ''; + $documentID = phpQuery::createDocumentWrapper($markup, $contentType); + return new PhpQueryObject($documentID); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentHTML($markup = null, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "text/html{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentXML($markup = null, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "text/xml{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentXHTML($markup = null, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "application/xhtml+xml{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentPHP($markup = null, $contentType = "text/html") { + // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function) + $markup = phpQuery::phpToMarkup($markup, self::$defaultCharset); + return self::newDocument($markup, $contentType); + } + public static function phpToMarkup($php, $charset = 'utf-8') { + $regexes = array( + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<' + . '?php?(.*?)(?:\\?>)([^\']*)\'@s', + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<' + . '?php?(.*?)(?:\\?>)([^"]*)"@s', + ); + foreach ($regexes as $regex) + while (preg_match($regex, $php, $matches)) { + $php = preg_replace_callback($regex, + // create_function('$m, $charset = "'.$charset.'"', + // 'return $m[1].$m[2] + // .htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset) + // .$m[5].$m[2];' + // ), + array( + 'phpQuery', + '_phpToMarkupCallback' + ), $php); + } + $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s'; + //preg_match_all($regex, $php, $matches); + //var_dump($matches); + $php = preg_replace($regex, '\\1', $php); + return $php; + } + public static function _phpToMarkupCallback($php, $charset = 'utf-8') { + return $m[1] . $m[2] + . htmlspecialchars("<" . "?php" . $m[4] . "?" . ">", ENT_QUOTES + | ENT_NOQUOTES, $charset) . $m[5] . $m[2]; + } + public static function _markupToPHPCallback($m) { + return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">"; + } + /** + * Converts document markup containing PHP code generated by phpQuery::php() + * into valid (executable) PHP code syntax. + * + * @param string|PhpQueryObject $content + * @return string PHP code. + */ + public static function markupToPHP($content) { + if ($content instanceof PhpQueryObject) + $content = $content->markupOuter(); + /* ... to */ + $content = preg_replace_callback('@\s*\s*@s', + // create_function('$m', + // 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";' + // ), + array( + 'phpQuery', + '_markupToPHPCallback' + ), $content); + /* extra space added to save highlighters */ + $regexes = array( + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^\']*)\'@s', + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^"]*)"@s', + ); + foreach ($regexes as $regex) + while (preg_match($regex, $content)) + $content = preg_replace_callback($regex, create_function('$m', 'return $m[1].$m[2].$m[3]."", " ", "\n", " ", "{", "$", "}", \'"\', "[", "]"), + htmlspecialchars_decode($m[4]) + ) + ." ?>".$m[5].$m[2];'), $content); + return $content; + } + /** + * Creates new document from file $file. + * Chainable. + * + * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources. + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFile($file, $contentType = null) { + $documentID = self::createDocumentWrapper(file_get_contents($file), $contentType); + return new PhpQueryObject($documentID); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileHTML($file, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "text/html{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileXML($file, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "text/xml{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileXHTML($file, $charset = null) { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "application/xhtml+xml{$contentType}"); + } + /** + * Creates new document from markup. + * Chainable. + * + * @param unknown_type $markup + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFilePHP($file, $contentType = null) { + return self::newDocumentPHP(file_get_contents($file), $contentType); + } + /** + * Reuses existing \DOMDocument object. + * Chainable. + * + * @param $document \DOMDocument + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support \DOMDocument + */ + public static function loadDocument($document) { + // TODO + die('TODO loadDocument'); + } + /** + * Enter description here... + * + * @param unknown_type $html + * @param unknown_type $domId + * @return unknown New DOM ID + * @todo support PHP tags in input + * @todo support passing \DOMDocument object from self::loadDocument + */ + protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) { + if (function_exists('domxml_open_mem')) + throw new Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); + // $id = $documentID + // ? $documentID + // : md5(microtime()); + $document = null; + if ($html instanceof \DOMDocument) { + if (self::getDocumentID($html)) { + // document already exists in phpQuery::$documents, make a copy + $document = clone $html; + } + else { + // new document, add it to phpQuery::$documents + $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); + } + } + else { + $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); + } + // $wrapper->id = $id; + // bind document + phpQuery::$documents[$wrapper->id] = $wrapper; + // remember last loaded document + phpQuery::selectDocument($wrapper->id); + return $wrapper->id; + } + /** + * Extend class namespace. + * + * @param string|array $target + * @param array $source + * @TODO support string $source + * @return unknown_type + */ + public static function extend($target, $source) { + switch ($target) { + case 'PhpQueryObject': + $targetRef = &self::$extendMethods; + $targetRef2 = &self::$pluginsMethods; + break; + case 'phpQuery': + $targetRef = &self::$extendStaticMethods; + $targetRef2 = &self::$pluginsStaticMethods; + break; + default: + throw new Exception("Unsupported \$target type"); + } + if (is_string($source)) + $source = array( + $source => $source + ); + foreach ($source as $method => $callback) { + if (isset($targetRef[$method])) { + // throw new Exception + self::debug("Duplicate method '{$method}', can\'t extend '{$target}'"); + continue; + } + if (isset($targetRef2[$method])) { + // throw new Exception + self::debug("Duplicate method '{$method}' from plugin '{$targetRef2[$method]}'," + . " can\'t extend '{$target}'"); + continue; + } + $targetRef[$method] = $callback; + } + return true; + } + /** + * Extend phpQuery with $class from $file. + * + * @param string $class Extending class name. Real class name can be prepended phpQuery_. + * @param string $file Filename to include. Defaults to "{$class}.php". + */ + public static function plugin($class, $file = null) { + // TODO $class checked agains phpQuery_$class + // if (strpos($class, 'phpQuery') === 0) + // $class = substr($class, 8); + if (in_array($class, self::$pluginsLoaded)) + return true; + if (!$file) + $file = $class . '.php'; + $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class); + $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class); + if (!$objectClassExists && !$staticClassExists) + require_once($file); + self::$pluginsLoaded[] = $class; + // static methods + if (class_exists('\PhpQuery\Plugin\Util' . $class)) { + $realClass = '\PhpQuery\Plugin\Util' . $class; + $vars = get_class_vars($realClass); + $loop = isset($vars['phpQueryMethods']) + && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + : get_class_methods($realClass); + foreach ($loop as $method) { + if ($method == '__initialize') + continue; + if (!is_callable(array( + $realClass, + $method + ))) + continue; + if (isset(self::$pluginsStaticMethods[$method])) { + throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" + . self::$pluginsStaticMethods[$method] . "'"); + return; + } + self::$pluginsStaticMethods[$method] = $class; + } + if (method_exists($realClass, '__initialize')) + call_user_func_array(array( + $realClass, + '__initialize' + ), array()); + } + // object methods + if (class_exists('\\PhpQuery\\Plugin\\' . $class)) { + $realClass = '\\PhpQuery\\Plugin\\' . $class; + $vars = get_class_vars($realClass); + $loop = isset($vars['phpQueryMethods']) + && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + : get_class_methods($realClass); + foreach ($loop as $method) { + if (!is_callable(array( + $realClass, + $method + ))) + continue; + if (isset(self::$pluginsMethods[$method])) { + throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" + . self::$pluginsMethods[$method] . "'"); + continue; + } + self::$pluginsMethods[$method] = $class; + } + } + return true; + } + /** + * Unloades all or specified document from memory. + * + * @param mixed $documentID @see phpQuery::getDocumentID() for supported types. + */ + public static function unloadDocuments($id = null) { + if (isset($id)) { + if ($id = self::getDocumentID($id)) + unset(phpQuery::$documents[$id]); + } + else { + foreach (phpQuery::$documents as $k => $v) { + unset(phpQuery::$documents[$k]); + } + } + } + /** + * Parses phpQuery object or HTML result against PHP tags and makes them active. + * + * @param phpQuery|string $content + * @deprecated + * @return string + */ + public static function unsafePHPTags($content) { + return self::markupToPHP($content); + } + public static function DOMNodeListToArray($DOMNodeList) { + $array = array(); + if (!$DOMNodeList) + return $array; + foreach ($DOMNodeList as $node) + $array[] = $node; + return $array; + } + /** + * Checks if $input is HTML string, which has to start with '<'. + * + * @deprecated + * @param String $input + * @return Bool + * @todo still used ? + */ + public static function isMarkup($input) { + return is_string($input) && substr(trim($input), 0, 1) == '<'; + } + public static function debug($text) { + if (self::$debug) + print var_dump($text); + } + /** + * Make an AJAX request. + * + * @param array See $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions + * Additional options are: + * 'document' - document for global events, @see phpQuery::getDocumentID() + * 'referer' - implemented + * 'requested_with' - TODO; not implemented (X-Requested-With) + * @return Zend_Http_Client + * @link http://docs.jquery.com/Ajax/jQuery.ajax + * + * @TODO $options['cache'] + * @TODO $options['processData'] + * @TODO $options['xhr'] + * @TODO $options['data'] as string + * @TODO XHR interface + */ + public static function ajax($options = array(), $xhr = null) { + $options = array_merge(self::$ajaxSettings, $options); + $documentID = isset($options['document']) ? self::getDocumentID($options['document']) + : null; + if ($xhr) { + // reuse existing XHR object, but clean it up + $client = $xhr; + // $client->setParameterPost(null); + // $client->setParameterGet(null); + $client->setAuth(false); + $client->setHeaders("If-Modified-Since", null); + $client->setHeaders("Referer", null); + $client->resetParameters(); + } + else { + // create new XHR object + $client = new Zend_Http_Client(); + $client->setCookieJar(); + } + if (isset($options['timeout'])) + $client->setConfig(array( + 'timeout' => $options['timeout'], + )); + // 'maxredirects' => 0, + foreach (self::$ajaxAllowedHosts as $k => $host) + if ($host == '.' && isset($_SERVER['HTTP_HOST'])) + self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST']; + $host = parse_url($options['url'], PHP_URL_HOST); + if (!in_array($host, self::$ajaxAllowedHosts)) { + throw new Exception("Request not permitted, host '$host' not present in " + . "phpQuery::\$ajaxAllowedHosts"); + } + // JSONP + $jsre = "/=\\?(&|$)/"; + if (isset($options['dataType']) && $options['dataType'] == 'jsonp') { + $jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback'; + if (strtolower($options['type']) == 'get') { + if (!preg_match($jsre, $options['url'])) { + $sep = strpos($options['url'], '?') ? '&' : '?'; + $options['url'] .= "$sep$jsonpCallbackParam=?"; + } + } + else if ($options['data']) { + $jsonp = false; + foreach ($options['data'] as $n => $v) { + if ($v == '?') + $jsonp = true; + } + if (!$jsonp) { + $options['data'][$jsonpCallbackParam] = '?'; + } + } + $options['dataType'] = 'json'; + } + if (isset($options['dataType']) && $options['dataType'] == 'json') { + $jsonpCallback = 'json_' . md5(microtime()); + $jsonpData = $jsonpUrl = false; + if ($options['data']) { + foreach ($options['data'] as $n => $v) { + if ($v == '?') + $jsonpData = $n; + } + } + if (preg_match($jsre, $options['url'])) + $jsonpUrl = true; + if ($jsonpData !== false || $jsonpUrl) { + // remember callback name for httpData() + $options['_jsonp'] = $jsonpCallback; + if ($jsonpData !== false) + $options['data'][$jsonpData] = $jsonpCallback; + if ($jsonpUrl) + $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']); + } + } + $client->setUri($options['url']); + $client->setMethod(strtoupper($options['type'])); + if (isset($options['referer']) && $options['referer']) + $client->setHeaders('Referer', $options['referer']); + $client->setHeaders(array( + // 'content-type' => $options['contentType'], + 'User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko' + . '/2008122010 Firefox/3.0.5', + // TODO custom charset + 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', + // 'Connection' => 'keep-alive', + // 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Language' => 'en-us,en;q=0.5', + )); + if ($options['username']) + $client->setAuth($options['username'], $options['password']); + if (isset($options['ifModified']) && $options['ifModified']) + $client->setHeaders("If-Modified-Since", self::$lastModified ? self::$lastModified + : "Thu, 01 Jan 1970 00:00:00 GMT"); + $client->setHeaders("Accept", isset($options['dataType']) + && isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']] + . ", */*" : self::$ajaxSettings['accepts']['_default']); + // TODO $options['processData'] + if ($options['data'] instanceof PhpQueryObject) { + $serialized = $options['data']->serializeArray($options['data']); + $options['data'] = array(); + foreach ($serialized as $r) + $options['data'][$r['name']] = $r['value']; + } + if (strtolower($options['type']) == 'get') { + $client->setParameterGet($options['data']); + } + else if (strtolower($options['type']) == 'post') { + $client->setEncType($options['contentType']); + $client->setParameterPost($options['data']); + } + if (self::$active == 0 && $options['global']) + phpQueryEvents::trigger($documentID, 'ajaxStart'); + self::$active++; + // beforeSend callback + if (isset($options['beforeSend']) && $options['beforeSend']) + phpQuery::callbackRun($options['beforeSend'], array( + $client + )); + // ajaxSend event + if ($options['global']) + phpQueryEvents::trigger($documentID, 'ajaxSend', array( + $client, + $options + )); + if (phpQuery::$debug) { + self::debug("{$options['type']}: {$options['url']}\n"); + self::debug("Options:
    " . var_export($options, true) . "
    \n"); + // if ($client->getCookieJar()) + // self::debug("Cookies:
    ".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."
    \n"); + } + // request + $response = $client->request(); + if (phpQuery::$debug) { + self::debug('Status: ' . $response->getStatus() . ' / ' + . $response->getMessage()); + self::debug($client->getLastRequest()); + self::debug($response->getHeaders()); + } + if ($response->isSuccessful()) { + // XXX tempolary + self::$lastModified = $response->getHeader('Last-Modified'); + $data = self::httpData($response->getBody(), $options['dataType'], $options); + if (isset($options['success']) && $options['success']) + phpQuery::callbackRun($options['success'], array( + $data, + $response->getStatus(), + $options + )); + if ($options['global']) + phpQueryEvents::trigger($documentID, 'ajaxSuccess', array( + $client, + $options + )); + } + else { + if (isset($options['error']) && $options['error']) + phpQuery::callbackRun($options['error'], array( + $client, + $response->getStatus(), + $response->getMessage() + )); + if ($options['global']) + phpQueryEvents::trigger($documentID, 'ajaxError', array( + $client, + /*$response->getStatus(),*/$response->getMessage(), + $options + )); + } + if (isset($options['complete']) && $options['complete']) + phpQuery::callbackRun($options['complete'], array( + $client, + $response->getStatus() + )); + if ($options['global']) + phpQueryEvents::trigger($documentID, 'ajaxComplete', array( + $client, + $options + )); + if ($options['global'] && !--self::$active) + phpQueryEvents::trigger($documentID, 'ajaxStop'); + return $client; + // if (is_null($domId)) + // $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; + // return new phpQueryAjaxResponse($response, $domId); + } + protected static function httpData($data, $type, $options) { + if (isset($options['dataFilter']) && $options['dataFilter']) + $data = self::callbackRun($options['dataFilter'], array( + $data, + $type + )); + if (is_string($data)) { + if ($type == "json") { + if (isset($options['_jsonp']) && $options['_jsonp']) { + $data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data); + } + $data = self::parseJSON($data); + } + } + return $data; + } + /** + * Enter description here... + * + * @param array|phpQuery $data + * + */ + public static function param($data) { + return http_build_query($data, null, '&'); + } + public static function get($url, $data = null, $callback = null, $type = null) { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + // TODO some array_values on this shit + return phpQuery::ajax(array( + 'type' => 'GET', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => $type, + )); + } + public static function post($url, $data = null, $callback = null, $type = null) { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + return phpQuery::ajax(array( + 'type' => 'POST', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => $type, + )); + } + public static function getJSON($url, $data = null, $callback = null) { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + // TODO some array_values on this shit + return phpQuery::ajax(array( + 'type' => 'GET', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => 'json', + )); + } + public static function ajaxSetup($options) { + self::$ajaxSettings = array_merge(self::$ajaxSettings, $options); + } + public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) { + $loop = is_array($host1) ? $host1 : func_get_args(); + foreach ($loop as $host) { + if ($host && !in_array($host, phpQuery::$ajaxAllowedHosts)) { + phpQuery::$ajaxAllowedHosts[] = $host; + } + } + } + public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) { + $loop = is_array($url1) ? $url1 : func_get_args(); + foreach ($loop as $url) + phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); + } + /** + * Returns JSON representation of $data. + * + * @static + * @param mixed $data + * @return string + */ + public static function toJSON($data) { + if (function_exists('json_encode')) + return json_encode($data); + require_once('Zend/Json/Encoder.php'); + return Zend_Json_Encoder::encode($data); + } + /** + * Parses JSON into proper PHP type. + * + * @static + * @param string $json + * @return mixed + */ + public static function parseJSON($json) { + if (function_exists('json_decode')) { + $return = json_decode(trim($json), true); + // json_decode and UTF8 issues + if (isset($return)) + return $return; + } + require_once('Zend/Json/Decoder.php'); + return Zend_Json_Decoder::decode($json); + } + /** + * Returns source's document ID. + * + * @param $source \DOMNode|PhpQueryObject + * @return string + */ + public static function getDocumentID($source) { + if ($source instanceof \DOMDocument) { + foreach (phpQuery::$documents as $id => $document) { + if ($source->isSameNode($document->document)) + return $id; + } + } + else if ($source instanceof \DOMNode) { + foreach (phpQuery::$documents as $id => $document) { + if ($source->ownerDocument->isSameNode($document->document)) + return $id; + } + } + else if ($source instanceof PhpQueryObject) + return $source->getDocumentID(); + else if (is_string($source) && isset(phpQuery::$documents[$source])) + return $source; + } + /** + * Get \DOMDocument object related to $source. + * Returns null if such document doesn't exist. + * + * @param $source \DOMNode|PhpQueryObject|string + * @return string + */ + public static function getDOMDocument($source) { + if ($source instanceof \DOMDocument) + return $source; + $source = self::getDocumentID($source); + return $source ? self::$documents[$id]['document'] : null; + } + + // UTILITIES + // http://docs.jquery.com/Utilities + + /** + * + * @return unknown_type + * @link http://docs.jquery.com/Utilities/jQuery.makeArray + */ + public static function makeArray($obj) { + $array = array(); + if (is_object($object) && $object instanceof \DOMNodeList) { + foreach ($object as $value) + $array[] = $value; + } + else if (is_object($object) && !($object instanceof Iterator)) { + foreach (get_object_vars($object) as $name => $value) + $array[0][$name] = $value; + } + else { + foreach ($object as $name => $value) + $array[0][$name] = $value; + } + return $array; + } + public static function inArray($value, $array) { + return in_array($value, $array); + } + /** + * + * @param $object + * @param $callback + * @return unknown_type + * @link http://docs.jquery.com/Utilities/jQuery.each + */ + public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null) { + $paramStructure = null; + if (func_num_args() > 2) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 2); + } + if (is_object($object) && !($object instanceof Iterator)) { + foreach (get_object_vars($object) as $name => $value) + phpQuery::callbackRun($callback, array( + $name, + $value + ), $paramStructure); + } + else { + foreach ($object as $name => $value) + phpQuery::callbackRun($callback, array( + $name, + $value + ), $paramStructure); + } + } + /** + * + * @link http://docs.jquery.com/Utilities/jQuery.map + */ + public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null) { + $result = array(); + $paramStructure = null; + if (func_num_args() > 2) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 2); + } + foreach ($array as $v) { + $vv = phpQuery::callbackRun($callback, array( + $v + ), $paramStructure); + // $callbackArgs = $args; + // foreach($args as $i => $arg) { + // $callbackArgs[$i] = $arg instanceof CallbackParam + // ? $v + // : $arg; + // } + // $vv = call_user_func_array($callback, $callbackArgs); + if (is_array($vv)) { + foreach ($vv as $vvv) + $result[] = $vvv; + } + else if ($vv !== null) { + $result[] = $vv; + } + } + return $result; + } + /** + * + * @param $callback Callback + * @param $params + * @param $paramStructure + * @return unknown_type + */ + public static function callbackRun($callback, $params = array(), $paramStructure = null) { + if (!$callback) + return; + if ($callback instanceof CallbackParameterToReference) { + // TODO support ParamStructure to select which $param push to reference + if (isset($params[0])) + $callback->callback = $params[0]; + return true; + } + if ($callback instanceof Callback) { + $paramStructure = $callback->params; + $callback = $callback->callback; + } + if (!$paramStructure) + return call_user_func_array($callback, $params); + $p = 0; + foreach ($paramStructure as $i => $v) { + $paramStructure[$i] = $v instanceof CallbackParam ? $params[$p++] : $v; + } + return call_user_func_array($callback, $paramStructure); + } + /** + * Merge 2 phpQuery objects. + * @param array $one + * @param array $two + * @protected + * @todo node lists, PhpQueryObject + */ + public static function merge($one, $two) { + $elements = $one->elements; + foreach ($two->elements as $node) { + $exists = false; + foreach ($elements as $node2) { + if ($node2->isSameNode($node)) + $exists = true; + } + if (!$exists) + $elements[] = $node; + } + return $elements; + // $one = $one->newInstance(); + // $one->elements = $elements; + // return $one; + } + /** + * + * @param $array + * @param $callback + * @param $invert + * @return unknown_type + * @link http://docs.jquery.com/Utilities/jQuery.grep + */ + public static function grep($array, $callback, $invert = false) { + $result = array(); + foreach ($array as $k => $v) { + $r = call_user_func_array($callback, array( + $v, + $k + )); + if ($r === !(bool) $invert) + $result[] = $v; + } + return $result; + } + public static function unique($array) { + return array_unique($array); + } + /** + * + * @param $function + * @return unknown_type + * @TODO there are problems with non-static methods, second parameter pass it + * but doesnt verify is method is really callable + */ + public static function isFunction($function) { + return is_callable($function); + } + public static function trim($str) { + return trim($str); + } + /* PLUGINS NAMESPACE */ + /** + * + * @param $url + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun(array( + self::$plugins, + 'browserGet' + ), $params); + } + else { + self::debug('WebBrowser plugin not available...'); + } + } + /** + * + * @param $url + * @param $data + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun(array( + self::$plugins, + 'browserPost' + ), $params); + } + else { + self::debug('WebBrowser plugin not available...'); + } + } + /** + * + * @param $ajaxSettings + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null) { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun(array( + self::$plugins, + 'browser' + ), $params); + } + else { + self::debug('WebBrowser plugin not available...'); + } + } + /** + * + * @param $code + * @return string + */ + public static function php($code) { + return self::code('php', $code); + } + /** + * + * @param $type + * @param $code + * @return string + */ + public static function code($type, $code) { + return "<$type>"; + } + + public static function __callStatic($method, $params) { + return call_user_func_array(array( + phpQuery::$plugins, + $method + ), $params); + } + protected static function dataSetupNode($node, $documentID) { + // search are return if alredy exists + foreach (phpQuery::$documents[$documentID]->dataNodes as $dataNode) { + if ($node->isSameNode($dataNode)) + return $dataNode; + } + // if doesn't, add it + phpQuery::$documents[$documentID]->dataNodes[] = $node; + return $node; + } + protected static function dataRemoveNode($node, $documentID) { + // search are return if alredy exists + foreach (phpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { + if ($node->isSameNode($dataNode)) { + unset(self::$documents[$documentID]->dataNodes[$k]); + unset(self::$documents[$documentID]->data[$dataNode->dataID]); + } + } + } + public static function data($node, $name, $data, $documentID = null) { + if (!$documentID) + // TODO check if this works + $documentID = self::getDocumentID($node); + $document = phpQuery::$documents[$documentID]; + $node = self::dataSetupNode($node, $documentID); + if (!isset($node->dataID)) + $node->dataID = ++phpQuery::$documents[$documentID]->uuid; + $id = $node->dataID; + if (!isset($document->data[$id])) + $document->data[$id] = array(); + if (!is_null($data)) + $document->data[$id][$name] = $data; + if ($name) { + if (isset($document->data[$id][$name])) + return $document->data[$id][$name]; + } + else + return $id; + } + public static function removeData($node, $name, $documentID) { + if (!$documentID) + // TODO check if this works + $documentID = self::getDocumentID($node); + $document = phpQuery::$documents[$documentID]; + $node = self::dataSetupNode($node, $documentID); + $id = $node->dataID; + if ($name) { + if (isset($document->data[$id][$name])) + unset($document->data[$id][$name]); + $name = null; + foreach ($document->data[$id] as $name) + break; + if (!$name) + self::removeData($node, $name, $documentID); + } + else { + self::dataRemoveNode($node, $documentID); + } + } +} +/** + * Plugins static namespace class. + * + * @author Tobiasz Cudnik + * @package phpQuery + * @todo move plugin methods here (as statics) + */ +class phpQueryPlugins { + public function __call($method, $args) { + if (isset(phpQuery::$extendStaticMethods[$method])) { + $return = call_user_func_array(phpQuery::$extendStaticMethods[$method], $args); + } + else if (isset(phpQuery::$pluginsStaticMethods[$method])) { + $class = phpQuery::$pluginsStaticMethods[$method]; + $realClass = "\PhpQuery\Plugin\Util$class"; + $return = call_user_func_array(array( + $realClass, + $method + ), $args); + return isset($return) ? $return : $this; + } + else + throw new Exception("Method '{$method}' doesnt exist"); + } +} +// // add plugins dir and Zend framework to include path +// set_include_path( +// get_include_path() +// .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/' +// .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/plugins/' +// ); +// why ? no __call nor __get for statics in php... +// XXX __callStatic will be available in PHP 5.3 +phpQuery::$plugins = new phpQueryPlugins(); +// include bootstrap file (personal library config) +if (file_exists(dirname(__FILE__) . '/phpQuery/bootstrap.php')) + require_once dirname(__FILE__) . '/phpQuery/bootstrap.php'; \ No newline at end of file diff --git a/src/PhpQueryEvents.php b/src/PhpQueryEvents.php new file mode 100644 index 0000000..43a001f --- /dev/null +++ b/src/PhpQueryEvents.php @@ -0,0 +1,161 @@ +document) + $pq->find('*')->add($pq->document)->trigger($type, $data); + } + } + else { + if (isset($data[0]) && $data[0] instanceof DOMEvent) { + $event = $data[0]; + $event->relatedTarget = $event->target; + $event->target = $node; + $data = array_slice($data, 1); + } + else { + $event = new DOMEvent(array( + 'type' => $type, + 'target' => $node, + 'timeStamp' => time(), + )); + } + $i = 0; + while ($node) { + // TODO whois + phpQuery::debug("Triggering " . ($i ? "bubbled " : '') + . "event '{$type}' on " . "node \n");//.PhpQueryObject::whois($node)."\n"); + $event->currentTarget = $node; + $eventNode = self::getNode($documentID, $node); + if (isset($eventNode->eventHandlers)) { + foreach ($eventNode->eventHandlers as $eventType => $handlers) { + $eventNamespace = null; + if (strpos($type, '.') !== false) + list($eventName, $eventNamespace) = explode('.', $eventType); + else + $eventName = $eventType; + if ($name != $eventName) + continue; + if ($namespace && $eventNamespace && $namespace != $eventNamespace) + continue; + foreach ($handlers as $handler) { + phpQuery::debug("Calling event handler\n"); + $event->data = $handler['data'] ? $handler['data'] : null; + $params = array_merge(array( + $event + ), $data); + $return = phpQuery::callbackRun($handler['callback'], $params); + if ($return === false) { + $event->bubbles = false; + } + } + } + } + // to bubble or not to bubble... + if (!$event->bubbles) + break; + $node = $node->parentNode; + $i++; + } + } + } + /** + * Binds a handler to one or more events (like click) for each matched element. + * Can also bind custom events. + * + * @param DOMNode|PhpQueryObject|string $document + * @param unknown_type $type + * @param unknown_type $data Optional + * @param unknown_type $callback + * + * @TODO support '!' (exclusive) events + * @TODO support more than event in $type (space-separated) + * @TODO support binding to global events + */ + public static function add($document, $node, $type, $data, $callback = null) { + phpQuery::debug("Binding '$type' event"); + $documentID = phpQuery::getDocumentID($document); + // if (is_null($callback) && is_callable($data)) { + // $callback = $data; + // $data = null; + // } + $eventNode = self::getNode($documentID, $node); + if (!$eventNode) + $eventNode = self::setNode($documentID, $node); + if (!isset($eventNode->eventHandlers[$type])) + $eventNode->eventHandlers[$type] = array(); + $eventNode->eventHandlers[$type][] = array( + 'callback' => $callback, + 'data' => $data, + ); + } + /** + * Enter description here... + * + * @param DOMNode|PhpQueryObject|string $document + * @param unknown_type $type + * @param unknown_type $callback + * + * @TODO namespace events + * @TODO support more than event in $type (space-separated) + */ + public static function remove($document, $node, $type = null, $callback = null) { + $documentID = phpQuery::getDocumentID($document); + $eventNode = self::getNode($documentID, $node); + if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) { + if ($callback) { + foreach ($eventNode->eventHandlers[$type] as $k => $handler) + if ($handler['callback'] == $callback) + unset($eventNode->eventHandlers[$type][$k]); + } + else { + unset($eventNode->eventHandlers[$type]); + } + } + } + protected static function getNode($documentID, $node) { + foreach (phpQuery::$documents[$documentID]->eventsNodes as $eventNode) { + if ($node->isSameNode($eventNode)) + return $eventNode; + } + } + protected static function setNode($documentID, $node) { + phpQuery::$documents[$documentID]->eventsNodes[] = $node; + return phpQuery::$documents[$documentID]->eventsNodes[count(phpQuery::$documents[$documentID]->eventsNodes) + - 1]; + } + protected static function issetGlobal($documentID, $type) { + return isset(phpQuery::$documents[$documentID]) ? in_array($type, phpQuery::$documents[$documentID]->eventsGlobal) + : false; + } +} diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php new file mode 100644 index 0000000..de7e75d --- /dev/null +++ b/src/PhpQueryObject.php @@ -0,0 +1,3449 @@ + + * @package phpQuery + * @method PhpQueryObject clone() clone() + * @method PhpQueryObject empty() empty() + * @method PhpQueryObject next() next($selector = null) + * @method PhpQueryObject prev() prev($selector = null) + * @property Int $length + */ +class PhpQueryObject implements \Iterator, \Countable, \ArrayAccess { + public $documentID = null; + /** + * \DOMDocument class. + * + * @var \DOMDocument + */ + public $document = null; + public $charset = null; + /** + * + * @var DOMDocumentWrapper + */ + public $documentWrapper = null; + /** + * XPath interface. + * + * @var DOMXPath + */ + public $xpath = null; + /** + * Stack of selected elements. + * @TODO refactor to ->nodes + * @var array + */ + public $elements = array(); + /** + * @access private + */ + protected $elementsBackup = array(); + /** + * @access private + */ + protected $previous = null; + /** + * @access private + * @TODO deprecate + */ + protected $root = array(); + /** + * Indicated if doument is just a fragment (no tag). + * + * Every document is realy a full document, so even documentFragments can + * be queried against , but getDocument(id)->htmlOuter() will return + * only contents of . + * + * @var bool + */ + public $documentFragment = true; + /** + * Iterator interface helper + * @access private + */ + protected $elementsInterator = array(); + /** + * Iterator interface helper + * @access private + */ + protected $valid = false; + /** + * Iterator interface helper + * @access private + */ + protected $current = null; + + /** + * Indicates whether CSS has been parsed or not. We only parse CSS if needed. + * @access private + */ + protected $cssIsParsed = array(); + /** + * A collection of complete CSS selector strings. + * @access private; + */ + protected $cssString = array(); + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + + protected $attribute_css_mapping = array( + 'bgcolor' => 'background-color', + 'text' => 'color', + 'width' => 'width', + 'height' => 'height' + ); + + public function __construct($documentID) { + // if ($documentID instanceof self) + // var_dump($documentID->getDocumentID()); + $id = $documentID instanceof self ? $documentID->getDocumentID() + : $documentID; + // var_dump($id); + if (!isset(phpQuery::$documents[$id])) { + // var_dump(phpQuery::$documents); + throw new Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); + } + $this->documentID = $id; + $this->documentWrapper = &phpQuery::$documents[$id]; + $this->document = &$this->documentWrapper->document; + $this->xpath = &$this->documentWrapper->xpath; + $this->charset = &$this->documentWrapper->charset; + $this->documentFragment = &$this->documentWrapper->isDocumentFragment; + // TODO check $this->DOM->documentElement; + // $this->root = $this->document->documentElement; + $this->root = &$this->documentWrapper->root; + // $this->toRoot(); + $this->elements = array( + $this->root + ); + } + /** + * + * @access private + * @param $attr + * @return unknown_type + */ + public function __get($attr) { + switch ($attr) { + // FIXME doesnt work at all ? + case 'length': + return $this->size(); + break; + default: + return $this->$attr; + } + } + /** + * Saves actual object to $var by reference. + * Useful when need to break chain. + * @param PhpQueryObject $var + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toReference(&$var) { + return $var = $this; + } + public function documentFragment($state = null) { + if ($state) { + phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; + return $this; + } + return $this->documentFragment; + } + /** + * @access private + * @TODO documentWrapper + */ + protected function isRoot($node) { + // return $node instanceof \DOMDocument || $node->tagName == 'html'; + return $node instanceof \DOMDocument + || ($node instanceof \DOMElement && $node->tagName == 'html') + || $this->root->isSameNode($node); + } + /** + * @access private + */ + protected function stackIsRoot() { + return $this->size() == 1 && $this->isRoot($this->elements[0]); + } + /** + * Enter description here... + * NON JQUERY METHOD + * + * Watch out, it doesn't creates new instance, can be reverted with end(). + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toRoot() { + $this->elements = array( + $this->root + ); + return $this; + // return $this->newInstance(array($this->root)); + } + /** + * Saves object's DocumentID to $var by reference. + * + * $myDocumentId; + * phpQuery::newDocument('
    ') + * ->getDocumentIDRef($myDocumentId) + * ->find('div')->... + * + * + * @param unknown_type $domId + * @see phpQuery::newDocument + * @see phpQuery::newDocumentFile + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocumentIDRef(&$documentID) { + $documentID = $this->getDocumentID(); + return $this; + } + /** + * Returns object with stack set to document root. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocument() { + return phpQuery::getDocument($this->getDocumentID()); + } + /** + * + * @return \DOMDocument + */ + public function getDOMDocument() { + return $this->document; + } + /** + * Get object's Document ID. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocumentID() { + return $this->documentID; + } + /** + * Unloads whole document from memory. + * CAUTION! None further operations will be possible on this document. + * All objects refering to it will be useless. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function unloadDocument() { + phpQuery::unloadDocuments($this->getDocumentID()); + } + public function isHTML() { + return $this->documentWrapper->isHTML; + } + public function isXHTML() { + return $this->documentWrapper->isXHTML; + } + public function isXML() { + return $this->documentWrapper->isXML; + } + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/serialize + * @return string + */ + public function serialize() { + return phpQuery::param($this->serializeArray()); + } + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/serializeArray + * @return array + */ + public function serializeArray($submit = null) { + $source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not('form'); + $return = array(); + // $source->dumpDie(); + foreach ($source as $input) { + $input = phpQuery::pq($input); + if ($input->is('[disabled]')) + continue; + if (!$input->is('[name]')) + continue; + if ($input->is('[type=checkbox]') && !$input->is('[checked]')) + continue; + // jquery diff + if ($submit && $input->is('[type=submit]')) { + if ($submit instanceof \DOMElement + && !$input->elements[0]->isSameNode($submit)) + continue; + else if (is_string($submit) && $input->attr('name') != $submit) + continue; + } + $return[] = array( + 'name' => $input->attr('name'), + 'value' => $input->val(), + ); + } + return $return; + } + /** + * @access private + */ + protected function debug($in) { + if (!phpQuery::$debug) + return; + print('
    ');
    +    print_r($in);
    +    // file debug
    +    //		file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
    +    // quite handy debug trace
    +    //		if ( is_array($in))
    +    //			print_r(array_slice(debug_backtrace(), 3));
    +    print("
    \n"); + } + /** + * @access private + */ + protected function isRegexp($pattern) { + return in_array($pattern[mb_strlen($pattern) - 1], array( + '^', + '*', + '$' + )); + } + /** + * Determines if $char is really a char. + * + * @param string $char + * @return bool + * @todo rewrite me to charcode range ! ;) + * @access private + */ + protected function isChar($char) { + return extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_eregi('\w', $char) + : preg_match('@\w@', $char); + } + /** + * @access private + */ + protected function parseSelector($query) { + // clean spaces + // TODO include this inside parsing ? + $query = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query))); + $queries = array( + array() + ); + if (!$query) + return $queries; + $return = &$queries[0]; + $specialChars = array( + '>', + ' ' + ); + // $specialCharsMapping = array('/' => '>'); + $specialCharsMapping = array(); + $strlen = mb_strlen($query); + $classChars = array( + '.', + '-' + ); + $pseudoChars = array( + '-' + ); + $tagChars = array( + '*', + '|', + '-' + ); + // split multibyte string + // http://code.google.com/p/phpquery/issues/detail?id=76 + $_query = array(); + for ($i = 0; $i < $strlen; $i++) + $_query[] = mb_substr($query, $i, 1); + $query = $_query; + // it works, but i dont like it... + $i = 0; + while ($i < $strlen) { + $c = $query[$i]; + $tmp = ''; + // TAG + if ($this->isChar($c) || in_array($c, $tagChars)) { + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) { + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // IDs + } + else if ($c == '#') { + $i++; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || $query[$i] == '-')) { + $tmp .= $query[$i]; + $i++; + } + $return[] = '#' . $tmp; + // SPECIAL CHARS + } + else if (in_array($c, $specialChars)) { + $return[] = $c; + $i++; + // MAPPED SPECIAL MULTICHARS + // } else if ( $c.$query[$i+1] == '//') { + // $return[] = ' '; + // $i = $i+2; + // MAPPED SPECIAL CHARS + } + else if (isset($specialCharsMapping[$c])) { + $return[] = $specialCharsMapping[$c]; + $i++; + // COMMA + } + else if ($c == ',') { + $queries[] = array(); + $return = &$queries[count($queries) - 1]; + $i++; + while (isset($query[$i]) && $query[$i] == ' ') + $i++; + // CLASSES + } + else if ($c == '.') { + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) { + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // ~ General Sibling Selector + } + else if ($c == '~') { + $spaceAllowed = true; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) + || $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) { + if ($query[$i] != ' ') + $spaceAllowed = false; + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // + Adjacent sibling selectors + } + else if ($c == '+') { + $spaceAllowed = true; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) + || $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) { + if ($query[$i] != ' ') + $spaceAllowed = false; + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // ATTRS + } + else if ($c == '[') { + $stack = 1; + $tmp .= $c; + while (isset($query[++$i])) { + $tmp .= $query[$i]; + if ($query[$i] == '[') { + $stack++; + } + else if ($query[$i] == ']') { + $stack--; + if (!$stack) + break; + } + } + $return[] = $tmp; + $i++; + // PSEUDO CLASSES + } + else if ($c == ':') { + $stack = 1; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) { + $tmp .= $query[$i]; + $i++; + } + // with arguments ? + if (isset($query[$i]) && $query[$i] == '(') { + $tmp .= $query[$i]; + $stack = 1; + while (isset($query[++$i])) { + $tmp .= $query[$i]; + if ($query[$i] == '(') { + $stack++; + } + else if ($query[$i] == ')') { + $stack--; + if (!$stack) + break; + } + } + $return[] = $tmp; + $i++; + } + else { + $return[] = $tmp; + } + } + else { + $i++; + } + } + foreach ($queries as $k => $q) { + if (isset($q[0])) { + if (isset($q[0][0]) && $q[0][0] == ':') + array_unshift($queries[$k], '*'); + if ($q[0] != '>') + array_unshift($queries[$k], ' '); + } + } + return $queries; + } + /** + * Return matched DOM nodes. + * + * @param int $index + * @return array|\DOMElement Single \DOMElement or array of \DOMElement. + */ + public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { + $return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index] + : null) : $this->elements; + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + foreach ($args as $callback) { + if (is_array($return)) + foreach ($return as $k => $v) + $return[$k] = phpQuery::callbackRun($callback, array( + $v + )); + else + $return = phpQuery::callbackRun($callback, array( + $return + )); + } + return $return; + } + /** + * Return matched DOM nodes. + * jQuery difference. + * + * @param int $index + * @return array|string Returns string if $index != null + * @todo implement callbacks + * @todo return only arrays ? + * @todo maybe other name... + */ + public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { + if ($index) + $return = $this->eq($index)->text(); + else { + $return = array(); + for ($i = 0; $i < $this->size(); $i++) { + $return[] = $this->eq($i)->text(); + } + } + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + foreach ($args as $callback) { + $return = phpQuery::callbackRun($callback, array( + $return + )); + } + return $return; + } + /** + * Return matched DOM nodes. + * jQuery difference. + * + * @param int $index + * @return array|string Returns string if $index != null + * @todo implement callbacks + * @todo return only arrays ? + * @todo maybe other name... + */ + public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { + if ($index) + $return = $this->eq($index)->text(); + else { + $return = array(); + for ($i = 0; $i < $this->size(); $i++) { + $return[] = $this->eq($i)->text(); + } + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + } + foreach ($args as $callback) { + if (is_array($return)) + foreach ($return as $k => $v) + $return[$k] = phpQuery::callbackRun($callback, array( + $v + )); + else + $return = phpQuery::callbackRun($callback, array( + $return + )); + } + return $return; + } + /** + * Returns new instance of actual class. + * + * @param array $newStack Optional. Will replace old stack with new and move old one to history.c + */ + public function newInstance($newStack = null) { + $class = get_class($this); + // support inheritance by passing old object to overloaded constructor + $new = $class != 'phpQuery' ? new $class($this, $this->getDocumentID()) + : new PhpQueryObject($this->getDocumentID()); + $new->previous = $this; + if (is_null($newStack)) { + $new->elements = $this->elements; + if ($this->elementsBackup) + $this->elements = $this->elementsBackup; + } + else if (is_string($newStack)) { + $new->elements = phpQuery::pq($newStack, $this->getDocumentID())->stack(); + } + else { + $new->elements = $newStack; + } + return $new; + } + /** + * Enter description here... + * + * In the future, when PHP will support XLS 2.0, then we would do that this way: + * contains(tokenize(@class, '\s'), "something") + * @param unknown_type $class + * @param unknown_type $node + * @return boolean + * @access private + */ + protected function matchClasses($class, $node) { + // multi-class + if (mb_strpos($class, '.', 1)) { + $classes = explode('.', substr($class, 1)); + $classesCount = count($classes); + $nodeClasses = explode(' ', $node->getAttribute('class')); + $nodeClassesCount = count($nodeClasses); + if ($classesCount > $nodeClassesCount) + return false; + $diff = count(array_diff($classes, $nodeClasses)); + if (!$diff) + return true; + // single-class + } + else { + return in_array( + // strip leading dot from class name + substr($class, 1), + // get classes for element as array + explode(' ', $node->getAttribute('class'))); + } + } + /** + * @access private + */ + protected function runQuery($XQuery, $selector = null, $compare = null) { + if ($compare && !method_exists($this, $compare)) + return false; + $stack = array(); + if (!$this->elements) + $this->debug('Stack empty, skipping...'); + // var_dump($this->elements[0]->nodeType); + // element, document + foreach ($this->stack(array( + 1, + 9, + 13 + )) as $k => $stackNode) { + $detachAfter = false; + // to work on detached nodes we need temporary place them somewhere + // thats because context xpath queries sucks ;] + $testNode = $stackNode; + while ($testNode) { + if (!$testNode->parentNode && !$this->isRoot($testNode)) { + $this->root->appendChild($testNode); + $detachAfter = $testNode; + break; + } + $testNode = isset($testNode->parentNode) ? $testNode->parentNode : null; + } + // XXX tmp ? + $xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html') + : $this->getNodeXpath($stackNode); + // FIXME pseudoclasses-only query, support XML + $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*' + : $xpath . $XQuery; + $this->debug("XPATH: {$query}"); + // run query, get elements + $nodes = $this->xpath->query($query); + $this->debug("QUERY FETCHED"); + if (!$nodes->length) + $this->debug('Nothing found'); + $debug = array(); + foreach ($nodes as $node) { + $matched = false; + if ($compare) { + phpQuery::$debug ? $this->debug("Found: " . $this->whois($node) + . ", comparing with {$compare}()") : null; + $phpQueryDebug = phpQuery::$debug; + phpQuery::$debug = false; + // TODO ??? use phpQuery::callbackRun() + if (call_user_func_array(array( + $this, + $compare + ), array( + $selector, + $node + ))) + $matched = true; + phpQuery::$debug = $phpQueryDebug; + } + else { + $matched = true; + } + if ($matched) { + if (phpQuery::$debug) + $debug[] = $this->whois($node); + $stack[] = $node; + } + } + if (phpQuery::$debug) { + $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug)); + } + if ($detachAfter) + $this->root->removeChild($detachAfter); + } + $this->elements = $stack; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function find($selectors, $context = null, $noHistory = false) { + if (!$noHistory) + // backup last stack /for end()/ + $this->elementsBackup = $this->elements; + // allow to define context + // TODO combine code below with phpQuery::pq() context guessing code + // as generic function + if (isset($context)) { + if (!is_array($context) && $context instanceof \DOMElement) { + $this->elements = array( + $context + ); + } + elseif (is_array($context)) { + $this->elements = array(); + foreach ($context as $c) + if ($c instanceof \DOMElement) + $this->elements[] = $c; + } + elseif ($context instanceof PhpQueryObject) { + $this->elements = $context->elements; + } + } + + $queries = $this->parseSelector($selectors); + + $this->debug(array( + 'FIND', + $selectors, + $queries + )); + $XQuery = ''; + // remember stack state because of multi-queries + $oldStack = $this->elements; + // here we will be keeping found elements + $stack = array(); + foreach ($queries as $selector) { + $this->elements = $oldStack; + $delimiterBefore = false; + foreach ($selector as $s) { + // TAG + $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s) + || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*'; + if ($isTag) { + if ($this->isXML()) { + // namespace support + if (mb_strpos($s, '|') !== false) { + $ns = $tag = null; + list($ns, $tag) = explode('|', $s); + $XQuery .= "$ns:$tag"; + } + else if ($s == '*') { + $XQuery .= "*"; + } + else { + $XQuery .= "*[local-name()='$s']"; + } + } + else { + $XQuery .= $s; + } + // ID + } + else if ($s[0] == '#') { + if ($delimiterBefore) + $XQuery .= '*'; + $XQuery .= "[@id='" . substr($s, 1) . "']"; + // ATTRIBUTES + } + else if ($s[0] == '[') { + if ($delimiterBefore) + $XQuery .= '*'; + // strip side brackets + $attr = trim($s, ']['); + $execute = false; + // attr with specifed value + if (mb_strpos($s, '=')) { + $value = null; + list($attr, $value) = explode('=', $attr); + $value = trim($value, "'\""); + if ($this->isRegexp($attr)) { + // cut regexp character + $attr = substr($attr, 0, -1); + $execute = true; + $XQuery .= "[@{$attr}]"; + } + else { + $XQuery .= "[@{$attr}='{$value}']"; + } + // attr without specified value + } + else { + $XQuery .= "[@{$attr}]"; + } + if ($execute) { + $this->runQuery($XQuery, $s, 'is'); + $XQuery = ''; + if (!$this->length()) + break; + } + // CLASSES + } + else if ($s[0] == '.') { + // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]"); + // thx wizDom ;) + if ($delimiterBefore) + $XQuery .= '*'; + $XQuery .= '[@class]'; + $this->runQuery($XQuery, $s, 'matchClasses'); + $XQuery = ''; + if (!$this->length()) + break; + // ~ General Sibling Selector + } + else if ($s[0] == '~') { + $this->runQuery($XQuery); + $XQuery = ''; + $this->elements = $this->siblings(substr($s, 1))->elements; + if (!$this->length()) + break; + // + Adjacent sibling selectors + } + else if ($s[0] == '+') { + // TODO /following-sibling:: + $this->runQuery($XQuery); + $XQuery = ''; + $subSelector = substr($s, 1); + $subElements = $this->elements; + $this->elements = array(); + foreach ($subElements as $node) { + // search first \DOMElement sibling + $test = $node->nextSibling; + while ($test && !($test instanceof \DOMElement)) + $test = $test->nextSibling; + if ($test && $this->is($subSelector, $test)) + $this->elements[] = $test; + } + if (!$this->length()) + break; + // PSEUDO CLASSES + } + else if ($s[0] == ':') { + // TODO optimization for :first :last + if ($XQuery) { + $this->runQuery($XQuery); + $XQuery = ''; + } + if (!$this->length()) + break; + $this->pseudoClasses($s); + if (!$this->length()) + break; + // DIRECT DESCENDANDS + } + else if ($s == '>') { + $XQuery .= '/'; + $delimiterBefore = 2; + // ALL DESCENDANDS + } + else if ($s == ' ') { + $XQuery .= '//'; + $delimiterBefore = 2; + // ERRORS + } + else { + phpQuery::debug("Unrecognized token '$s'"); + } + $delimiterBefore = $delimiterBefore === 2; + } + // run query if any + if ($XQuery && $XQuery != '//') { + $this->runQuery($XQuery); + $XQuery = ''; + } + foreach ($this->elements as $node) + if (!$this->elementsContainsNode($node, $stack)) + $stack[] = $node; + } + $this->elements = $stack; + return $this->newInstance(); + } + /** + * @todo create API for classes with pseudoselectors + * @access private + */ + protected function pseudoClasses($class) { + // TODO clean args parsing ? + $class = ltrim($class, ':'); + $haveArgs = mb_strpos($class, '('); + if ($haveArgs !== false) { + $args = substr($class, $haveArgs + 1, -1); + $class = substr($class, 0, $haveArgs); + } + switch ($class) { + case 'even': + case 'odd': + $stack = array(); + foreach ($this->elements as $i => $node) { + if ($class == 'even' && ($i % 2) == 0) + $stack[] = $node; + else if ($class == 'odd' && $i % 2) + $stack[] = $node; + } + $this->elements = $stack; + break; + case 'eq': + $k = intval($args); + $this->elements = isset($this->elements[$k]) ? array( + $this->elements[$k] + ) : array(); + break; + case 'gt': + $this->elements = array_slice($this->elements, $args + 1); + break; + case 'lt': + $this->elements = array_slice($this->elements, 0, $args + 1); + break; + case 'first': + if (isset($this->elements[0])) + $this->elements = array( + $this->elements[0] + ); + break; + case 'last': + if ($this->elements) + $this->elements = array( + $this->elements[count($this->elements) - 1] + ); + break; + /*case 'parent': + $stack = array(); + foreach($this->elements as $node) { + if ( $node->childNodes->length ) + $stack[] = $node; + } + $this->elements = $stack; + break;*/ + case 'contains': + $text = trim($args, "\"'"); + $stack = array(); + foreach ($this->elements as $node) { + if (mb_stripos($node->textContent, $text) === false) + continue; + $stack[] = $node; + } + $this->elements = $stack; + break; + case 'not': + $selector = self::unQuote($args); + $this->elements = $this->not($selector)->stack(); + break; + case 'slice': + // TODO jQuery difference ? + $args = explode(',', str_replace(', ', ',', trim($args, "\"'"))); + $start = $args[0]; + $end = isset($args[1]) ? $args[1] : null; + if ($end > 0) + $end = $end - $start; + $this->elements = array_slice($this->elements, $start, $end); + break; + case 'has': + $selector = trim($args, "\"'"); + $stack = array(); + foreach ($this->stack(1) as $el) { + if ($this->find($selector, $el, true)->length) + $stack[] = $el; + } + $this->elements = $stack; + break; + case 'submit': + case 'reset': + $this->elements = phpQuery::merge($this->map(array( + $this, + 'is' + ), "input[type=$class]", new CallbackParam()), $this->map(array( + $this, + 'is' + ), "button[type=$class]", new CallbackParam())); + break; + // $stack = array(); + // foreach($this->elements as $node) + // if ($node->is('input[type=submit]') || $node->is('button[type=submit]')) + // $stack[] = $el; + // $this->elements = $stack; + case 'input': + $this->elements = $this->map(array( + $this, + 'is' + ), 'input', new CallbackParam())->elements; + break; + case 'password': + case 'checkbox': + case 'radio': + case 'hidden': + case 'image': + case 'file': + $this->elements = $this->map(array( + $this, + 'is' + ), "input[type=$class]", new CallbackParam())->elements; + break; + case 'parent': + $this->elements = $this->map(create_function('$node', ' + return $node instanceof \DOMElement && $node->childNodes->length + ? $node : null;'))->elements; + break; + case 'empty': + $this->elements = $this->map(create_function('$node', ' + return $node instanceof \DOMElement && $node->childNodes->length + ? null : $node;'))->elements; + break; + case 'disabled': + case 'selected': + case 'checked': + $this->elements = $this->map(array( + $this, + 'is' + ), "[$class]", new CallbackParam())->elements; + break; + case 'enabled': + $this->elements = $this->map(create_function('$node', ' + return pq($node)->not(":disabled") ? $node : null;'))->elements; + break; + case 'header': + $this->elements = $this->map(create_function('$node', '$isHeader = isset($node->tagName) && in_array($node->tagName, array( + "h1", "h2", "h3", "h4", "h5", "h6", "h7" + )); + return $isHeader + ? $node + : null;'))->elements; + // $this->elements = $this->map( + // create_function('$node', '$node = pq($node); + // return $node->is("h1") + // || $node->is("h2") + // || $node->is("h3") + // || $node->is("h4") + // || $node->is("h5") + // || $node->is("h6") + // || $node->is("h7") + // ? $node + // : null;') + // )->elements; + break; + case 'only-child': + $this->elements = $this->map(create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;'))->elements; + break; + case 'first-child': + $this->elements = $this->map(create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;'))->elements; + break; + case 'last-child': + $this->elements = $this->map(create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;'))->elements; + break; + case 'nth-child': + $param = trim($args, "\"'"); + if (!$param) + break; + // nth-child(n+b) to nth-child(1n+b) + if ($param{0} == 'n') + $param = '1' . $param; + // :nth-child(index/even/odd/equation) + if ($param == 'even' || $param == 'odd') + $mapped = $this->map(create_function('$node, $param', '$index = pq($node)->prevAll()->size()+1; + if ($param == "even" && ($index%2) == 0) + return $node; + else if ($param == "odd" && $index%2 == 1) + return $node; + else + return null;'), new CallbackParam(), $param); + else if (mb_strlen($param) > 1 + && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1) + // an+b + $mapped = $this->map(create_function('$node, $param', '$prevs = pq($node)->prevAll()->size(); + $index = 1+$prevs; + + preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches); + $a = intval($matches[1]); + $b = intval($matches[3]); + if( $matches[2] === "-" ) { + $b = -$b; + } + + if ($a > 0) { + return ($index-$b)%$a == 0 + ? $node + : null; + phpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs"); + return $a*floor($index/$a)+$b-1 == $prevs + ? $node + : null; + } else if ($a == 0) + return $index == $b + ? $node + : null; + else + // negative value + return $index <= $b + ? $node + : null; +// if (! $b) +// return $index%$a == 0 +// ? $node +// : null; +// else +// return ($index-$b)%$a == 0 +// ? $node +// : null; + '), new CallbackParam(), $param); + else + // index + $mapped = $this->map(create_function('$node, $index', '$prevs = pq($node)->prevAll()->size(); + if ($prevs && $prevs == $index-1) + return $node; + else if (! $prevs && $index == 1) + return $node; + else + return null;'), new CallbackParam(), $param); + $this->elements = $mapped->elements; + break; + default: + $this->debug("Unknown pseudoclass '{$class}', skipping..."); + } + } + /** + * @access private + */ + protected function __pseudoClassParam($paramsString) { + // TODO; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function is($selector, $nodes = null) { + phpQuery::debug(array( + "Is:", + $selector + )); + if (!$selector) + return false; + $oldStack = $this->elements; + $returnArray = false; + if ($nodes && is_array($nodes)) { + $this->elements = $nodes; + } + else if ($nodes) + $this->elements = array( + $nodes + ); + $this->filter($selector, true); + $stack = $this->elements; + $this->elements = $oldStack; + if ($nodes) + return $stack ? $stack : null; + return (bool) count($stack); + } + /** + * Enter description here... + * jQuery difference. + * + * Callback: + * - $index int + * - $node DOMNode + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @link http://docs.jquery.com/Traversing/filter + */ + public function filterCallback($callback, $_skipHistory = false) { + if (!$_skipHistory) { + $this->elementsBackup = $this->elements; + $this->debug("Filtering by callback"); + } + $newStack = array(); + foreach ($this->elements as $index => $node) { + $result = phpQuery::callbackRun($callback, array( + $index, + $node + )); + if (is_null($result) || (!is_null($result) && $result)) + $newStack[] = $node; + } + $this->elements = $newStack; + return $_skipHistory ? $this : $this->newInstance(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @link http://docs.jquery.com/Traversing/filter + */ + public function filter($selectors, $_skipHistory = false) { + if ($selectors instanceof Callback OR $selectors instanceof Closure) + return $this->filterCallback($selectors, $_skipHistory); + if (!$_skipHistory) + $this->elementsBackup = $this->elements; + $notSimpleSelector = array( + ' ', + '>', + '~', + '+', + '/' + ); + if (!is_array($selectors)) + $selectors = $this->parseSelector($selectors); + if (!$_skipHistory) + $this->debug(array( + "Filtering:", + $selectors + )); + $finalStack = array(); + foreach ($selectors as $selector) { + $stack = array(); + if (!$selector) + break; + // avoid first space or / + if (in_array($selector[0], $notSimpleSelector)) + $selector = array_slice($selector, 1); + // PER NODE selector chunks + foreach ($this->stack() as $node) { + $break = false; + foreach ($selector as $s) { + if (!($node instanceof \DOMElement)) { + // all besides \DOMElement + if ($s[0] == '[') { + $attr = trim($s, '[]'); + if (mb_strpos($attr, '=')) { + list($attr, $val) = explode('=', $attr); + if ($attr == 'nodeType' && $node->nodeType != $val) + $break = true; + } + } + else + $break = true; + } + else { + // \DOMElement only + // ID + if ($s[0] == '#') { + if ($node->getAttribute('id') != substr($s, 1)) + $break = true; + // CLASSES + } + else if ($s[0] == '.') { + if (!$this->matchClasses($s, $node)) + $break = true; + // ATTRS + } + else if ($s[0] == '[') { + // strip side brackets + $attr = trim($s, '[]'); + if (mb_strpos($attr, '=')) { + list($attr, $val) = explode('=', $attr); + $val = self::unQuote($val); + if ($attr == 'nodeType') { + if ($val != $node->nodeType) + $break = true; + } + else if ($this->isRegexp($attr)) { + $val = extension_loaded('mbstring') + && phpQuery::$mbstringSupport ? quotemeta(trim($val, '"\'')) + : preg_quote(trim($val, '"\''), '@'); + // switch last character + switch (substr($attr, -1)) { + // quotemeta used insted of preg_quote + // http://code.google.com/p/phpquery/issues/detail?id=76 + case '^': + $pattern = '^' . $val; + break; + case '*': + $pattern = '.*' . $val . '.*'; + break; + case '$': + $pattern = '.*' . $val . '$'; + break; + } + // cut last character + $attr = substr($attr, 0, -1); + $isMatch = extension_loaded('mbstring') + && phpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr)) + : preg_match("@{$pattern}@", $node->getAttribute($attr)); + if (!$isMatch) + $break = true; + } + else if ($node->getAttribute($attr) != $val) + $break = true; + } + else if (!$node->hasAttribute($attr)) + $break = true; + // PSEUDO CLASSES + } + else if ($s[0] == ':') { + // skip + // TAG + } + else if (trim($s)) { + if ($s != '*') { + // TODO namespaces + if (isset($node->tagName)) { + if ($node->tagName != $s) + $break = true; + } + else if ($s == 'html' && !$this->isRoot($node)) + $break = true; + } + // AVOID NON-SIMPLE SELECTORS + } + else if (in_array($s, $notSimpleSelector)) { + $break = true; + $this->debug(array( + 'Skipping non simple selector', + $selector + )); + } + } + if ($break) + break; + } + // if element passed all chunks of selector - add it to new stack + if (!$break) + $stack[] = $node; + } + $tmpStack = $this->elements; + $this->elements = $stack; + // PER ALL NODES selector chunks + foreach ($selector as $s) + // PSEUDO CLASSES + if ($s[0] == ':') + $this->pseudoClasses($s); + foreach ($this->elements as $node) + // XXX it should be merged without duplicates + // but jQuery doesnt do that + $finalStack[] = $node; + $this->elements = $tmpStack; + } + $this->elements = $finalStack; + if ($_skipHistory) { + return $this; + } + else { + $this->debug("Stack length after filter(): " . count($finalStack)); + return $this->newInstance(); + } + } + /** + * + * @param $value + * @return unknown_type + * @TODO implement in all methods using passed parameters + */ + protected static function unQuote($value) { + return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1) + : $value; + } + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/load + * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo Support $selector + */ + public function load($url, $data = null, $callback = null) { + if ($data && !is_array($data)) { + $callback = $data; + $data = null; + } + if (mb_strpos($url, ' ') !== false) { + $matches = null; + if (extension_loaded('mbstring') && phpQuery::$mbstringSupport) + mb_ereg('^([^ ]+) (.*)$', $url, $matches); + else + preg_match('@^([^ ]+) (.*)$@', $url, $matches); + $url = $matches[1]; + $selector = $matches[2]; + // FIXME this sucks, pass as callback param + $this->_loadSelector = $selector; + } + $ajax = array( + 'url' => $url, + 'type' => $data ? 'POST' : 'GET', + 'data' => $data, + 'complete' => $callback, + 'success' => array( + $this, + '__loadSuccess' + ) + ); + phpQuery::ajax($ajax); + return $this; + } + /** + * @access private + * @param $html + * @return unknown_type + */ + public function __loadSuccess($html) { + if ($this->_loadSelector) { + $html = phpQuery::newDocument($html)->find($this->_loadSelector); + unset($this->_loadSelector); + } + foreach ($this->stack(1) as $node) { + phpQuery::pq($node, $this->getDocumentID())->markup($html); + } + } + + /** + * Allows users to enter strings of CSS selectors. Useful + * when the CSS is loaded via style or @imports that phpQuery can't load + * because it doesn't know the URL context of the request. + */ + public function addCSS($string) { + if (!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = ''; + } + $this->cssString[$this->getDocumentID()] .= $string; + $this->parseCSS(); + } + /** + * Either sets the CSS property of an object or retrieves the + * CSS property of a proejct. + * + * @return string of css property value + * @todo + */ + public function css($property_name, $value = FALSE) { + if (!isset($this->cssIsParsed[$this->getDocumentID()]) + || $this->cssIsParsed[$this->getDocumentID()] = false) { + $this->parseCSS(); + } + $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); + if (!$value) { + if (isset($data[$property_name])) { + return $data[$property_name]['value']; + } + return null; + } + $specificity = (isset($data[$property_name])) ? $data[$property_name]['specificity'] + + 1 : 1000; + $data[$property_name] = array( + 'specificity' => $specificity, + 'value' => $value + ); + phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); + $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); + + if ($specificity >= 1000) { + $styles = array(); + foreach ($this->data('phpquery_css') as $k => $v) { + if ($v['specificity'] >= 1000) { + $styles[$k] = trim($k) . ':' . trim($v['value']); + } + } + ksort($styles); + if (empty($styles)) { + $this->removeAttr('style'); + } + elseif (phpQuery::$enableCssShorthand) { + $parser = new Sabberworm\CSS\Parser('{' . join(';', $styles) . '}'); + $doc = $parser->parse(); + $doc->createShorthands(); + $style = trim($doc->__toString(), "\n\r\t {}"); + } + else { + $style = join(';', $styles); + } + $this->attr('style', $style); + } + } + + public function parseCSS() { + if (!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) + . '/Resources/default.css'); + } + foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) { + $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); + } + + $CssParser = new CssParser($this->cssString[$this->getDocumentID()]); + $CssDocument = $CssParser->parse(); + foreach ($CssDocument->getAllRuleSets() as $ruleset) { + foreach ($ruleset->getSelector() as $selector) { + $specificity = $selector->getSpecificity(); + foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || $existing[$rule]['specificity'] <= $specificity) { + $value = $value->getValue(); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => $specificity, + 'value' => $value + ); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); + } + } + } + foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + $style = pq($el)->attr('style'); + $style = strlen($style) ? explode(';', $style) : array(); + foreach ($this->attribute_css_mapping as $map => $css_equivalent) { + if ($el->hasAttribute($map)) { + $style[] = $css_equivalent . ':' . pq($el)->attr($map); + } + } + if (count($style)) { + $CssParser = new CssParser('#ruleset {' . implode(';', $style) . '}'); + $CssDocument = $CssParser->parse(); + $ruleset = $CssDocument->getAllRulesets(); + $ruleset = reset($ruleset); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || 1000 >= $existing[$rule]['specificity']) { + $value = $value->getValue(); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => 1000, + 'value' => $value + ); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); + } + } + } + + protected function bubbleCSS($element) { + $style = $element->data('phpquery_css'); + foreach ($element->children() as $element_child) { + $existing = phpQuery::pq($element_child)->data('phpquery_css'); + foreach ($style as $rule => $value) { + if (!isset($existing[$rule]) + || $value['specificity'] > $existing[$rule]['specificity']) { + $existing[$rule] = $value; + } + } + phpQuery::pq($element_child)->data('phpquery_css', $existing); + if (phpQuery::pq($element_child)->children()->length) { + $this->bubbleCSS(phpQuery::pq($element_child)); + } + } + } + + /** + * @todo + * + */ + public function show() { + $display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state') + : 'block'; + $this->css('display', $display); + return $this; + } + /** + * @todo + * + */ + public function hide() { + $this->data('phpquery_display_state', $this->css('display')); + $this->css('display', 'none'); + return $this; + } + /** + * Trigger a type of event on every matched element. + * + * @param unknown_type $type + * @param unknown_type $data + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support more than event in $type (space-separated) + */ + public function trigger($type, $data = array()) { + foreach ($this->elements as $node) + PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node); + return $this; + } + /** + * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. + * + * @param unknown_type $type + * @param unknown_type $data + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO + */ + public function triggerHandler($type, $data = array()) { + // TODO; + } + /** + * Binds a handler to one or more events (like click) for each matched element. + * Can also bind custom events. + * + * @param unknown_type $type + * @param unknown_type $data Optional + * @param unknown_type $callback + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support '!' (exclusive) events + * @TODO support more than event in $type (space-separated) + */ + public function bind($type, $data, $callback = null) { + // TODO check if $data is callable, not using is_callable + if (!isset($callback)) { + $callback = $data; + $data = null; + } + foreach ($this->elements as $node) + PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback); + return $this; + } + /** + * Enter description here... + * + * @param unknown_type $type + * @param unknown_type $callback + * @return unknown + * @TODO namespace events + * @TODO support more than event in $type (space-separated) + */ + public function unbind($type = null, $callback = null) { + foreach ($this->elements as $node) + PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback); + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function change($callback = null) { + if ($callback) + return $this->bind('change', $callback); + return $this->trigger('change'); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function submit($callback = null) { + if ($callback) + return $this->bind('submit', $callback); + return $this->trigger('submit'); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function click($callback = null) { + if ($callback) + return $this->bind('click', $callback); + return $this->trigger('click'); + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAllOld($wrapper) { + $wrapper = pq($wrapper)->_clone(); + if (!$wrapper->length() || !$this->length()) + return $this; + $wrapper->insertBefore($this->elements[0]); + $deepest = $wrapper->elements[0]; + while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) + $deepest = $deepest->firstChild; + pq($deepest)->append($this); + return $this; + } + /** + * Enter description here... + * + * TODO testme... + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAll($wrapper) { + if (!$this->length()) + return $this; + return phpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(array( + $this, + '___wrapAllCallback' + ))->append($this); + } + /** + * + * @param $node + * @return unknown_type + * @access private + */ + public function ___wrapAllCallback($node) { + $deepest = $node; + while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) + $deepest = $deepest->firstChild; + return $deepest; + } + /** + * Enter description here... + * NON JQUERY METHOD + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAllPHP($codeBefore, $codeAfter) { + return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end(); + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrap($wrapper) { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper); + return $this; + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapPHP($codeBefore, $codeAfter) { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter); + return $this; + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapInner($wrapper) { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper); + return $this; + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapInnerPHP($codeBefore, $codeAfter) { + foreach ($this->stack(1) as $node) + phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter); + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @testme Support for text nodes + */ + public function contents() { + $stack = array(); + foreach ($this->stack(1) as $el) { + // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56 + // if (! isset($el->childNodes)) + // continue; + foreach ($el->childNodes as $node) { + $stack[] = $node; + } + } + return $this->newInstance($stack); + } + /** + * Enter description here... + * + * jQuery difference. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function contentsUnwrap() { + foreach ($this->stack(1) as $node) { + if (!$node->parentNode) + continue; + $childNodes = array(); + // any modification in DOM tree breaks childNodes iteration, so cache them first + foreach ($node->childNodes as $chNode) + $childNodes[] = $chNode; + foreach ($childNodes as $chNode) + // $node->parentNode->appendChild($chNode); + $node->parentNode->insertBefore($chNode, $node); + $node->parentNode->removeChild($node); + } + return $this; + } + /** + * Enter description here... + * + * jQuery difference. + */ + public function switchWith($markup) { + $markup = pq($markup, $this->getDocumentID()); + $content = null; + foreach ($this->stack(1) as $node) { + pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content)); + } + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function eq($num) { + $oldStack = $this->elements; + $this->elementsBackup = $this->elements; + $this->elements = array(); + if (isset($oldStack[$num])) + $this->elements[] = $oldStack[$num]; + return $this->newInstance(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function size() { + return count($this->elements); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @deprecated Use length as attribute + */ + public function length() { + return $this->size(); + } + public function count() { + return $this->size(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo $level + */ + public function end($level = 1) { + // $this->elements = array_pop( $this->history ); + // return $this; + // $this->previous->DOM = $this->DOM; + // $this->previous->XPath = $this->XPath; + return $this->previous ? $this->previous : $this; + } + /** + * Enter description here... + * Normal use ->clone() . + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _clone() { + $newStack = array(); + //pr(array('copy... ', $this->whois())); + //$this->dumpHistory('copy'); + $this->elementsBackup = $this->elements; + foreach ($this->elements as $node) { + $newStack[] = $node->cloneNode(true); + } + $this->elements = $newStack; + return $this->newInstance(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function replaceWithPHP($code) { + return $this->replaceWith(phpQuery::php($code)); + } + /** + * Enter description here... + * + * @param String|phpQuery $content + * @link http://docs.jquery.com/Manipulation/replaceWith#content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function replaceWith($content) { + return $this->after($content)->remove(); + } + /** + * Enter description here... + * + * @param String $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo this works ? + */ + public function replaceAll($selector) { + foreach (phpQuery::pq($selector, $this->getDocumentID()) as $node) + phpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove(); + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function remove($selector = null) { + $loop = $selector ? $this->filter($selector)->elements : $this->elements; + foreach ($loop as $node) { + if (!$node->parentNode) + continue; + if (isset($node->tagName)) + $this->debug("Removing '{$node->tagName}'"); + $node->parentNode->removeChild($node); + // Mutation event + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'DOMNodeRemoved' + )); + PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( + $event + ), $node); + } + return $this; + } + protected function markupEvents($newMarkup, $oldMarkup, $node) { + if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) { + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( + $event + ), $node); + } + } + /** + * jQuey difference + * + * @param $markup + * @return unknown_type + * @TODO trigger change event for textarea + */ + public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null) { + $args = func_get_args(); + if ($this->documentWrapper->isXML) + return call_user_func_array(array( + $this, + 'xml' + ), $args); + else + return call_user_func_array(array( + $this, + 'html' + ), $args); + } + /** + * jQuey difference + * + * @param $markup + * @return unknown_type + */ + public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null) { + $args = func_get_args(); + if ($this->documentWrapper->isXML) + return call_user_func_array(array( + $this, + 'xmlOuter' + ), $args); + else + return call_user_func_array(array( + $this, + 'htmlOuter' + ), $args); + } + /** + * Enter description here... + * + * @param unknown_type $html + * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO force html result + */ + public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null) { + if (isset($html)) { + // INSERT + $nodes = $this->documentWrapper->import($html); + $this->empty(); + foreach ($this->stack(1) as $alreadyAdded => $node) { + // for now, limit events for textarea + if (($this->isXHTML() || $this->isHTML()) + && $node->tagName == 'textarea') + $oldHtml = pq($node, $this->getDocumentID())->markup(); + foreach ($nodes as $newNode) { + $node->appendChild($alreadyAdded ? $newNode->cloneNode(true) + : $newNode); + } + // for now, limit events for textarea + if (($this->isXHTML() || $this->isHTML()) + && $node->tagName == 'textarea') + $this->markupEvents($html, $oldHtml, $node); + } + return $this; + } + else { + // FETCH + $return = $this->documentWrapper->markup($this->elements, true); + $args = func_get_args(); + foreach (array_slice($args, 1) as $callback) { + $return = phpQuery::callbackRun($callback, array( + $return + )); + } + return $return; + } + } + /** + * @TODO force xml result + */ + public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null) { + $args = func_get_args(); + return call_user_func_array(array( + $this, + 'html' + ), $args); + } + /** + * Enter description here... + * @TODO force html result + * + * @return String + */ + public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { + $markup = $this->documentWrapper->markup($this->elements); + // pass thou callbacks + $args = func_get_args(); + foreach ($args as $callback) { + $markup = phpQuery::callbackRun($callback, array( + $markup + )); + } + return $markup; + } + /** + * @TODO force xml result + */ + public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { + $args = func_get_args(); + return call_user_func_array(array( + $this, + 'htmlOuter' + ), $args); + } + public function __toString() { + return $this->markupOuter(); + } + /** + * Just like html(), but returns markup with VALID (dangerous) PHP tags. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo support returning markup with PHP tags when called without param + */ + public function php($code = null) { + return $this->markupPHP($code); + } + /** + * Enter description here... + * + * @param $code + * @return unknown_type + */ + public function markupPHP($code = null) { + return isset($code) ? $this->markup(phpQuery::php($code)) + : phpQuery::markupToPHP($this->markup()); + } + /** + * Enter description here... + * + * @param $code + * @return unknown_type + */ + public function markupOuterPHP() { + return phpQuery::markupToPHP($this->markupOuter()); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function children($selector = null) { + $stack = array(); + foreach ($this->stack(1) as $node) { + // foreach($node->getElementsByTagName('*') as $newNode) { + foreach ($node->childNodes as $newNode) { + if ($newNode->nodeType != 1) + continue; + if ($selector && !$this->is($selector, $newNode)) + continue; + if ($this->elementsContainsNode($newNode, $stack)) + continue; + $stack[] = $newNode; + } + } + $this->elementsBackup = $this->elements; + $this->elements = $stack; + return $this->newInstance(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function ancestors($selector = null) { + return $this->children($selector); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function append($content) { + return $this->insert($content, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function appendPHP($content) { + return $this->insert("", 'append'); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function appendTo($seletor) { + return $this->insert($seletor, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prepend($content) { + return $this->insert($content, __FUNCTION__); + } + /** + * Enter description here... + * + * @todo accept many arguments, which are joined, arrays maybe also + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prependPHP($content) { + return $this->insert("", 'prepend'); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prependTo($seletor) { + return $this->insert($seletor, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function before($content) { + return $this->insert($content, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function beforePHP($content) { + return $this->insert("", 'before'); + } + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function insertBefore($seletor) { + return $this->insert($seletor, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function after($content) { + return $this->insert($content, __FUNCTION__); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function afterPHP($content) { + return $this->insert("", 'after'); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function insertAfter($seletor) { + return $this->insert($seletor, __FUNCTION__); + } + /** + * Internal insert method. Don't use it. + * + * @param unknown_type $target + * @param unknown_type $type + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function insert($target, $type) { + $this->debug("Inserting data with '{$type}'"); + $to = false; + switch ($type) { + case 'appendTo': + case 'prependTo': + case 'insertBefore': + case 'insertAfter': + $to = true; + } + switch (gettype($target)) { + case 'string': + $insertFrom = $insertTo = array(); + if ($to) { + // INSERT TO + $insertFrom = $this->elements; + if (phpQuery::isMarkup($target)) { + // $target is new markup, import it + $insertTo = $this->documentWrapper->import($target); + // insert into selected element + } + else { + // $tagret is a selector + $thisStack = $this->elements; + $this->toRoot(); + $insertTo = $this->find($target)->elements; + $this->elements = $thisStack; + } + } + else { + // INSERT FROM + $insertTo = $this->elements; + $insertFrom = $this->documentWrapper->import($target); + } + break; + case 'object': + $insertFrom = $insertTo = array(); + // phpQuery + if ($target instanceof self) { + if ($to) { + $insertTo = $target->elements; + if ($this->documentFragment && $this->stackIsRoot()) + // get all body children + // $loop = $this->find('body > *')->elements; + // TODO test it, test it hard... + // $loop = $this->newInstance($this->root)->find('> *')->elements; + $loop = $this->root->childNodes; + else + $loop = $this->elements; + // import nodes if needed + $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop + : $target->documentWrapper->import($loop); + } + else { + $insertTo = $this->elements; + if ($target->documentFragment && $target->stackIsRoot()) + // get all body children + // $loop = $target->find('body > *')->elements; + $loop = $target->root->childNodes; + else + $loop = $target->elements; + // import nodes if needed + $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop + : $this->documentWrapper->import($loop); + } + // DOMNODE + } + elseif ($target instanceof DOMNODE) { + // import node if needed + // if ( $target->ownerDocument != $this->DOM ) + // $target = $this->DOM->importNode($target, true); + if ($to) { + $insertTo = array( + $target + ); + if ($this->documentFragment && $this->stackIsRoot()) + // get all body children + $loop = $this->root->childNodes; + // $loop = $this->find('body > *')->elements; + else + $loop = $this->elements; + foreach ($loop as $fromNode) + // import nodes if needed + $insertFrom[] = !$fromNode->ownerDocument->isSameNode($target->ownerDocument) ? $target->ownerDocument->importNode($fromNode, true) + : $fromNode; + } + else { + // import node if needed + if (!$target->ownerDocument->isSameNode($this->document)) + $target = $this->document->importNode($target, true); + $insertTo = $this->elements; + $insertFrom[] = $target; + } + } + break; + } + phpQuery::debug("From " . count($insertFrom) . "; To " . count($insertTo) + . " nodes"); + foreach ($insertTo as $insertNumber => $toNode) { + // we need static relative elements in some cases + switch ($type) { + case 'prependTo': + case 'prepend': + $firstChild = $toNode->firstChild; + break; + case 'insertAfter': + case 'after': + $nextSibling = $toNode->nextSibling; + break; + } + foreach ($insertFrom as $fromNode) { + // clone if inserted already before + $insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode; + switch ($type) { + case 'appendTo': + case 'append': + // $toNode->insertBefore( + // $fromNode, + // $toNode->lastChild->nextSibling + // ); + $toNode->appendChild($insert); + $eventTarget = $insert; + break; + case 'prependTo': + case 'prepend': + $toNode->insertBefore($insert, $firstChild); + break; + case 'insertBefore': + case 'before': + if (!$toNode->parentNode) + throw new Exception("No parentNode, can't do {$type}()"); + else + $toNode->parentNode->insertBefore($insert, $toNode); + break; + case 'insertAfter': + case 'after': + if (!$toNode->parentNode) + throw new Exception("No parentNode, can't do {$type}()"); + else + $toNode->parentNode->insertBefore($insert, $nextSibling); + break; + } + // Mutation event + $event = new DOMEvent(array( + 'target' => $insert, + 'type' => 'DOMNodeInserted' + )); + PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( + $event + ), $insert); + } + } + return $this; + } + /** + * Enter description here... + * + * @return Int + */ + public function index($subject) { + $index = -1; + $subject = $subject instanceof PhpQueryObject ? $subject->elements[0] + : $subject; + foreach ($this->newInstance() as $k => $node) { + if ($node->isSameNode($subject)) + $index = $k; + } + return $index; + } + /** + * Enter description here... + * + * @param unknown_type $start + * @param unknown_type $end + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @testme + */ + public function slice($start, $end = null) { + // $last = count($this->elements)-1; + // $end = $end + // ? min($end, $last) + // : $last; + // if ($start < 0) + // $start = $last+$start; + // if ($start > $last) + // return array(); + if ($end > 0) + $end = $end - $start; + return $this->newInstance(array_slice($this->elements, $start, $end)); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function reverse() { + $this->elementsBackup = $this->elements; + $this->elements = array_reverse($this->elements); + return $this->newInstance(); + } + /** + * Return joined text content. + * @return String + */ + public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null) { + if (isset($text)) + return $this->html(htmlspecialchars($text)); + $args = func_get_args(); + $args = array_slice($args, 1); + $return = ''; + foreach ($this->elements as $node) { + $text = $node->textContent; + if (count($this->elements) > 1 && $text) + $text .= "\n"; + foreach ($args as $callback) { + $text = phpQuery::callbackRun($callback, array( + $text + )); + } + $return .= $text; + } + return $return; + } + + /** + * @return The text content of each matching element, like + * text() but returns an array with one entry per matched element. + * Read only. + */ + public function texts($attr = null) { + $results = array(); + foreach ($this->elements as $node) { + $results[] = $node->textContent; + } + return $results; + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function plugin($class, $file = null) { + phpQuery::plugin($class, $file); + return $this; + } + /** + * Deprecated, use $pq->plugin() instead. + * + * @deprecated + * @param $class + * @param $file + * @return unknown_type + */ + public static function extend($class, $file = null) { + return $this->plugin($class, $file); + } + /** + * + * @access private + * @param $method + * @param $args + * @return unknown_type + */ + public function __call($method, $args) { + $aliasMethods = array( + 'clone', + 'empty' + ); + if (isset(phpQuery::$extendMethods[$method])) { + array_unshift($args, $this); + return phpQuery::callbackRun(phpQuery::$extendMethods[$method], $args); + } + else if (isset(phpQuery::$pluginsMethods[$method])) { + array_unshift($args, $this); + $class = phpQuery::$pluginsMethods[$method]; + $realClass = "\PhpQuery\Plugin\$class"; + $return = call_user_func_array(array( + $realClass, + $method + ), $args); + // XXX deprecate ? + return is_null($return) ? $this : $return; + } + else if (in_array($method, $aliasMethods)) { + return call_user_func_array(array( + $this, + '_' . $method + ), $args); + } + else + throw new Exception("Method '{$method}' doesnt exist"); + } + /** + * Safe rename of next(). + * + * Use it ONLY when need to call next() on an iterated object (in same time). + * Normaly there is no need to do such thing ;) + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _next($selector = null) { + return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true)); + } + /** + * Use prev() and next(). + * + * @deprecated + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _prev($selector = null) { + return $this->prev($selector); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prev($selector = null) { + return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true)); + } + /** + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo + */ + public function prevAll($selector = null) { + return $this->newInstance($this->getElementSiblings('previousSibling', $selector)); + } + /** + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo FIXME: returns source elements insted of next siblings + */ + public function nextAll($selector = null) { + return $this->newInstance($this->getElementSiblings('nextSibling', $selector)); + } + /** + * @access private + */ + protected function getElementSiblings($direction, $selector = null, $limitToOne = false) { + $stack = array(); + $count = 0; + foreach ($this->stack() as $node) { + $test = $node; + while (isset($test->{$direction}) && $test->{$direction}) { + $test = $test->{$direction}; + if (!$test instanceof \DOMElement) + continue; + $stack[] = $test; + if ($limitToOne) + break; + } + } + if ($selector) { + $stackOld = $this->elements; + $this->elements = $stack; + $stack = $this->filter($selector, true)->stack(); + $this->elements = $stackOld; + } + return $stack; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function siblings($selector = null) { + $stack = array(); + $siblings = array_merge($this->getElementSiblings('previousSibling', $selector), $this->getElementSiblings('nextSibling', $selector)); + foreach ($siblings as $node) { + if (!$this->elementsContainsNode($node, $stack)) + $stack[] = $node; + } + return $this->newInstance($stack); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function not($selector = null) { + if (is_string($selector)) + phpQuery::debug(array( + 'not', + $selector + )); + else + phpQuery::debug('not'); + $stack = array(); + if ($selector instanceof self || $selector instanceof DOMNODE) { + foreach ($this->stack() as $node) { + if ($selector instanceof self) { + $matchFound = false; + foreach ($selector->stack() as $notNode) { + if ($notNode->isSameNode($node)) + $matchFound = true; + } + if (!$matchFound) + $stack[] = $node; + } + else if ($selector instanceof DOMNODE) { + if (!$selector->isSameNode($node)) + $stack[] = $node; + } + else { + if (!$this->is($selector)) + $stack[] = $node; + } + } + } + else { + $orgStack = $this->stack(); + $matched = $this->filter($selector, true)->stack(); + // $matched = array(); + // // simulate OR in filter() instead of AND 5y + // foreach($this->parseSelector($selector) as $s) { + // $matched = array_merge($matched, + // $this->filter(array($s))->stack() + // ); + // } + foreach ($orgStack as $node) + if (!$this->elementsContainsNode($node, $matched)) + $stack[] = $node; + } + return $this->newInstance($stack); + } + /** + * Enter description here... + * + * @param string|PhpQueryObject + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function add($selector = null) { + if (!$selector) + return $this; + $stack = array(); + $this->elementsBackup = $this->elements; + $found = phpQuery::pq($selector, $this->getDocumentID()); + $this->merge($found->elements); + return $this->newInstance(); + } + /** + * @access private + */ + protected function merge() { + foreach (func_get_args() as $nodes) + foreach ($nodes as $newNode) + if (!$this->elementsContainsNode($newNode)) + $this->elements[] = $newNode; + } + /** + * @access private + * TODO refactor to stackContainsNode + */ + protected function elementsContainsNode($nodeToCheck, $elementsStack = null) { + $loop = !is_null($elementsStack) ? $elementsStack : $this->elements; + foreach ($loop as $node) { + if ($node->isSameNode($nodeToCheck)) + return true; + } + return false; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function parent($selector = null) { + $stack = array(); + foreach ($this->elements as $node) + if ($node->parentNode + && !$this->elementsContainsNode($node->parentNode, $stack)) + $stack[] = $node->parentNode; + $this->elementsBackup = $this->elements; + $this->elements = $stack; + if ($selector) + $this->filter($selector, true); + return $this->newInstance(); + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function parents($selector = null) { + $stack = array(); + if (!$this->elements) + $this->debug('parents() - stack empty'); + foreach ($this->elements as $node) { + $test = $node; + while ($test->parentNode) { + $test = $test->parentNode; + if ($this->isRoot($test)) + break; + if (!$this->elementsContainsNode($test, $stack)) { + $stack[] = $test; + continue; + } + } + } + $this->elementsBackup = $this->elements; + $this->elements = $stack; + if ($selector) + $this->filter($selector, true); + return $this->newInstance(); + } + /** + * Internal stack iterator. + * + * @access private + * @return {Array.} + */ + public function stack($nodeTypes = null) { + if (!isset($nodeTypes)) + return $this->elements; + if (!is_array($nodeTypes)) + $nodeTypes = array( + $nodeTypes + ); + $return = array(); + foreach ($this->elements as $node) { + if (in_array($node->nodeType, $nodeTypes)) + $return[] = $node; + } + return $return; + } + // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes + protected function attrEvents($attr, $oldAttr, $oldValue, $node) { + // skip events for XML documents + if (!$this->isXHTML() && !$this->isHTML()) + return; + $event = null; + // identify + $isInputValue = $node->tagName == 'input' + && (in_array($node->getAttribute('type'), array( + 'text', + 'password', + 'hidden' + )) || !$node->getAttribute('type')); + $isRadio = $node->tagName == 'input' + && $node->getAttribute('type') == 'radio'; + $isCheckbox = $node->tagName == 'input' + && $node->getAttribute('type') == 'checkbox'; + $isOption = $node->tagName == 'option'; + if ($isInputValue && $attr == 'value' + && $oldValue != $node->getAttribute($attr)) { + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + } + else if (($isRadio || $isCheckbox) && $attr == 'checked' + && ( + // check + (!$oldAttr && $node->hasAttribute($attr)) + // un-check + || (!$node->hasAttribute($attr) && $oldAttr))) { + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + } + else if ($isOption && $node->parentNode && $attr == 'selected' + && ( + // select + (!$oldAttr && $node->hasAttribute($attr)) + // un-select + || (!$node->hasAttribute($attr) && $oldAttr))) { + $event = new DOMEvent(array( + 'target' => $node->parentNode, + 'type' => 'change' + )); + } + if ($event) { + PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( + $event + ), $node); + } + } + public function attr($attr = null, $value = null) { + foreach ($this->stack(1) as $node) { + if (!is_null($value)) { + $loop = $attr == '*' ? $this->getNodeAttrs($node) + : array( + $attr + ); + foreach ($loop as $a) { + $oldValue = $node->getAttribute($a); + $oldAttr = $node->hasAttribute($a); + // TODO raises an error when charset other than UTF-8 + // while document's charset is also not UTF-8 + @$node->setAttribute($a, $value); + $this->attrEvents($a, $oldAttr, $oldValue, $node); + } + } + else if ($attr == '*') { + // jQuery difference + $return = array(); + foreach ($node->attributes as $n => $v) + $return[$n] = $v->value; + return $return; + } + else + return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null; + } + return is_null($value) ? '' : $this; + } + + /** + * @return The same attribute of each matching element, like + * attr() but returns an array with one entry per matched element. + * Read only. + */ + public function attrs($attr = null) { + $results = array(); + foreach ($this->stack(1) as $node) { + $results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr) + : null; + } + return $results; + } + + /** + * @access private + */ + protected function getNodeAttrs($node) { + $return = array(); + foreach ($node->attributes as $n => $o) + $return[] = $n; + return $return; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo check CDATA ??? + */ + public function attrPHP($attr, $code) { + if (!is_null($code)) { + $value = '<' . '?php ' . $code . ' ?' . '>'; + // TODO tempolary solution + // http://code.google.com/p/phpquery/issues/detail?id=17 + // if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII') + // $value = mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES'); + } + foreach ($this->stack(1) as $node) { + if (!is_null($code)) { + // $attrNode = $this->DOM->createAttribute($attr); + $node->setAttribute($attr, $value); + // $attrNode->value = $value; + // $node->appendChild($attrNode); + } + else if ($attr == '*') { + // jQuery diff + $return = array(); + foreach ($node->attributes as $n => $v) + $return[$n] = $v->value; + return $return; + } + else + return $node->getAttribute($attr); + } + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function removeAttr($attr) { + foreach ($this->stack(1) as $node) { + $loop = $attr == '*' ? $this->getNodeAttrs($node) + : array( + $attr + ); + foreach ($loop as $a) { + $oldValue = $node->getAttribute($a); + $node->removeAttribute($a); + $this->attrEvents($a, $oldValue, null, $node); + } + } + return $this; + } + /** + * Return form element value. + * + * @return String Fields value. + */ + public function val($val = null) { + if (!isset($val)) { + if ($this->eq(0)->is('select')) { + $selected = $this->eq(0)->find('option[selected=selected]'); + if ($selected->is('[value]')) + return $selected->attr('value'); + else + return $selected->text(); + } + else if ($this->eq(0)->is('textarea')) + return $this->eq(0)->markup(); + else + return $this->eq(0)->attr('value'); + } + else { + $_val = null; + foreach ($this->stack(1) as $node) { + $node = pq($node, $this->getDocumentID()); + if (is_array($val) + && in_array($node->attr('type'), array( + 'checkbox', + 'radio' + ))) { + $isChecked = in_array($node->attr('value'), $val) + || in_array($node->attr('name'), $val); + if ($isChecked) + $node->attr('checked', 'checked'); + else + $node->removeAttr('checked'); + } + else if ($node->get(0)->tagName == 'select') { + if (!isset($_val)) { + $_val = array(); + if (!is_array($val)) + $_val = array( + (string) $val + ); + else + foreach ($val as $v) + $_val[] = $v; + } + foreach ($node['option']->stack(1) as $option) { + $option = pq($option, $this->getDocumentID()); + $selected = false; + // XXX: workaround for string comparsion, see issue #96 + // http://code.google.com/p/phpquery/issues/detail?id=96 + $selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val) + : in_array($option->attr('value'), $_val); + // $optionValue = $option->attr('value'); + // $optionText = $option->text(); + // $optionTextLenght = mb_strlen($optionText); + // foreach($_val as $v) + // if ($optionValue == $v) + // $selected = true; + // else if ($optionText == $v && $optionTextLenght == mb_strlen($v)) + // $selected = true; + if ($selected) + $option->attr('selected', 'selected'); + else + $option->removeAttr('selected'); + } + } + else if ($node->get(0)->tagName == 'textarea') + $node->markup($val); + else + $node->attr('value', $val); + } + } + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function andSelf() { + if ($this->previous) + $this->elements = array_merge($this->elements, $this->previous->elements); + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function addClass($className) { + if (!$className) + return $this; + foreach ($this->stack(1) as $node) { + if (!$this->is(".$className", $node)) + $node->setAttribute('class', trim($node->getAttribute('class') . ' ' + . $className)); + } + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function addClassPHP($className) { + foreach ($this->stack(1) as $node) { + $classes = $node->getAttribute('class'); + $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?' + . '>' : '<' . '?php ' . $className . ' ?' . '>'; + $node->setAttribute('class', $newValue); + } + return $this; + } + /** + * Enter description here... + * + * @param string $className + * @return bool + */ + public function hasClass($className) { + foreach ($this->stack(1) as $node) { + if ($this->is(".$className", $node)) + return true; + } + return false; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function removeClass($className) { + foreach ($this->stack(1) as $node) { + $classes = explode(' ', $node->getAttribute('class')); + if (in_array($className, $classes)) { + $classes = array_diff($classes, array( + $className + )); + if ($classes) + $node->setAttribute('class', implode(' ', $classes)); + else + $node->removeAttribute('class'); + } + } + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toggleClass($className) { + foreach ($this->stack(1) as $node) { + if ($this->is($node, '.' . $className)) + $this->removeClass($className); + else + $this->addClass($className); + } + return $this; + } + /** + * Proper name without underscore (just ->empty()) also works. + * + * Removes all child nodes from the set of matched elements. + * + * Example: + * pq("p")._empty() + * + * HTML: + *

    Hello, Person and person

    + * + * Result: + * [

    ] + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _empty() { + foreach ($this->stack(1) as $node) { + // thx to 'dave at dgx dot cz' + $node->nodeValue = ''; + } + return $this; + } + /** + * Enter description here... + * + * @param array|string $callback Expects $node as first param, $index as second + * @param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope) + * @param array $arg1 Will ba passed as third and futher args to callback. + * @param array $arg2 Will ba passed as fourth and futher args to callback, and so on... + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function each($callback, $param1 = null, $param2 = null, $param3 = null) { + $paramStructure = null; + if (func_num_args() > 1) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 1); + } + foreach ($this->elements as $v) + phpQuery::callbackRun($callback, array( + $v + ), $paramStructure); + return $this; + } + /** + * Run callback on actual object. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function callback($callback, $param1 = null, $param2 = null, $param3 = null) { + $params = func_get_args(); + $params[0] = $this; + phpQuery::callbackRun($callback, $params); + return $this; + } + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo add $scope and $args as in each() ??? + */ + public function map($callback, $param1 = null, $param2 = null, $param3 = null) { + // $stack = array(); + //// foreach($this->newInstance() as $node) { + // foreach($this->newInstance() as $node) { + // $result = call_user_func($callback, $node); + // if ($result) + // $stack[] = $result; + // } + $params = func_get_args(); + array_unshift($params, $this->elements); + return $this->newInstance(call_user_func_array(array( + 'phpQuery', + 'map' + ), $params) + // phpQuery::map($this->elements, $callback) + ); + } + /** + * Enter description here... + * + * @param $key + * @param $value + */ + public function data($key, $value = null) { + if (!isset($value)) { + // TODO? implement specific jQuery behavior od returning parent values + // is child which we look up doesn't exist + return phpQuery::data($this->get(0), $key, $value, $this->getDocumentID()); + } + else { + foreach ($this as $node) + phpQuery::data($node, $key, $value, $this->getDocumentID()); + return $this; + } + } + /** + * Enter description here... + * + * @param $key + */ + public function removeData($key) { + foreach ($this as $node) + phpQuery::removeData($node, $key, $this->getDocumentID()); + return $this; + } + // INTERFACE IMPLEMENTATIONS + + // ITERATOR INTERFACE + /** + * @access private + */ + public function rewind() { + $this->debug('iterating foreach'); + // phpQuery::selectDocument($this->getDocumentID()); + $this->elementsBackup = $this->elements; + $this->elementsInterator = $this->elements; + $this->valid = isset($this->elements[0]) ? 1 : 0; + // $this->elements = $this->valid + // ? array($this->elements[0]) + // : array(); + $this->current = 0; + } + /** + * @access private + */ + public function current() { + return $this->elementsInterator[$this->current]; + } + /** + * @access private + */ + public function key() { + return $this->current; + } + /** + * Double-function method. + * + * First: main iterator interface method. + * Second: Returning next sibling, alias for _next(). + * + * Proper functionality is choosed automagicaly. + * + * @see PhpQueryObject::_next() + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function next($cssSelector = null) { + // if ($cssSelector || $this->valid) + // return $this->_next($cssSelector); + $this->valid = isset($this->elementsInterator[$this->current + 1]) ? true + : false; + if (!$this->valid && $this->elementsInterator) { + $this->elementsInterator = null; + } + else if ($this->valid) { + $this->current++; + } + else { + return $this->_next($cssSelector); + } + } + /** + * @access private + */ + public function valid() { + return $this->valid; + } + // ITERATOR INTERFACE END + // ARRAYACCESS INTERFACE + /** + * @access private + */ + public function offsetExists($offset) { + return $this->find($offset)->size() > 0; + } + /** + * @access private + */ + public function offsetGet($offset) { + return $this->find($offset); + } + /** + * @access private + */ + public function offsetSet($offset, $value) { + // $this->find($offset)->replaceWith($value); + $this->find($offset)->html($value); + } + /** + * @access private + */ + public function offsetUnset($offset) { + // empty + throw new Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); + } + // ARRAYACCESS INTERFACE END + /** + * Returns node's XPath. + * + * @param unknown_type $oneNode + * @return string + * @TODO use native getNodePath is avaible + * @access private + */ + protected function getNodeXpath($oneNode = null, $namespace = null) { + $return = array(); + $loop = $oneNode ? array( + $oneNode + ) : $this->elements; + // if ($namespace) + // $namespace .= ':'; + foreach ($loop as $node) { + if ($node instanceof \DOMDocument) { + $return[] = ''; + continue; + } + $xpath = array(); + while (!($node instanceof \DOMDocument)) { + $i = 1; + $sibling = $node; + while ($sibling->previousSibling) { + $sibling = $sibling->previousSibling; + $isElement = $sibling instanceof \DOMElement; + if ($isElement && $sibling->tagName == $node->tagName) + $i++; + } + $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]" + : "{$node->tagName}[{$i}]"; + $node = $node->parentNode; + } + $xpath = join('/', array_reverse($xpath)); + $return[] = '/' . $xpath; + } + return $oneNode ? $return[0] : $return; + } + // HELPERS + public function whois($oneNode = null) { + $return = array(); + $loop = $oneNode ? array( + $oneNode + ) : $this->elements; + foreach ($loop as $node) { + if (isset($node->tagName)) { + $tag = in_array($node->tagName, array( + 'php', + 'js' + )) ? strtoupper($node->tagName) : $node->tagName; + $return[] = $tag + . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '') + . ($node->getAttribute('class') ? '.' + . join('.', explode(' ', $node->getAttribute('class'))) : '') + . ($node->getAttribute('name') ? '[name="' + . $node->getAttribute('name') . '"]' : '') + . ($node->getAttribute('value') + && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="' + . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15) + . '"]' : '') + . ($node->getAttribute('value') + && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]' + : '') . ($node->getAttribute('selected') ? '[selected]' : '') + . ($node->getAttribute('checked') ? '[checked]' : ''); + } + else if ($node instanceof DOMTEXT) { + if (trim($node->textContent)) + $return[] = 'Text:' + . substr(str_replace("\n", ' ', $node->textContent), 0, 15); + } + else { + + } + } + return $oneNode && isset($return[0]) ? $return[0] : $return; + } + /** + * Dump htmlOuter and preserve chain. Usefull for debugging. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * + */ + public function dump() { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump($this->htmlOuter()); + return $this; + } + public function dumpWhois() { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump('whois', $this->whois()); + phpQuery::$debug = $debug; + return $this; + } + public function dumpLength() { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump('length', $this->length()); + phpQuery::$debug = $debug; + return $this; + } + public function dumpTree($html = true, $title = true) { + $output = $title ? 'DUMP #' . (phpQuery::$dumpCount++) . " \n" : ''; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + foreach ($this->stack() as $node) + $output .= $this->__dumpTree($node); + phpQuery::$debug = $debug; + print $html ? nl2br(str_replace(' ', ' ', $output)) : $output; + return $this; + } + private function __dumpTree($node, $intend = 0) { + $whois = $this->whois($node); + $return = ''; + if ($whois) + $return .= str_repeat(' - ', $intend) . $whois . "\n"; + if (isset($node->childNodes)) + foreach ($node->childNodes as $chNode) + $return .= $this->__dumpTree($chNode, $intend + 1); + return $return; + } + /** + * Dump htmlOuter and stop script execution. Usefull for debugging. + * + */ + public function dumpDie() { + print __FILE__ . ':' . __LINE__; + var_dump($this->htmlOuter()); + die(); + } +} diff --git a/phpQuery/phpQuery/plugins/Scripts.php b/src/Plugin/Scripts.php similarity index 75% rename from phpQuery/phpQuery/plugins/Scripts.php rename to src/Plugin/Scripts.php index cc4dd6f..b7b1f8c 100644 --- a/phpQuery/phpQuery/plugins/Scripts.php +++ b/src/Plugin/Scripts.php @@ -3,9 +3,9 @@ * phpQuery plugin class extending phpQuery object. * Methods from this class are callable on every phpQuery object. * - * Class name prefix 'phpQueryObjectPlugin_' must be preserved. + * Class name prefix '\PhpQuery\Plugin\' must be preserved. */ -abstract class phpQueryObjectPlugin_Scripts { +abstract class \PhpQuery\Plugin\Scripts { /** * Limit binded methods. * @@ -19,16 +19,16 @@ abstract class phpQueryObjectPlugin_Scripts { /** * Enter description here... * - * @param phpQueryObject $self + * @param PhpQueryObject $self */ public static function script($self, $arg1) { $params = func_get_args(); $params = array_slice($params, 2); $return = null; $config = self::$config; - if (phpQueryPlugin_Scripts::$scriptMethods[$arg1]) { + if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$arg1]) { phpQuery::callbackRun( - phpQueryPlugin_Scripts::$scriptMethods[$arg1], + \PhpQuery\Plugin\UtilScripts::$scriptMethods[$arg1], array($self, $params, &$return, $config) ); } else if ($arg1 != '__config' && file_exists(dirname(__FILE__)."/Scripts/$arg1.php")) { @@ -42,12 +42,12 @@ public static function script($self, $arg1) { : $self; } } -abstract class phpQueryPlugin_Scripts { +abstract class \PhpQuery\Plugin\UtilScripts { public static $scriptMethods = array(); public static function __initialize() { if (file_exists(dirname(__FILE__)."/Scripts/__config.php")) { include dirname(__FILE__)."/Scripts/__config.php"; - phpQueryObjectPlugin_Scripts::$config = $config; + \PhpQuery\Plugin\Scripts::$config = $config; } } /** @@ -64,9 +64,9 @@ public static function __initialize() { * @return bool */ public static function script($name, $callback) { - if (phpQueryPlugin_Scripts::$scriptMethods[$name]) + if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name]) throw new Exception("Script name conflict - '$name'"); - phpQueryPlugin_Scripts::$scriptMethods[$name] = $callback; + \PhpQuery\Plugin\UtilScripts::$scriptMethods[$name] = $callback; } } ?> \ No newline at end of file diff --git a/phpQuery/phpQuery/plugins/Scripts/__config.example.php b/src/Plugin/Scripts/__config.example.php similarity index 100% rename from phpQuery/phpQuery/plugins/Scripts/__config.example.php rename to src/Plugin/Scripts/__config.example.php diff --git a/phpQuery/phpQuery/plugins/Scripts/example.php b/src/Plugin/Scripts/example.php similarity index 100% rename from phpQuery/phpQuery/plugins/Scripts/example.php rename to src/Plugin/Scripts/example.php diff --git a/phpQuery/phpQuery/plugins/Scripts/fix_webroot.php b/src/Plugin/Scripts/fix_webroot.php similarity index 100% rename from phpQuery/phpQuery/plugins/Scripts/fix_webroot.php rename to src/Plugin/Scripts/fix_webroot.php diff --git a/phpQuery/phpQuery/plugins/Scripts/google_login.php b/src/Plugin/Scripts/google_login.php similarity index 100% rename from phpQuery/phpQuery/plugins/Scripts/google_login.php rename to src/Plugin/Scripts/google_login.php diff --git a/phpQuery/phpQuery/plugins/Scripts/print_source.php b/src/Plugin/Scripts/print_source.php similarity index 87% rename from phpQuery/phpQuery/plugins/Scripts/print_source.php rename to src/Plugin/Scripts/print_source.php index 03d8061..6c30d12 100644 --- a/phpQuery/phpQuery/plugins/Scripts/print_source.php +++ b/src/Plugin/Scripts/print_source.php @@ -4,6 +4,6 @@ * * @author Tobiasz Cudnik */ -/** @var phpQueryObject */ +/** @var PhpQueryObject */ $self = $self; $return = htmlspecialchars($self); \ No newline at end of file diff --git a/phpQuery/phpQuery/plugins/Scripts/print_websafe.php b/src/Plugin/Scripts/print_websafe.php similarity index 91% rename from phpQuery/phpQuery/plugins/Scripts/print_websafe.php rename to src/Plugin/Scripts/print_websafe.php index 4f48bd7..d9c00d1 100644 --- a/phpQuery/phpQuery/plugins/Scripts/print_websafe.php +++ b/src/Plugin/Scripts/print_websafe.php @@ -4,7 +4,7 @@ * * @author Tobiasz Cudnik */ -/** @var phpQueryObject */ +/** @var PhpQueryObject */ $self = $self; $self ->find('script') diff --git a/phpQuery/phpQuery/plugins/WebBrowser.php b/src/Plugin/WebBrowser.php similarity index 95% rename from phpQuery/phpQuery/plugins/WebBrowser.php rename to src/Plugin/WebBrowser.php index e5e83d0..75568e5 100644 --- a/phpQuery/phpQuery/plugins/WebBrowser.php +++ b/src/Plugin/WebBrowser.php @@ -3,7 +3,7 @@ * WebBrowser plugin. * */ -class phpQueryObjectPlugin_WebBrowser { +class \PhpQuery\Plugin\WebBrowser { /** * Limit binded methods to specified ones. * @@ -13,7 +13,7 @@ class phpQueryObjectPlugin_WebBrowser { /** * Enter description here... * - * @param phpQueryObject $self + * @param PhpQueryObject $self * @todo support 'reset' event */ public static function WebBrowser($self, $callback = null, $location = null) { @@ -27,8 +27,8 @@ public static function WebBrowser($self, $callback = null, $location = null) { if (! $location) throw new Exception('Location needed to activate WebBrowser plugin !'); else { - $self->bind('click', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'hadleClick')); - $self->bind('submit', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'handleSubmit')); + $self->bind('click', array($location, $callback), array('\PhpQuery\Plugin\UtilWebBrowser', 'hadleClick')); + $self->bind('submit', array($location, $callback), array('\PhpQuery\Plugin\UtilWebBrowser', 'handleSubmit')); } } public static function browser($self, $callback = null, $location = null) { @@ -75,7 +75,7 @@ public static function location($self, $url = null) { ), $xhr); $return = false; if ($xhr->getLastResponse()->isSuccessful()) { - $return = phpQueryPlugin_WebBrowser::browserReceive($xhr); + $return = \PhpQuery\Plugin\UtilWebBrowser::browserReceive($xhr); if (isset($self->document->WebBrowserCallback)) phpQuery::callbackRun( $self->document->WebBrowserCallback, @@ -95,7 +95,7 @@ public static function download($self, $url = null) { ), $xhr); $return = false; if ($xhr->getLastResponse()->isSuccessful()) { - $return = phpQueryPlugin_WebBrowser::browserDownload($xhr); + $return = \PhpQuery\Plugin\UtilWebBrowser::browserDownload($xhr); if (isset($self->document->WebBrowserCallback)) phpQuery::callbackRun( $self->document->WebBrowserCallback, @@ -105,7 +105,7 @@ public static function download($self, $url = null) { return $return; } } -class phpQueryPlugin_WebBrowser { +class \PhpQuery\Plugin\UtilWebBrowser { /** * * @param $url @@ -260,7 +260,7 @@ public static function browserReceive($xhr) { if ($xhr->getLastResponse()->isSuccessful()) { // if all is ok, repeat this method... return call_user_func_array( - array('phpQueryPlugin_WebBrowser', 'browserReceive'), array($xhr) + array('\PhpQuery\Plugin\UtilWebBrowser', 'browserReceive'), array($xhr) ); } } else diff --git a/jQueryServer/demo/demo.htm b/src/Proxy/demo/demo.htm similarity index 100% rename from jQueryServer/demo/demo.htm rename to src/Proxy/demo/demo.htm diff --git a/jQueryServer/demo/jquery.js b/src/Proxy/demo/jquery.js similarity index 100% rename from jQueryServer/demo/jquery.js rename to src/Proxy/demo/jquery.js diff --git a/jQueryServer/jQueryServer.config.php.example b/src/Proxy/jQueryServer.config.php.example similarity index 100% rename from jQueryServer/jQueryServer.config.php.example rename to src/Proxy/jQueryServer.config.php.example diff --git a/jQueryServer/jQueryServer.js b/src/Proxy/jQueryServer.js similarity index 100% rename from jQueryServer/jQueryServer.js rename to src/Proxy/jQueryServer.js diff --git a/src/Proxy/jQueryServer.php b/src/Proxy/jQueryServer.php new file mode 100755 index 0000000..1b4cb1b --- /dev/null +++ b/src/Proxy/jQueryServer.php @@ -0,0 +1,116 @@ +` + + * @link http://code.google.com/p/phpquery/wiki/jQueryServer + * @link http://code.google.com/p/phpquery/ + * @todo local files support (safe...) + * @todo respond with proper HTTP code + * @todo persistant thread support (with timeout...) + * @todo 2.0: JSON RPC - Zend_Json_Server + * @todo 2.0: XML RPC ? + */ +class jQueryServer { + public $config = array( + 'allowedRefererHosts' => array( + '.' + ), + 'refererMustMatch' => true, + ); + public $calls = null; + public $options = null; + public $allowedHosts = null; + function __construct($data) { + $pq = null; + include_once(dirname(__FILE__) . '/../phpQuery/phpQuery.php'); + if (file_exists(dirname(__FILE__) . '/jQueryServer.config.php')) { + include_once(dirname(__FILE__) . '/jQueryServer.config.php'); + if ($jQueryServerConfig) + $this->config = array_merge_recursive($this->config, $jQueryServerConfig); + } + if ($this->config['refererMustMatch']) { + foreach ($this->config['allowedRefererHosts'] as $i => $host) + if ($host == '.') + $this->config['allowedRefererHosts'][$i] = $_SERVER['HTTP_HOST']; + $referer = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST); + $authorized = $referer + && in_array($referer, $this->config['allowedRefererHosts']); + if (!$authorized) { + throw new Exception("Host '{$_SERVER['HTTP_REFERER']}' not authorized to make requests."); + return; + } + } + // phpQueryClass::$debug = true; + // if (! function_exists('json_decode')) { + // include_once(dirname(__FILE__).'/JSON.php'); + // $this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); + // } + // $data = $this->jsonDecode($data); + $data = phpQuery::parseJSON($data); + // load document (required for first $data element) + if (is_array($data[0]) && isset($data[0]['url'])) { + $this->options = $data[0]; + $ajax = $this->options; + $this->calls = array_slice($data, 1); + $ajax['success'] = array( + $this, + 'success' + ); + phpQuery::ajax($ajax); + } + else { + throw new Exception("URL needed to download content"); + } + } + public function success($response) { + $pq = phpQuery::newDocument($response); + foreach ($this->calls as $k => $r) { + // check if method exists + if (!method_exists(get_class($pq), $r['method'])) { + throw new Exception("Method '{$r['method']}' not implemented in phpQuery, sorry..."); + // execute method + } + else { + $pq = call_user_func_array(array( + $pq, + $r['method'] + ), $r['arguments']); + } + } + if (!isset($this->options['dataType'])) + $this->options['dataType'] = ''; + switch (strtolower($this->options['dataType'])) { + case 'json': + if ($pq instanceof PHPQUERYOBJECT) { + $results = array(); + foreach ($pq as $node) + $results[] = pq($node)->htmlOuter(); + print phpQuery::toJSON($results); + } + else { + print phpQuery::toJSON($pq); + } + break; + default: + print $pq; + } + // output results + } + // public function jsonEncode($data) { + // return function_exists('json_encode') + // ? json_encode($data) + // : $this->json->encode($data); + // } + // public function jsonDecode($data) { + // return function_exists('json_decode') + // ? json_decode($data, true) + // : $this->json->decode($data); + // } +} +new jQueryServer($_POST['data']); +?> \ No newline at end of file diff --git a/phpQuery/phpQuery/default.css b/src/Resources/default.css similarity index 100% rename from phpQuery/phpQuery/default.css rename to src/Resources/default.css diff --git a/src/Tests/BasicTest.php b/src/Tests/BasicTest.php new file mode 100644 index 0000000..27e3f8a --- /dev/null +++ b/src/Tests/BasicTest.php @@ -0,0 +1,205 @@ +find('p')->filter('.body:gt(1)'); + $result = array( + 'p.body', + ); + + $this->assertTrue($pq->whois() == $result); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testSlice($pq) { + $testResult = array( + 'li#testID', + ); + $pq = $pq->find('li')->slice(1, 2); + + $this->assertTrue($pq->whois() == $testResult); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testSlice2($pq) { + // SLICE2 + $testResult = array( + 'li#testID', + 'li', + 'li#i_have_nested_list', + 'li.nested', + ); + + $pq = $pq->find('li')->slice(1, -1); + + $this->assertTrue($pq->whois() == $testResult); + } + + /** + * @return void + */ + function testMultiInsert() { + // Multi-insert + $pq = phpQuery::newDocument('
  • ')->find('.field1')->php('longlongtest'); + $validResult = '
  • longlongtestlonglongtest
  • '; + similar_text($pq->htmlOuter(), $validResult, $similarity); + + $this->assertGreaterThan(80, $similarity); + + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testIndex($pq) { + $testResult = 1; + $pq = $pq->find('p')->index($pq->find('p.title:first')); + + $this->assertTrue($pq == $testResult); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testClone($pq) { + $testResult = 3; + $document = null; + $pq = $pq->toReference($document)->find('p:first'); + + foreach (array( + 0, + 1, + 2 + ) as $i) { + $pq->clone()->addClass("clone-test")->addClass("class-$i")->insertBefore($pq); + } + + $size = $document->find('.clone-test')->size(); + $this->assertEquals($testResult, $size); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testNextSibling($pq) { + $testResult = 3; + $document = null; + $result = $pq->find('li:first')->next()->next()->prev()->is('#testID'); + + $this->assertTrue($result); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + function testSimpleDataInsertion($pq) { + $testName = 'Simple data insertion'; + $testResult = << + div.articles text node +
      + +
    • +

      This is paragraph of first LI

      +

      News 1 title

      +

      News 1 body

      +
    • + +
    • +

      This is paragraph of first LI

      +

      News 2 title

      +

      News 2 body

      +
    • +
    • +

      This is paragraph of first LI

      +

      News 3

      +

      News 3 body

      +
    • +
    +

    paragraph after UL

    +
    +EOF; + $expected_pq = phpQuery::newDocumentHTML($testResult); + $rows = array( + array( + 'title' => 'News 1 title', + 'body' => 'News 1 body', + ), + array( + 'title' => 'News 2 title', + 'body' => 'News 2 body', + ), + array( + 'title' => 'News 3', + 'body' => 'News 3 body', + ), + ); + $articles = $pq->find('.articles ul'); + $rowSrc = $articles->find('li')->remove()->eq(0); + foreach ($rows as $r) { + $row = $rowSrc->_clone(); + foreach ($r as $field => $value) { + $row->find(".{$field}")->html($value); + // die($row->htmlOuter()); + } + $row->appendTo($articles); + } + $result = $pq->find('.articles')->htmlOuter(); + // print htmlspecialchars("
    {$result}
    ").'
    '; + + $this->assertEqualXMLStructure($expected_pq->find('.articles')->elements[0], $pq->find('.articles')->elements[0]); + // $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); + } + + /** + * @param phpQueryObject $pq + * @dataProvider provider + * @return void + */ + public function testCssParser() { + phpQuery::$enableCssShorthand = FALSE; + + $expected_html = '
    Hello World!
    '; + $expected_pq = phpQuery::newDocumentHTML($expected_html); + + $test_pq = phpQuery::newDocumentHTML('
    '); + $test = pq('div'); + $test->append('Hello World!'); + $test->hide(); + $test->css('color', 'red'); + $test->css('margin', '20px'); + $this->assertEqualXMLStructure($expected_pq->find('div')->elements[0], $test->elements[0]); + } +} diff --git a/test-cases/document-types/document-fragment-utf8.html b/src/Tests/_archive/document-types/document-fragment-utf8.html similarity index 100% rename from test-cases/document-types/document-fragment-utf8.html rename to src/Tests/_archive/document-types/document-fragment-utf8.html diff --git a/test-cases/document-types/document-fragment-utf8.xhtml b/src/Tests/_archive/document-types/document-fragment-utf8.xhtml similarity index 100% rename from test-cases/document-types/document-fragment-utf8.xhtml rename to src/Tests/_archive/document-types/document-fragment-utf8.xhtml diff --git a/test-cases/document-types/document-fragment-utf8.xml b/src/Tests/_archive/document-types/document-fragment-utf8.xml similarity index 100% rename from test-cases/document-types/document-fragment-utf8.xml rename to src/Tests/_archive/document-types/document-fragment-utf8.xml diff --git a/test-cases/document-types/document-iso88592-nocharset.html b/src/Tests/_archive/document-types/document-iso88592-nocharset.html similarity index 100% rename from test-cases/document-types/document-iso88592-nocharset.html rename to src/Tests/_archive/document-types/document-iso88592-nocharset.html diff --git a/test-cases/document-types/document-iso88592-nocharset.xhtml b/src/Tests/_archive/document-types/document-iso88592-nocharset.xhtml similarity index 100% rename from test-cases/document-types/document-iso88592-nocharset.xhtml rename to src/Tests/_archive/document-types/document-iso88592-nocharset.xhtml diff --git a/test-cases/document-types/document-iso88592-nocharset.xml b/src/Tests/_archive/document-types/document-iso88592-nocharset.xml similarity index 100% rename from test-cases/document-types/document-iso88592-nocharset.xml rename to src/Tests/_archive/document-types/document-iso88592-nocharset.xml diff --git a/test-cases/document-types/document-iso88592.html b/src/Tests/_archive/document-types/document-iso88592.html similarity index 100% rename from test-cases/document-types/document-iso88592.html rename to src/Tests/_archive/document-types/document-iso88592.html diff --git a/test-cases/document-types/document-iso88592.xhtml b/src/Tests/_archive/document-types/document-iso88592.xhtml similarity index 100% rename from test-cases/document-types/document-iso88592.xhtml rename to src/Tests/_archive/document-types/document-iso88592.xhtml diff --git a/test-cases/document-types/document-iso88592.xml b/src/Tests/_archive/document-types/document-iso88592.xml similarity index 100% rename from test-cases/document-types/document-iso88592.xml rename to src/Tests/_archive/document-types/document-iso88592.xml diff --git a/test-cases/document-types/document-utf8-nocharset.html b/src/Tests/_archive/document-types/document-utf8-nocharset.html similarity index 100% rename from test-cases/document-types/document-utf8-nocharset.html rename to src/Tests/_archive/document-types/document-utf8-nocharset.html diff --git a/test-cases/document-types/document-utf8-nocharset.xhtml b/src/Tests/_archive/document-types/document-utf8-nocharset.xhtml similarity index 100% rename from test-cases/document-types/document-utf8-nocharset.xhtml rename to src/Tests/_archive/document-types/document-utf8-nocharset.xhtml diff --git a/test-cases/document-types/document-utf8-nocharset.xml b/src/Tests/_archive/document-types/document-utf8-nocharset.xml similarity index 100% rename from test-cases/document-types/document-utf8-nocharset.xml rename to src/Tests/_archive/document-types/document-utf8-nocharset.xml diff --git a/test-cases/document-types/document-utf8.html b/src/Tests/_archive/document-types/document-utf8.html similarity index 100% rename from test-cases/document-types/document-utf8.html rename to src/Tests/_archive/document-types/document-utf8.html diff --git a/test-cases/document-types/document-utf8.php b/src/Tests/_archive/document-types/document-utf8.php similarity index 100% rename from test-cases/document-types/document-utf8.php rename to src/Tests/_archive/document-types/document-utf8.php diff --git a/test-cases/document-types/document-utf8.xhtml b/src/Tests/_archive/document-types/document-utf8.xhtml similarity index 100% rename from test-cases/document-types/document-utf8.xhtml rename to src/Tests/_archive/document-types/document-utf8.xhtml diff --git a/test-cases/document-types/document-utf8.xml b/src/Tests/_archive/document-types/document-utf8.xml similarity index 100% rename from test-cases/document-types/document-utf8.xml rename to src/Tests/_archive/document-types/document-utf8.xml diff --git a/test-cases/document_types.php b/src/Tests/_archive/document_types.php similarity index 100% rename from test-cases/document_types.php rename to src/Tests/_archive/document_types.php diff --git a/test-cases/run.php b/src/Tests/_archive/run.php similarity index 100% rename from test-cases/run.php rename to src/Tests/_archive/run.php diff --git a/test-cases/test.html b/src/Tests/_archive/test.html similarity index 100% rename from test-cases/test.html rename to src/Tests/_archive/test.html diff --git a/test-cases/test_2.php b/src/Tests/_archive/test_2.php similarity index 100% rename from test-cases/test_2.php rename to src/Tests/_archive/test_2.php diff --git a/test-cases/test_4.php b/src/Tests/_archive/test_4.php similarity index 100% rename from test-cases/test_4.php rename to src/Tests/_archive/test_4.php diff --git a/test-cases/test_5.php b/src/Tests/_archive/test_5.php similarity index 100% rename from test-cases/test_5.php rename to src/Tests/_archive/test_5.php diff --git a/test-cases/test_ajax.php b/src/Tests/_archive/test_ajax.php similarity index 100% rename from test-cases/test_ajax.php rename to src/Tests/_archive/test_ajax.php diff --git a/test-cases/test_ajax_data_1 b/src/Tests/_archive/test_ajax_data_1 similarity index 100% rename from test-cases/test_ajax_data_1 rename to src/Tests/_archive/test_ajax_data_1 diff --git a/test-cases/test_arrayaccess.php b/src/Tests/_archive/test_arrayaccess.php similarity index 100% rename from test-cases/test_arrayaccess.php rename to src/Tests/_archive/test_arrayaccess.php diff --git a/test-cases/test_attr.php b/src/Tests/_archive/test_attr.php similarity index 100% rename from test-cases/test_attr.php rename to src/Tests/_archive/test_attr.php diff --git a/test-cases/test_callback.php b/src/Tests/_archive/test_callback.php similarity index 93% rename from test-cases/test_callback.php rename to src/Tests/_archive/test_callback.php index a854ab5..0dace99 100644 --- a/test-cases/test_callback.php +++ b/src/Tests/_archive/test_callback.php @@ -17,7 +17,7 @@ public function testExtend() { 'newMethod1' => array($this, 'callback1'), 'newMethod2' => array($this, 'callback2'), ); - phpQuery::extend('phpQueryObject', $newMethods); + phpQuery::extend('PhpQueryObject', $newMethods); $doc = phpQuery::newDocumentXML("
    "); $this->assertTrue($doc->newMethod1() == $doc, '$doc->newMethod1 == $doc'); diff --git a/test-cases/test_charset.php b/src/Tests/_archive/test_charset.php similarity index 100% rename from test-cases/test_charset.php rename to src/Tests/_archive/test_charset.php diff --git a/test-cases/test_document.php b/src/Tests/_archive/test_document.php similarity index 100% rename from test-cases/test_document.php rename to src/Tests/_archive/test_document.php diff --git a/test-cases/test_events.php b/src/Tests/_archive/test_events.php similarity index 100% rename from test-cases/test_events.php rename to src/Tests/_archive/test_events.php diff --git a/test-cases/test_insert.php b/src/Tests/_archive/test_insert.php similarity index 100% rename from test-cases/test_insert.php rename to src/Tests/_archive/test_insert.php diff --git a/test-cases/test_manipulation.php b/src/Tests/_archive/test_manipulation.php similarity index 100% rename from test-cases/test_manipulation.php rename to src/Tests/_archive/test_manipulation.php diff --git a/test-cases/test_manual.php b/src/Tests/_archive/test_manual.php similarity index 100% rename from test-cases/test_manual.php rename to src/Tests/_archive/test_manual.php diff --git a/test-cases/test_multidoc.php b/src/Tests/_archive/test_multidoc.php similarity index 100% rename from test-cases/test_multidoc.php rename to src/Tests/_archive/test_multidoc.php diff --git a/test-cases/test_php.php b/src/Tests/_archive/test_php.php similarity index 100% rename from test-cases/test_php.php rename to src/Tests/_archive/test_php.php diff --git a/test-cases/test_replace.php b/src/Tests/_archive/test_replace.php similarity index 100% rename from test-cases/test_replace.php rename to src/Tests/_archive/test_replace.php diff --git a/test-cases/test_scripts.php b/src/Tests/_archive/test_scripts.php similarity index 100% rename from test-cases/test_scripts.php rename to src/Tests/_archive/test_scripts.php diff --git a/test-cases/test_selectors.php b/src/Tests/_archive/test_selectors.php similarity index 100% rename from test-cases/test_selectors.php rename to src/Tests/_archive/test_selectors.php diff --git a/test-cases/test_webbrowser.php b/src/Tests/_archive/test_webbrowser.php similarity index 96% rename from test-cases/test_webbrowser.php rename to src/Tests/_archive/test_webbrowser.php index b41981c..e15054e 100755 --- a/test-cases/test_webbrowser.php +++ b/src/Tests/_archive/test_webbrowser.php @@ -14,7 +14,7 @@ phpQuery::$plugins->browserGet('http://google.com/', 'success1'); /** * - * @param $pq phpQueryObject + * @param $pq PhpQueryObject * @return unknown_type */ function success1($pq) { @@ -29,7 +29,7 @@ function success1($pq) { } /** * - * @param $html phpQueryObject + * @param $html PhpQueryObject * @return unknown_type */ function success2($pq) { diff --git a/test-cases/test_wrap.php b/src/Tests/_archive/test_wrap.php similarity index 100% rename from test-cases/test_wrap.php rename to src/Tests/_archive/test_wrap.php diff --git a/test-cases/xpath.php b/src/Tests/_archive/xpath.php similarity index 100% rename from test-cases/xpath.php rename to src/Tests/_archive/xpath.php diff --git a/unit-tests/test.html b/src/Tests/test.html similarity index 100% rename from unit-tests/test.html rename to src/Tests/test.html diff --git a/src/bootstrap.php b/src/bootstrap.php new file mode 100644 index 0000000..4142464 --- /dev/null +++ b/src/bootstrap.php @@ -0,0 +1,97 @@ + + * @package phpQuery + */ +function pq($arg1, $context = null) { + $args = func_get_args(); + return call_user_func_array( + array('\\PhpQuery\\PhpQuery', 'pq'), + $args + ); +} + + +// -- Multibyte Compatibility functions --------------------------------------- +// http://svn.iphonewebdev.com/lace/lib/mb_compat.php + +/** + * mb_internal_encoding() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($enc) { + return true; + } +} + +/** + * mb_regex_encoding() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_regex_encoding')) { + function mb_regex_encoding($enc) { + return true; + } +} + +/** + * mb_strlen() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_strlen')) { + function mb_strlen($str) { + return strlen($str); + } +} + +/** + * mb_strpos() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0) { + return strpos($haystack, $needle, $offset); + } +} +/** + * mb_stripos() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0) { + return stripos($haystack, $needle, $offset); + } +} + +/** + * mb_substr() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_substr')) { + function mb_substr($str, $start, $length = 0) { + return substr($str, $start, $length); + } +} + +/** + * mb_substr_count() + * + * Included for mbstring pseudo-compatability. + */ +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle) { + return substr_count($haystack, $needle); + } +} diff --git a/unit-tests/test.php b/unit-tests/test.php deleted file mode 100644 index 03b914c..0000000 --- a/unit-tests/test.php +++ /dev/null @@ -1,231 +0,0 @@ -find('p') - ->filter('.body:gt(1)'); - $result = array( - 'p.body', - ); - - $this->assertTrue( $pq->whois() == $result ); - } - - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testSlice( $pq ) { - $testResult = array( - 'li#testID', - ); - $pq = $pq->find('li') - ->slice(1, 2); - - $this->assertTrue( $pq->whois() == $testResult ); - } - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testSlice2( $pq ) { - // SLICE2 - $testResult = array( - 'li#testID', - 'li', - 'li#i_have_nested_list', - 'li.nested', - ); - - $pq = $pq->find('li') - ->slice(1, -1); - - $this->assertTrue( $pq->whois() == $testResult ); - } - - - /** - * @return void - */ - function testMultiInsert() { - // Multi-insert - $pq = phpQuery::newDocument('
  • ') - ->find('.field1') - ->php('longlongtest'); - $validResult = '
  • longlongtestlonglongtest
  • '; - similar_text($pq->htmlOuter(), $validResult, $similarity); - - $this->assertGreaterThan( 80, $similarity); - - } - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testIndex( $pq ) { - $testResult = 1; - $pq = $pq->find('p') - ->index( - $pq->find('p.title:first') - ); - - $this->assertTrue( $pq == $testResult ); - } - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testClone( $pq ) { - $testResult = 3; - $document = null; - $pq = $pq->toReference($document) - ->find('p:first'); - - foreach(array(0,1,2) as $i) { - $pq->clone() - ->addClass("clone-test") - ->addClass("class-$i") - ->insertBefore($pq); - } - - $size = $document->find('.clone-test')->size(); - $this->assertEquals( $testResult, $size); - } - - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testNextSibling( $pq ) { - $testResult = 3; - $document = null; - $result = $pq->find('li:first') - ->next() - ->next() - ->prev() - ->is('#testID'); - - $this->assertTrue( $result ); - } - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - function testSimpleDataInsertion( $pq ) { - $testName = 'Simple data insertion'; - $testResult = << - div.articles text node -
      - -
    • -

      This is paragraph of first LI

      -

      News 1 title

      -

      News 1 body

      -
    • - -
    • -

      This is paragraph of first LI

      -

      News 2 title

      -

      News 2 body

      -
    • -
    • -

      This is paragraph of first LI

      -

      News 3

      -

      News 3 body

      -
    • -
    -

    paragraph after UL

    -
    -EOF; - $expected_pq = phpQuery::newDocumentHTML($testResult); - $rows = array( - array( - 'title' => 'News 1 title', - 'body' => 'News 1 body', - ), - array( - 'title' => 'News 2 title', - 'body' => 'News 2 body', - ), - array( - 'title' => 'News 3', - 'body' => 'News 3 body', - ), - ); - $articles = $pq->find('.articles ul'); - $rowSrc = $articles->find('li') - ->remove() - ->eq(0); - foreach ($rows as $r) { - $row = $rowSrc->_clone(); - foreach ($r as $field => $value) { - $row->find(".{$field}") - ->html($value); - // die($row->htmlOuter()); - } - $row->appendTo($articles); - } - $result = $pq->find('.articles')->htmlOuter(); -// print htmlspecialchars("
    {$result}
    ").'
    '; - - $this->assertEqualXMLStructure($expected_pq->find('.articles')->elements[0], $pq->find('.articles')->elements[0]); -// $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement); - } - - /** - * @param phpQueryObject $pq - * @dataProvider provider - * @return void - */ - public function testCssParser() { - phpQuery::$enableCssShorthand = FALSE; - - $expected_html = '
    Hello World!
    '; - $expected_pq = phpQuery::newDocumentHTML($expected_html); - - $test_pq = phpQuery::newDocumentHTML('
    '); - $test = pq('div'); - $test->append('Hello World!'); - $test->hide(); - $test->css('color', 'red'); - $test->css('margin', '20px'); - $this->assertEqualXMLStructure($expected_pq->find('div')->elements[0], $test->elements[0]); - } -} - -$test = new phpQueryBasicTest(); -//$test->testFilterWithPseudoclass(); -$result = null; -//$test->run($result); \ No newline at end of file From 951c3100c7886ae5416660af8dffaa1ae77e2f5f Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sat, 8 Mar 2014 22:02:56 -0600 Subject: [PATCH 35/59] Closes #8. Remove pq() from the global namespace. --- src/PhpQuery.php | 29 +++++++++++++++++++++++++++++ src/Tests/BasicTest.php | 1 + src/bootstrap.php | 18 ------------------ 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/PhpQuery.php b/src/PhpQuery.php index 85f04bf..f830e77 100644 --- a/src/PhpQuery.php +++ b/src/PhpQuery.php @@ -16,6 +16,19 @@ use PhpQuery\Dom\DomDocumentWrapper as DOMDocumentWrapper; require_once __DIR__ . '/bootstrap.php'; +/** + * Shortcut to phpQuery::pq($arg1, $context) + * Chainable. + * + * @see phpQuery::pq() + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @author Tobiasz Cudnik + * @package phpQuery + */ +function pq($arg1, $context = NULL) { + return PhpQuery::pq($arg1, $context); +} + /** * Static namespace for phpQuery functions. * @@ -103,6 +116,22 @@ abstract class phpQuery { public static $dumpCount = 0; public static $enableCssShorthand = FALSE; + public static function use_function($ns = '\\', $func = 'pq') { + if ($ns{0} !== '\\') { + $ns = '\\' . $ns; + } + if (!function_exists($ns . '\\' . $func)) { + if ($ns === '\\') { + eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }"); + } + else { + $ns = substr($ns, 1); + eval("namespace $ns { function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); } }"); + } + } + } + + /** * Multi-purpose function. * Use pq() as shortcut. diff --git a/src/Tests/BasicTest.php b/src/Tests/BasicTest.php index 27e3f8a..82f931b 100644 --- a/src/Tests/BasicTest.php +++ b/src/Tests/BasicTest.php @@ -1,6 +1,7 @@ - * @package phpQuery - */ -function pq($arg1, $context = null) { - $args = func_get_args(); - return call_user_func_array( - array('\\PhpQuery\\PhpQuery', 'pq'), - $args - ); -} - - // -- Multibyte Compatibility functions --------------------------------------- // http://svn.iphonewebdev.com/lace/lib/mb_compat.php From 2dd92cce47631fc0e249cf583ba55b2d26ef76a4 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 15:22:54 -0500 Subject: [PATCH 36/59] Converted googlecode wiki pages to markedown files. --- docs/Ajax.md | 129 +++++++++++++++++++++++++ docs/Attributes.md | 78 +++++++++++++++ docs/Basics.md | 77 +++++++++++++++ docs/CSS.md | 1 + docs/Callbacks.md | 145 ++++++++++++++++++++++++++++ docs/Chains.md | 1 + docs/CommandLineInterface.md | 21 +++++ docs/Debugging.md | 23 +++++ docs/Dependencies.md | 30 ++++++ docs/Events.md | 87 +++++++++++++++++ docs/LibrarySections.md | 2 + docs/Manipulation.md | 104 ++++++++++++++++++++ docs/Manual.md | 37 ++++++++ docs/MultiDocumentSupport.md | 78 +++++++++++++++ docs/PHPSupport.md | 157 ++++++++++++++++++++++++++++++ docs/PluginsClientSidePorts.md | 15 +++ docs/PluginsServerSide.md | 93 ++++++++++++++++++ docs/ReleasePackages.md | 19 ++++ docs/SVNCheckout.md | 21 +++++ docs/ScriptsPlugin.md | 42 +++++++++ docs/Selectors.md | 168 +++++++++++++++++++++++++++++++++ docs/Traversing.md | 88 +++++++++++++++++ docs/Utilities.md | 43 +++++++++ docs/WebBrowser.md | 55 +++++++++++ docs/jQueryDifferences.md | 2 + docs/jQueryHelpers.md | 5 + docs/jQueryPortingState.md | 42 +++++++++ docs/jQueryServer.md | 29 ++++++ docs/jQueryServerSidePorts.md | 10 ++ 29 files changed, 1602 insertions(+) create mode 100644 docs/Ajax.md create mode 100644 docs/Attributes.md create mode 100644 docs/Basics.md create mode 100644 docs/CSS.md create mode 100644 docs/Callbacks.md create mode 100644 docs/Chains.md create mode 100644 docs/CommandLineInterface.md create mode 100644 docs/Debugging.md create mode 100644 docs/Dependencies.md create mode 100644 docs/Events.md create mode 100644 docs/LibrarySections.md create mode 100644 docs/Manipulation.md create mode 100644 docs/Manual.md create mode 100644 docs/MultiDocumentSupport.md create mode 100644 docs/PHPSupport.md create mode 100644 docs/PluginsClientSidePorts.md create mode 100644 docs/PluginsServerSide.md create mode 100644 docs/ReleasePackages.md create mode 100644 docs/SVNCheckout.md create mode 100644 docs/ScriptsPlugin.md create mode 100644 docs/Selectors.md create mode 100644 docs/Traversing.md create mode 100644 docs/Utilities.md create mode 100644 docs/WebBrowser.md create mode 100644 docs/jQueryDifferences.md create mode 100644 docs/jQueryHelpers.md create mode 100644 docs/jQueryPortingState.md create mode 100644 docs/jQueryServer.md create mode 100644 docs/jQueryServerSidePorts.md diff --git a/docs/Ajax.md b/docs/Ajax.md new file mode 100644 index 0000000..178d62b --- /dev/null +++ b/docs/Ajax.md @@ -0,0 +1,129 @@ +Example +------- + +``` {.prettyprint} +pq('#element')->load('http://somesite.com/page .inline-selector')->... +``` + +Table of Contents +================= + +- [Server Side Ajax](#Server_Side_Ajax) +- [Cross Domain Ajax](#Cross_Domain_Ajax) +- [Ajax Requests](#Ajax_Requests) +- [Ajax Events](#Ajax_Events) +- [Misc](#Misc) + +==Server Side Ajax== Ajax, standing for *Asynchronous JavaScript and +XML* is combination of HTTP Client and XML parser which doesn't lock +program's thread (doing request in asynchronous way). + +**phpQuery** also offers such functionality, making use of solid quality +[Zend\_Http\_Client](http://framework.zend.com/manual/en/zend.http.html). +Unfortunately requests aren't asynchronous, but nothing is impossible. +For today, instead of +[XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest) you always +get Zend\_Http\_Client instance. API unification is +[planned](http://code.google.com/p/phpquery/issues/detail?id=44). + +Cross Domain Ajax +----------------- + +For security reasons, by default **phpQuery** doesn't allow connections +to hosts other than actual `$_SERVER['HTTP_HOST']`. Developer needs to +grant rights to other hosts before making an +[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. + +There are 2 methods for allowing other hosts + +- phpQuery::**ajaxAllowURL**(\$url) +- phpQuery::**ajaxAllowHost**(\$host) + +``` {.prettyprint} +// connect to google.com +phpQuery::ajaxAllowHost('google.com'); +phpQuery::get('http://google.com/ig'); +// or using same string +$url = 'http://google.com/ig'; +phpQuery::ajaxAllowURL($url); +phpQuery::get($url); +``` + +Ajax Requests +------------- + +- **[phpQuery::ajax](http://docs.jquery.com/Ajax/jQuery.ajax)**[(\$options)](http://docs.jquery.com/Ajax/jQuery.ajax) + Load a remote page using an HTTP request. +- **[load](http://docs.jquery.com/Ajax/load)**[(\$url, \$data, + \$callback)](http://docs.jquery.com/Ajax/load) Load HTML from a + remote file and inject it into the DOM. +- **[phpQuery::get](http://docs.jquery.com/Ajax/jQuery.get)**[(\$url, + \$data, \$callback)](http://docs.jquery.com/Ajax/jQuery.get) Load a + remote page using an HTTP GET request. +- **[phpQuery::getJSON](http://docs.jquery.com/Ajax/jQuery.getJSON)**[(\$url, + \$data, \$callback)](http://docs.jquery.com/Ajax/jQuery.getJSON) + Load JSON data using an HTTP GET request. +- **[phpQuery::getScript](http://docs.jquery.com/Ajax/jQuery.getScript)**[(\$url, + \$callback)](http://docs.jquery.com/Ajax/jQuery.getScript) Loads, + and executes, a local JavaScript file using an HTTP GET request. +- **[phpQuery::post](http://docs.jquery.com/Ajax/jQuery.post)**[(\$url, + \$data, \$callback, + \$type)](http://docs.jquery.com/Ajax/jQuery.post) Load a remote page + using an HTTP POST request. + +==Ajax Events== + +- **[ajaxComplete](http://docs.jquery.com/Ajax/ajaxComplete)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxComplete) + Attach a function to be executed whenever an AJAX request completes. + This is an Ajax Event. +- **[ajaxError](http://docs.jquery.com/Ajax/ajaxError)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxError) + Attach a function to be executed whenever an AJAX request fails. + This is an Ajax Event. +- **[ajaxSend](http://docs.jquery.com/Ajax/ajaxSend)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxSend) + Attach a function to be executed before an AJAX request is sent. + This is an Ajax Event. +- **[ajaxStart](http://docs.jquery.com/Ajax/ajaxStart)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxStart) + Attach a function to be executed whenever an AJAX request begins and + there is none already active. This is an Ajax Event. +- **[ajaxStop](http://docs.jquery.com/Ajax/ajaxStop)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxStop) + Attach a function to be executed whenever all AJAX requests have + ended. This is an Ajax Event. +- **[ajaxSuccess](http://docs.jquery.com/Ajax/ajaxSuccess)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxSuccess) + Attach a function to be executed whenever an AJAX request completes + successfully. This is an Ajax Event. + +==Misc== + +- **[phpQuery::ajaxSetup](http://docs.jquery.com/Ajax/jQuery.ajaxSetup)**[(\$options)](http://docs.jquery.com/Ajax/jQuery.ajaxSetup) + Setup global settings for AJAX requests. +- **[serialize](http://docs.jquery.com/Ajax/serialize)**[()](http://docs.jquery.com/Ajax/serialize) + Serializes a set of input elements into a string of data. This will + serialize all given elements. +- **[serializeArray](http://docs.jquery.com/Ajax/serializeArray)**[()](http://docs.jquery.com/Ajax/serializeArray) + Serializes all forms and form elements (like the .serialize() + method) but returns a JSON data structure for you to work with. + +==Options== Detailed options description in available at [jQuery +Documentation Site](http://docs.jquery.com/Ajax/jQuery.ajax#toptions). + +- **`async`** `Boolean` +- **`beforeSend`** `Function` +- **`cache`** `Boolean` +- **`complete`** `Function` +- **`contentType`** `String` +- **`data`** `Object, String` +- **`dataType`** `String` +- **`error`** `Function` +- **`global`** `Boolean` +- **`ifModified`** `Boolean` +- **`jsonp`** `String` +- **`password`** `String` +- **`processData`** `Boolean` +- **`success`** `Function` +- **`timeout`** `Number` +- **`type`** `String` +- **`url`** `String` +- **`username`** `String` + +Read more at [Ajax](http://docs.jquery.com/Ajax) section on [jQuery +Documentation Site](http://docs.jquery.com/). diff --git a/docs/Attributes.md b/docs/Attributes.md new file mode 100644 index 0000000..33b8266 --- /dev/null +++ b/docs/Attributes.md @@ -0,0 +1,78 @@ +Example +------- + +``` {.prettyprint} +pq('a')->attr('href', 'newVal')->removeClass('className')->html('newHtml')->... +``` + +Table of Contents +================= + +- [Attr](#Attr) +- [Class](#Class) +- [HTML](#HTML) +- [Text](#Text) +- [Value](#Value) + +==Attr== + +- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$name)](http://docs.jquery.com/Attributes/attr) + Access a property on the first matched element. This method makes it + easy to retrieve a property value from the first matched element. If + the element does not have an attribute with such a name, undefined + is returned. +- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$properties)](http://docs.jquery.com/Attributes/attr) + Set a key/value object as properties to all matched elements. +- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$key, + \$value)](http://docs.jquery.com/Attributes/attr) Set a single + property to a value, on all matched elements. +- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$key, + \$fn)](http://docs.jquery.com/Attributes/attr) Set a single property + to a computed value, on all matched elements. +- **[removeAttr](http://docs.jquery.com/Attributes/removeAttr)**[(\$name)](http://docs.jquery.com/Attributes/removeAttr) + Remove an attribute from each of the matched elements. + +==Class== + +- **[addClass](http://docs.jquery.com/Attributes/addClass)**[(\$class)](http://docs.jquery.com/Attributes/addClass) + Adds the specified class(es) to each of the set of matched elements. +- **[hasClass](http://docs.jquery.com/Attributes/hasClass)**[(\$class)](http://docs.jquery.com/Attributes/hasClass) + Returns true if the specified class is present on at least one of + the set of matched elements. +- **[removeClass](http://docs.jquery.com/Attributes/removeClass)**[(\$class)](http://docs.jquery.com/Attributes/removeClass) + Removes all or the specified class(es) from the set of matched + elements. +- **[toggleClass](http://docs.jquery.com/Attributes/toggleClass)**[(\$class)](http://docs.jquery.com/Attributes/toggleClass) + Adds the specified class if it is not present, removes the specified + class if it is present. + +==HTML== + +- **[html](http://docs.jquery.com/Attributes/html)**[()](http://docs.jquery.com/Attributes/html) + Get the html contents (innerHTML) of the first matched element. This + property is not available on XML documents (although it will work + for XHTML documents). +- **[html](http://docs.jquery.com/Attributes/html)**[(\$val)](http://docs.jquery.com/Attributes/html) + Set the html contents of every matched element. This property is not + available on XML documents (although it will work for XHTML + documents). + +==Text== + +- **[text](http://docs.jquery.com/Attributes/text)**[()](http://docs.jquery.com/Attributes/text) + Get the combined text contents of all matched elements. +- **[text](http://docs.jquery.com/Attributes/text)**[(\$val)](http://docs.jquery.com/Attributes/text) + Set the text contents of all matched elements. + +==Value== + +- **[val](http://docs.jquery.com/Attributes/val)**[()](http://docs.jquery.com/Attributes/val) + Get the content of the value attribute of the first matched element. +- **[val](http://docs.jquery.com/Attributes/val)**[(\$val)](http://docs.jquery.com/Attributes/val) + Set the value attribute of every matched element. +- **[val](http://docs.jquery.com/Attributes/val)**[(\$val)](http://docs.jquery.com/Attributes/val) + Checks, or selects, all the radio buttons, checkboxes, and select + options that match the set of values. + +Read more at [Attributes](http://docs.jquery.com/Attributes) section on +[jQuery Documentation Site](http://docs.jquery.com/). diff --git a/docs/Basics.md b/docs/Basics.md new file mode 100644 index 0000000..d792f4b --- /dev/null +++ b/docs/Basics.md @@ -0,0 +1,77 @@ +Example +------- + +``` {.prettyprint} +phpQuery::newDocumentFileXHTML('my-xhtml.html')->find('p'); +$ul = pq('ul'); +``` + +Table of Contents +================= + +- [Loading documents](#Loading_documents) +- [pq() function](#pq_function) + +Loading documents +----------------- + +- phpQuery::**newDocument**(\$html, \$contentType = null) Creates new + document from markup. If no \$contentType, autodetection is made + (based on markup). If it fails, text/html in utf-8 is used. +- phpQuery::**newDocumentFile**(\$file, \$contentType = null) Creates + new document from file. Works like newDocument() +- phpQuery::**newDocumentHTML**(\$html, \$charset = 'utf-8') +- phpQuery::**newDocumentXHTML**(\$html, \$charset = 'utf-8') +- phpQuery::**newDocumentXML**(\$html, \$charset = 'utf-8') +- phpQuery::**newDocumentPHP**(\$html, \$contentType = null) Read more + about it on [PHPSupport + page](http://code.google.com/p/phpquery/wiki/PHPSupport) +- phpQuery::**newDocumentFileHTML**(\$file, \$charset = 'utf-8') +- phpQuery::**newDocumentFileXHTML**(\$file, \$charset = 'utf-8') +- phpQuery::**newDocumentFileXML**(\$file, \$charset = 'utf-8') +- phpQuery::**newDocumentFilePHP**(\$file, \$contentType) Read more + about it on [PHPSupport + page](http://code.google.com/p/phpquery/wiki/PHPSupport) + +==pq function== **`pq($param, $context = null);`** + +**pq();** function is equivalent of jQuery's **\$();**. It's used for 3 +type of things: + +1. Importing markup + +``` {.prettyprint} +// Import into selected document: +// doesn't accept text nodes at beginning of input string +pq('
    ') +// Import into document with ID from $pq->getDocumentID(): +pq('
    ', $pq->getDocumentID()) +// Import into same document as DOMNode belongs to: +pq('
    ', DOMNode) +// Import into document from phpQuery object: +pq('
    ', $pq) +``` + +1. Running queries + +``` {.prettyprint} +// Run query on last selected document: +pq('div.myClass') +// Run query on document with ID from $pq->getDocumentID(): +pq('div.myClass', $pq->getDocumentID()) +// Run query on same document as DOMNode belongs to and use node(s)as root for query: +pq('div.myClass', DOMNode) +// Run query on document from phpQuery object +// and use object's stack as root node(s) for query: +pq('div.myClass', $pq) +``` + +1. Wrapping DOMNodes with phpQuery objects + +``` {.prettyprint} +foreach(pq('li') as $li) + // $li is pure DOMNode, change it to phpQuery object + pq($li); +``` + + diff --git a/docs/CSS.md b/docs/CSS.md new file mode 100644 index 0000000..40a6c89 --- /dev/null +++ b/docs/CSS.md @@ -0,0 +1 @@ +Work in progress. Scheduled before 1.0. diff --git a/docs/Callbacks.md b/docs/Callbacks.md new file mode 100644 index 0000000..1a28098 --- /dev/null +++ b/docs/Callbacks.md @@ -0,0 +1,145 @@ +Table of Contents +================= + +[What are callbacks](#What_are_callbacks) + +[phpQuery callback system](#phpQuery_callbacks) + +- [Callback class](#Callback) +- [CallbackParam class](#CallbackParam) +- [CallbackReference class](#CallbackReference) + +[Scope Pseudo-Inheritance](#Scope_Pseudo_Inheritance) + +==What are callbacks== Callbacks are functions *called back* by other +functions in proper moment (eg on +[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request error). + +In **JavaScript** this pattern can be very flexible due to +[Closures](http://en.wikipedia.org/wiki/Closure_(computer_science)) +support, which can be inline (no code break) and inherits scope (no need +to passing params). + +**PHP** has only simple [support for +callbacks](http://pl2.php.net/manual/en/function.call-user-func-array.php) +so the case is more complicated. That's why phpQuery extends callback +support by it's own. + +phpQuery callback system +------------------------ + +phpQuery uses it's own approach to callbacks. This task is achieved thou +**Callback**, **CallbackParam** and **CallbackReference** classes. + +### Callback + +Callback class is used for wrapping valid callbacks with params. + +#### Example 1 + +``` {.prettyprint} +function myCallback($param1, $param2) { + var_dump($param1); + var_dump($param2); +} +phpQuery::get($url, + new Callback('myCallback', 'myParam1', new CallbackParam) +); +// now $param1 in myCallback will have value 'myParam1' +// and $param2 will be parameter passed by function calling callback +// which in this example would be ajax request result +``` + +### CallbackParam + +As we can see in [last example](#Example_1), new instance of +CallbackParam class is used for defining places, where original callback +parameter(s) will be placed. Such pattern can be used also without +Callback class for some methods. + +#### Example 2 + +``` {.prettyprint} +phpQuery::each( + // first param is array which will be iterated + array(1,2,3), + // second param is callback (string or array to call objects method) + 'myCallback', + // rest of params are ParamStructure + // CallbackParam objects will be changed to $i and $v by phpQuery::each method + 'param1', new CallbackParam, new CallbackParam, 'param4' +); +function myCallback($param1, $i, $v, $param4) { + print "Index: $i; Value: $v"; +} +``` + +Methods supporting CallbackParam **without** using Callback class: + +- `phpQuery::each()` +- `phpQuery::map()` +- `pq()->each()` +- `pq()->map()` + +===CallbackReference=== Finally, CallbackReference can be used when we +don't really want a callback, only parameter passed to it. +CallbackReference takes first parameter's value and passes it to +reference. Thanks to that, we can use **if statement** instead of +**callback function**. + +#### Example 3 + +``` {.prettyprint} +$html; +phpQuery::get($url, new CallbackReference($html)); +if ($html) { + // callback triggered, value non-false + phpQuery::get($url, new CallbackReference($html)); + if ($html) { + // we just skipped 2 function declarations + } +} +``` + +Scope Pseudo Inheritance +------------------------ + +There is an easy way to pseudo inherit scope in PHP. +[Scope](http://en.wikipedia.org/wiki/Scope_(programming)) means +*variables accessible in specified point of code* (which in other words +means *any variable you can use*). It's achieved using +[compact()](http://php.net/compact) and +[extract()](http://php.net/extract) functions. + +#### Example 4 + +Look at this modified [example 2](#Example_2). Previous comments were +removed. + +``` {.prettyprint} +$a = 'foo'; +$b = 'bar'; +phpQuery::each( + array(1,2,3), + 'myCallback', + // notice that 'param1' changed to compact('a', 'b') + // where 'a' and 'b' are variable names accessible in actual scope + compact('a', 'b'), new CallbackParam, new CallbackParam, 'param4' +); +function myCallback($scope, $i, $v, $param4) { + // this is the place where variables from $scope array + // are forwarded to actual function's scope + extract($scope); + print "Var a: $a"; // will print 'Var a: foo' + print "Var b: $b"; // will print 'Var a: bar' + print "Index: $i; Value: $v"; +} +``` + +Future +------ + +In the future this functionality will be extended and more methods will +support it. Check [Issue Tracker entry +\#48](http://code.google.com/p/phpquery/issues/detail?id=48) if you're +interested in any way. diff --git a/docs/Chains.md b/docs/Chains.md new file mode 100644 index 0000000..4b14c0e --- /dev/null +++ b/docs/Chains.md @@ -0,0 +1 @@ +TODO ;) diff --git a/docs/CommandLineInterface.md b/docs/CommandLineInterface.md new file mode 100644 index 0000000..2550612 --- /dev/null +++ b/docs/CommandLineInterface.md @@ -0,0 +1,21 @@ +**Labels:**Featured phpQuery features CommandLineInterface aka CLI. + +``` {.prettyprint} +Usage: phpquery URL --method1 arg1 arg2 argN --method2 arg1 arg2 argN ... +Example: phpquery 'http://localhost' --find 'div > p' --contents +Pipe: cat index.html | phpquery --find 'div > p' --contents +Docs: http://code.google.com/p/phpquery/wiki/ +``` + +Example +------- + +Fetch number of downloads of all release packages. + +``` {.prettyprint} +phpquery 'http://code.google.com/p/phpquery/downloads/list?can=1' \ + --find '.vt.col_4 a' --contents \ + --getString null array_sum +``` + + diff --git a/docs/Debugging.md b/docs/Debugging.md new file mode 100644 index 0000000..7ceef9d --- /dev/null +++ b/docs/Debugging.md @@ -0,0 +1,23 @@ +Enabling debugging +------------------ + +``` {.prettyprint} +// enable debugging messages +phpQuery::$debug = 1; +// enable extensive debugging messages +// used to debug document loading errors from phpQuery::newDocument() +phpQuery::$debug = 2; +``` + +Debugging methods +----------------- + +``` {.prettyprint} +// debug inside chain +pq('.foo')->dump()->...; +pq('.foo')->dumpWhois()->...; +pq('.foo')->dumpTree()->...; +pq('.foo')->dumpDie()->...; +``` + + diff --git a/docs/Dependencies.md b/docs/Dependencies.md new file mode 100644 index 0000000..251c944 --- /dev/null +++ b/docs/Dependencies.md @@ -0,0 +1,30 @@ +**phpQuery** depends on following code parts: + +- [PHP5](#PHP5) +- [PHP5 DOM extension](#DOM_extension) +- [Zend Framework](#Zend_Framework) + +PHP5 +---- + +Required version of PHP is [PHP5](http://www.php.net/), **5.2** +recommended. + +DOM extension +------------- + +PHP5's build-in [DOM extension](http://php.net/manual/en/book.dom.php) +is required. Users of [windows +XAMPP](http://www.apachefriends.org/en/xampp-windows.html) (and maybe +other unofficial PHP distributions) need to disable depracated [DOM +XML](http://php.net/manual/en/ref.domxml.php) extension. More +information can be found in [this post on +mrclay.org](http://mrclay.org/index.php/2008/10/08/getting-phpquery-running-under-xampp-for-windows/) + +Zend Framework +-------------- + +[Zend Framework](http://framework.zend.com/) is used as HTTP Client and +JSON encoder. Those who already have Zend Framework in their +applications, can remove directory **/phpQuery/Zend**. Only condition is +having proper include path set for own copy of the library. diff --git a/docs/Events.md b/docs/Events.md new file mode 100644 index 0000000..703b479 --- /dev/null +++ b/docs/Events.md @@ -0,0 +1,87 @@ +Table of Contents +================= + +- [Example](#Example) +- [Server Side Events](#Server_Side_Events) +- [Page Load](#Page_Load) +- [Event Handling](#Event_Handling) +- [Interaction Helpers](#Interaction_Helpers) +- [Event Helpers](#Event_Helpers) + +Example +------- + +``` {.prettyprint} +pq('form')->bind('submit', 'submitHandler')->trigger('submit')->... +function submitHandler($e) { + print 'Target: '.$e->target->tagName; + print 'Bubbling ? '.$e->currentTarget->tagName; +} +``` + +Server Side Events +------------------ + +phpQuery support **server-side** events, same as jQuery handle +client-side ones. On server there isn't, of course, events such as +*mouseover* (but they can be triggered). + +By default, phpQuery automatically fires up only **change** event for +form elements. If you load WebBrowser plugin, **submit** and **click** +will be handled properly - eg submitting form with inputs' data to +action URL via new [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) +request. + +\$this (`this` in JS) context for handler scope **isn't available**. You +have to use one of following manually: + +- \$event-\>**target** +- \$event-\>**currentTarget** +- \$event-\>**relatedTarget** + +Page Load +--------- + +*none* + +Event Handling +-------------- + +- **[bind](http://docs.jquery.com/Events/bind)**[(\$type, \$data, + \$fn)](http://docs.jquery.com/Events/bind) Binds a handler to one or + more events (like click) for each matched element. Can also bind + custom events. +- **[one](http://docs.jquery.com/Events/one)**[(\$type, \$data, + \$fn)](http://docs.jquery.com/Events/one) Binds a handler to one or + more events to be executed once for each matched element. +- **[trigger](http://docs.jquery.com/Events/trigger)**[(\$type , + \$data )](http://docs.jquery.com/Events/trigger) Trigger a type of + event on every matched element. +- **[triggerHandler](http://docs.jquery.com/Events/triggerHandler)**[(\$type + , \$data )](http://docs.jquery.com/Events/triggerHandler) This + particular method triggers all bound event handlers on an element + (for a specific event type) WITHOUT executing the browsers default + actions. +- **[unbind](http://docs.jquery.com/Events/unbind)**[(\$type , \$data + )](http://docs.jquery.com/Events/unbind) This does the opposite of + bind, it removes bound events from each of the matched elements. + +Interaction Helpers +------------------- + +*none* + +Event Helpers +------------- + +- **[change](http://docs.jquery.com/Events/change)**[()](http://docs.jquery.com/Events/change) + Triggers the change event of each matched element. +- **[change](http://docs.jquery.com/Events/change)**[(\$fn)](http://docs.jquery.com/Events/change) + Binds a function to the change event of each matched element. +- **[submit](http://docs.jquery.com/Events/submit)**[()](http://docs.jquery.com/Events/submit) + Trigger the submit event of each matched element. +- **[submit](http://docs.jquery.com/Events/submit)**[(\$fn)](http://docs.jquery.com/Events/submit) + Bind a function to the submit event of each matched element. + +Read more at [Events](http://docs.jquery.com/Events) section on [jQuery +Documentation Site](http://docs.jquery.com/). diff --git a/docs/LibrarySections.md b/docs/LibrarySections.md new file mode 100644 index 0000000..4510f6d --- /dev/null +++ b/docs/LibrarySections.md @@ -0,0 +1,2 @@ +**Labels:**Deprecated Renamed to +[Manual](http://code.google.com/p/phpquery/wiki/Manual). diff --git a/docs/Manipulation.md b/docs/Manipulation.md new file mode 100644 index 0000000..786a0ea --- /dev/null +++ b/docs/Manipulation.md @@ -0,0 +1,104 @@ +Example +------- + +``` {.prettyprint} +pq('div.old')->replaceWith( pq('div.new')->clone() )->appendTo('.trash')->prepend('Deleted')->... +``` + +Table of Contents +================= + +- [Changing Contents](#Changing_Contents) +- [Inserting Inside](#Inserting_Inside) +- [Inserting Outside](#Inserting_Outside) +- [Inserting Around](#Inserting_Around) +- [Replacing](#Replacing) +- [Removing](#Removing) +- [Copying](#Copying) + +==Changing Contents== + +- **[html](http://docs.jquery.com/Manipulation/html)**[()](http://docs.jquery.com/Manipulation/html) + Get the html contents (innerHTML) of the first matched element. This + property is not available on XML documents (although it will work + for XHTML documents). +- **[html](http://docs.jquery.com/Manipulation/html)**[(\$val)](http://docs.jquery.com/Manipulation/html) + Set the html contents of every matched element. This property is not + available on XML documents (although it will work for XHTML + documents). +- **[text](http://docs.jquery.com/Manipulation/text)**[()](http://docs.jquery.com/Manipulation/text) + Get the combined text contents of all matched elements. +- **[text](http://docs.jquery.com/Manipulation/text)**[(\$val)](http://docs.jquery.com/Manipulation/text) + Set the text contents of all matched elements. + +==Inserting Inside== + +- **[append](http://docs.jquery.com/Manipulation/append)**[(\$content)](http://docs.jquery.com/Manipulation/append) + Append content to the inside of every matched element. +- **[appendTo](http://docs.jquery.com/Manipulation/appendTo)**[(\$content)](http://docs.jquery.com/Manipulation/appendTo) + Append all of the matched elements to another, specified, set of + elements. +- **[prepend](http://docs.jquery.com/Manipulation/prepend)**[(\$content)](http://docs.jquery.com/Manipulation/prepend) + Prepend content to the inside of every matched element. +- **[prependTo](http://docs.jquery.com/Manipulation/prependTo)**[(\$content)](http://docs.jquery.com/Manipulation/prependTo) + Prepend all of the matched elements to another, specified, set of + elements. + +==Inserting Outside== + +- **[after](http://docs.jquery.com/Manipulation/after)**[(\$content)](http://docs.jquery.com/Manipulation/after) + Insert content after each of the matched elements. +- **[before](http://docs.jquery.com/Manipulation/before)**[(\$content)](http://docs.jquery.com/Manipulation/before) + Insert content before each of the matched elements. +- **[insertAfter](http://docs.jquery.com/Manipulation/insertAfter)**[(\$content)](http://docs.jquery.com/Manipulation/insertAfter) + Insert all of the matched elements after another, specified, set of + elements. +- **[insertBefore](http://docs.jquery.com/Manipulation/insertBefore)**[(\$content)](http://docs.jquery.com/Manipulation/insertBefore) + Insert all of the matched elements before another, specified, set of + elements. + +==Inserting Around== + +- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[(\$html)](http://docs.jquery.com/Manipulation/wrap) + Wrap each matched element with the specified HTML content. +- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[(\$elem)](http://docs.jquery.com/Manipulation/wrap) + Wrap each matched element with the specified element. +- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[(\$html)](http://docs.jquery.com/Manipulation/wrapAll) + Wrap all the elements in the matched set into a single wrapper + element. +- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[(\$elem)](http://docs.jquery.com/Manipulation/wrapAll) + Wrap all the elements in the matched set into a single wrapper + element. +- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[(\$html)](http://docs.jquery.com/Manipulation/wrapInner) + Wrap the inner child contents of each matched element (including + text nodes) with an HTML structure. +- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[(\$elem)](http://docs.jquery.com/Manipulation/wrapInner) + Wrap the inner child contents of each matched element (including + text nodes) with a DOM element. + +==Replacing== + +- **[replaceWith](http://docs.jquery.com/Manipulation/replaceWith)**[(\$content)](http://docs.jquery.com/Manipulation/replaceWith) + Replaces all matched elements with the specified HTML or DOM + elements. +- **[replaceAll](http://docs.jquery.com/Manipulation/replaceAll)**[(\$selector)](http://docs.jquery.com/Manipulation/replaceAll) + Replaces the elements matched by the specified selector with the + matched elements. + +==Removing== + +- **[empty](http://docs.jquery.com/Manipulation/empty)**[()](http://docs.jquery.com/Manipulation/empty) + Remove all child nodes from the set of matched elements. +- **[remove](http://docs.jquery.com/Manipulation/remove)**[(\$expr)](http://docs.jquery.com/Manipulation/remove) + Removes all matched elements from the DOM. + +==Copying== + +- **[clone](http://docs.jquery.com/Manipulation/clone)**[()](http://docs.jquery.com/Manipulation/clone) + Clone matched DOM Elements and select the clones. +- **[clone](http://docs.jquery.com/Manipulation/clone)**[(\$true)](http://docs.jquery.com/Manipulation/clone) + Clone matched DOM Elements, and all their event handlers, and select + the clones. + +Read more at [Manipulation](http://docs.jquery.com/Manipulation) section +on [jQuery Documentation Site](http://docs.jquery.com/). diff --git a/docs/Manual.md b/docs/Manual.md new file mode 100644 index 0000000..7608839 --- /dev/null +++ b/docs/Manual.md @@ -0,0 +1,37 @@ +**Labels:**Featured + +[Basics](http://code.google.com/p/phpquery/wiki/Basics) + +[Ported jQuery +sections](http://code.google.com/p/phpquery/wiki/jQueryPortingState) + +1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) +2. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) +3. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) +4. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) +5. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) +6. [Events](http://code.google.com/p/phpquery/wiki/Events) +7. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) +8. [Plugin + ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) + +[PHP Support](http://code.google.com/p/phpquery/wiki/PHPSupport) + +[Command Line +Interface](http://code.google.com/p/phpquery/wiki/CommandLineInterface) + +[Multi document +support](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) + +[Plugins](http://code.google.com/p/phpquery/wiki/PluginsServerSide) + +1. [WebBrowser](http://code.google.com/p/phpquery/wiki/WebBrowser) +2. [Scripts](http://code.google.com/p/phpquery/wiki/ScriptsPlugin) + +[jQueryServer](http://code.google.com/p/phpquery/wiki/jQueryServer) + +[Debugging](http://code.google.com/p/phpquery/wiki/Debugging) + +Bootstrap file + +**[API Reference](http://meta20.net/phpquery-api/)** is also available. diff --git a/docs/MultiDocumentSupport.md b/docs/MultiDocumentSupport.md new file mode 100644 index 0000000..acd7b45 --- /dev/null +++ b/docs/MultiDocumentSupport.md @@ -0,0 +1,78 @@ +What MultiDocumentSupport is +---------------------------- + +support for working on several documents in same time + +easy importing of nodes from one document to another + +pointing document thought + +- phpQuery object +- [DOMNode](http://www.php.net/manual/en/class.domnode.php) object +- [DOMDocument](http://www.php.net/manual/en/class.domdocument.php) + object +- internal document ID + +last created (or selected) document is assumed to be default in pq(); + +==What MultiDocumentSupport is NOT== + +- it's **not possible** to fetch nodes from several document in one + query +- it's **not possible** to operate on nodes from several document in + one phpQuery object + +Example +------- + +``` {.prettyprint} +// first three documents are wrapped inside phpQuery +$doc1 = phpQuery::newDocumentFile('my-file.html'); +$doc2 = phpQuery::newDocumentFile('my-file.html'); +$doc3 = phpQuery::newDocumentFile('my-other-file.html'); +// $doc4 is plain DOMDocument +$doc4 = new DOMDocument; +$doc4->loadHTMLFile('my-file.html'); +// find first UL list in $doc1 +$doc1->find('ul:first') + // append all LIs from $doc2 (node import) + ->append( $doc2->find('li') ) + // append UL (with new LIs) into $doc3 BODY (node import) + ->appendTo( $doc3->find('body') ); +// this will find all LIs from $doc3 +// thats because it was created as last one +pq('li'); +// this will find all LIs inside first UL in $doc2 (context query) +pq('li', $doc2->find('ul:first')->get()); +// this will find all LIs in whole $doc2 (not a context query) +pq('li', $doc2->find('ul:first')->getDocumentID()); +// this will transparently load $doc4 into phpQuery::$documents +// and then all LIs will be found +// TODO this example must be verified +pq('li', $doc4); +``` + +Static Methods +-------------- + +- phpQuery::**newDocument**(\$html) Creates new document from markup +- phpQuery::**newDocumentFile**(\$file) Creates new document from file +- phpQuery::**getDocument**(\$id = null) Returns phpQueryObject + containing document with id \$id or default document (last + created/selected) +- phpQuery::**selectDocument**(\$id) Sets default document to \$id +- phpQuery::**unloadDocuments**(\$id = null) Unloades all or specified + document from memory +- phpQuery::**getDocumentID**(\$source) Returns \$source's document ID +- phpQuery::**getDOMDocument**(\$source) Get DOMDocument object + related to \$source + +==Object Methods== + +- \$pq-\>**getDocument**() Returns object with stack set to document + root +- \$pq-\>**getDocumentID**() Get object's Document ID +- \$pq-\>**getDocumentIDRef**(&\$documentID) Saves object's DocumentID + to \$var by reference +- \$pq-\>**unloadDocument**() Unloads whole document from memory + diff --git a/docs/PHPSupport.md b/docs/PHPSupport.md new file mode 100644 index 0000000..e19bab5 --- /dev/null +++ b/docs/PHPSupport.md @@ -0,0 +1,157 @@ +**Labels:**Featured,Phase-Implementation Although **phpQuery** is a +[jQuery +port](http://code.google.com/p/phpquery/wiki/jQueryPortingState), there +is extensive PHP-specific support. + +Table of Contents +================= + +[Class Interfaces](#Class_Interfaces) + +- [Iterator Interface](#Iterator) +- [ArrayAccess](#Array_Access) +- [Countable Interface](#Countable) + +[Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) + +[PHP Code Support](#PHP_Code_Support) + +- [Opening PHP files as DOM](#Opening_PHP_files_as_DOM) +- [Inputting PHP code](#Inputting_PHP_code) +- [Outputting PHP code](#Outputting_PHP_code) + +Class Interfaces +---------------- + +phpQuery implements some of [Standard PHP Library +(SPL)](http://pl.php.net/spl) interfaces. + +#### Iterator + +Iterator interface allows looping objects thou native PHP **foreach +loop**. Example: + +``` {.prettyprint} +// get all direct LI elements from UL list of class 'im-the-list' +$LIs = pq('ul.im-the-list > li'); +foreach($LIs as $li) { + pq($li)->addClass('foreached'); +} +``` + +Now there is a catch above. Foreach loop **doesn't return phpQuery +object**. Instead it returns pure DOMNode. That's how jQuery does, +because not always you need **phpQuery** when you found interesting +nodes. + +#### Array Access + +If you like writing arrays, with phpQuery you can still do it, thanks to +the ArrayAccess interface. + +``` {.prettyprint} +$pq = phpQuery::newDocumentFile('somefile.html'); +// print first list outer HTML +print $pq['ul:first']; +// change INNER HTML of second LI directly in first UL +$pq['ul:first > li:eq(1)'] = 'new inner html of second LI directly in first UL'; +// now look at the difference (outer vs inner) +print $pq['ul:first > li:eq(1)']; +// will print
  • new inner html of second LI directly in first UL
  • +``` + +#### Countable + +If used to do `count($something)` you can still do this that way, +instead of eg `pq('p')->size()`. + +``` {.prettyprint} +// count all direct LIs in first list +print count(pq('ul:first > li')); +``` + +Callbacks +--------- + +There is a special +[Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) wiki +section, to which you should refer to. + +PHP Code Support +---------------- + +#### Opening PHP files as DOM + +PHP files can be opened using **phpQuery::newDocumentPHP(\$markup)** or +**phpQuery::newDocumentFilePHP(\$file)**. Such files are visible as DOM, +where: + +- PHP tags beetween DOM elements are available (queryable) as + ` ...code... ` +- PHP tags inside attributes are HTML entities +- PHP tags between DOM element's attributes are **not yet supported** + +====Inputting PHP code==== Additional methods allows placing PHP code +inside DOM. Below each method visible is it's logic equivalent. + +**attrPHP**(\$attr, \$code) + +- [attr](http://docs.jquery.com/Attributes/attr)(\$attr, "\") + +**addClassPHP**(\$code) + +- [addClass](http://docs.jquery.com/Attributes/addClass)("\") + +**beforePHP**(\$code) + +- [before](http://docs.jquery.com/Manipulation/before)("\") + +**afterPHP**(\$code) + +- [after](http://docs.jquery.com/Manipulation/after)("\") + +**prependPHP**(\$code) + +- [prepend](http://docs.jquery.com/Manipulation/prepend)("\") + +**appendPHP**(\$code) + +- [append](http://docs.jquery.com/Manipulation/append)("\") + +**php**(\$code) + +- [html](http://docs.jquery.com/Manipulation/html)("\") + +**wrapAllPHP**(\$codeBefore, \$codeAfter) + +- [wrapAll](http://docs.jquery.com/Manipulation/wrapAll)("\\") + +**wrapPHP**(\$codeBefore, \$codeAfter) + +- [wrap](http://docs.jquery.com/Manipulation/wrap)("\\") + +**wrapInnerPHP**(\$codeBefore, \$codeAfter) + +- [wrapInner](http://docs.jquery.com/Manipulation/wrapInner)("\\") + +**replaceWithPHP**(\$code) + +- [replaceWith](http://docs.jquery.com/Manipulation/replaceWith)("\") + +====Outputting PHP code==== Code inserted with methods above won't be +returned as valid (runnable) using classic output methods such as +**html()**. To make it work, **php()** method without parameter have to +be used. Optionaly **phpQuery::markupToPHP(\$markup)** can activate tags +in string outputed before. **REMEMBER** Outputing runnable code and +placing it on webserver is always dangerous ! diff --git a/docs/PluginsClientSidePorts.md b/docs/PluginsClientSidePorts.md new file mode 100644 index 0000000..bf637b5 --- /dev/null +++ b/docs/PluginsClientSidePorts.md @@ -0,0 +1,15 @@ +In [Issue Tracker](http://code.google.com/p/phpquery/issues/list) there +is a list of [plugins which are planned to be +ported](http://code.google.com/p/phpquery/issues/list?can=2&q=label%3APort). + +JSON +---- + +Port of [JSON](http://jollytoad.googlepages.com/json.js) plugin. + +``` {.prettyprint} +$jsonString = phpQuery::toJSON( pq('form')->serializeArray() ); +$array = phpQuery::parseJSON('{"foo": "bar"}'); +``` + + diff --git a/docs/PluginsServerSide.md b/docs/PluginsServerSide.md new file mode 100644 index 0000000..03797b1 --- /dev/null +++ b/docs/PluginsServerSide.md @@ -0,0 +1,93 @@ +**Labels:**Featured If you need to write plugin only for simple task, +write a **script** using ScriptsPlugin. + +Using plugins +------------- + +Plugins are loaded using **plugin** method from phpQueryObject or +phpQuery static namespace. + +``` {.prettyprint} +// all calls to plugin below are equal +phpQuery::plugin('example') +phpQuery::plugin('example', 'example.php') +pq('ul')->plugin('example') +pq('ul')->plugin('example', 'example.php') +``` + +Writing plugins +--------------- + +Plugin consist from 2 classes - first extending **phpQueryObjects** +(result of pq(); function) and second, extending static +**phpQuery::\$plugins** namespace. Plugin classes are never intialized, +just method calls are forwarded in static way from phpQuery. + +#### Extending phpQueryObject + +``` {.prettyprint} +/** + * phpQuery plugin class extending phpQuery object. + * Methods from this class are callable on every phpQuery object. + * + * Class name prefix 'phpQueryObjectPlugin_' must be preserved. + */ +abstract class phpQueryObjectPlugin_example { + /** + * Limit binded methods. + * + * null means all public. + * array means only specified ones. + * + * @var array|null + */ + public static $phpQueryMethods = null; + /** + * Enter description here... + * + * @param phpQueryObject $self + */ + public static function example($self, $arg1) { + // this method can be called on any phpQuery object, like this: + // pq('div')->example('$arg1 Value') + + // do something + $self->append('Im just an example !'); + // change stack of result object + return $self->find('div'); + } + protected static function helperFunction() { + // this method WONT be avaible as phpQuery method, + // because it isn't publicly callable + } +} +``` + +#### Extending phpQuery + +``` {.prettyprint} +/** + * phpQuery plugin class extending phpQuery static namespace. + * Methods from this class are callable as follows: + * phpQuery::$plugins->staticMethod() + * + * Class name prefix 'phpQueryPlugin_' must be preserved. + */ +abstract class phpQueryPlugin_example { + /** + * Limit binded methods. + * + * null means all public. + * array means only specified ones. + * + * @var array|null + */ + public static $phpQueryMethods = null; + public static function staticMethod() { + // this method can be called within phpQuery class namespace, like this: + // phpQuery::$plugins->staticMethod() + } +} +``` + + diff --git a/docs/ReleasePackages.md b/docs/ReleasePackages.md new file mode 100644 index 0000000..e005efc --- /dev/null +++ b/docs/ReleasePackages.md @@ -0,0 +1,19 @@ +This page is TODO +================= + +Formats +------- + +- RPM +- ZIP + +Forms +----- + +Standard + +OneFile + +- Broken plugins support ? +- ZendFramework not included + diff --git a/docs/SVNCheckout.md b/docs/SVNCheckout.md new file mode 100644 index 0000000..db2add9 --- /dev/null +++ b/docs/SVNCheckout.md @@ -0,0 +1,21 @@ +#### Checkout latest release + +``` {.prettyprint} +svn checkout http://phpquery.googlecode.com/svn/trunk/ phpQuery +``` + +#### Checkout developer branch + +``` {.prettyprint} +svn checkout http://phpquery.googlecode.com/svn/branches/dev/ phpQuery-dev +``` + +You can directly [browse the +code](http://code.google.com/p/phpquery/source/browse/) using web +interface. + +SVN changelog is also available thou [web +interface](http://code.google.com/p/phpquery/source/list) and also as +[RSS](http://code.google.com/feeds/p/phpquery/svnchanges/basic). + +Get SVN for Windows from [TortoiseSVN](http://tortoisesvn.tigris.org/). diff --git a/docs/ScriptsPlugin.md b/docs/ScriptsPlugin.md new file mode 100644 index 0000000..789d03a --- /dev/null +++ b/docs/ScriptsPlugin.md @@ -0,0 +1,42 @@ +**Labels:**Plugin ScriptsPlugin simplifies writing short code scripts +which can be easily reused (chained). It removes plugin overhead +allowing script to be one-line command. + +Using scripts +------------- + +Before using any script, you need to load **Scripts** plugin, like so: + +``` {.prettyprint} +phpQuery::plugin('Scripts'); +// or inside a chain +pq('li')->plugin('Scripts'); +``` + +After that, any available script can be used thou **script** method. + +``` {.prettyprint} +print pq('div')->script('safe_print'); +``` + +Writing scripts +--------------- + +Scripts are placed in **/phpQuery/plugins/Scripts**. Each script has +it's own file. Each file has access to 4 variables: + +- **\$self** Represents \$this +- **\$params** Represents parameters passed to script() method + (without script name) +- **\$return** If not null, will be used as method result +- **\$config** Content of **config.php file + +By default each script returns \$self aka \$this. + +##### Example script + +``` {.prettyprint} +$return = $self->find($params[0]); +``` + + diff --git a/docs/Selectors.md b/docs/Selectors.md new file mode 100644 index 0000000..d0f094b --- /dev/null +++ b/docs/Selectors.md @@ -0,0 +1,168 @@ +Selectors are the heart of jQuery-like interface. Most of [CSS Level +3](http://www.w3.org/TR/2005/WD-css3-selectors-20051215/) syntax is +implemented (in state same as in jQuery). + +Example +------- + +``` {.prettyprint} +pq(".class ul > li[rel='foo']:first:has(a)")->appendTo('.append-target-wrapper div')->... +``` + +Table of Contents +================= + +- [Basics](#Basics) +- [Hierarchy](#Hierarchy) +- [Basic Filters](#Basic_Filters) +- [Content Filters](#Content_Filters) +- [Visibility Filters](#Visibility_Filters) +- [Attribute Filters](#Attribute_Filters) +- [Child Filters](#Child_Filters) +- [Forms](#Forms) +- [Form Filters](#Form_Filters) + +==Basics== + +- **[\#id](http://docs.jquery.com/Selectors/id)** Matches a single + element with the given id attribute. +- **[element](http://docs.jquery.com/Selectors/element)** Matches all + elements with the given name. +- **[.class](http://docs.jquery.com/Selectors/class)** Matches all + elements with the given class. +- **http://docs.jquery.com/Selectors/all WIKI PARSE WARNING: + unterminated '['!**]**Matches all elements.WIKI PARSE WARNING: + unterminated '\*'!** +- **[selector1, selector2, + selectorN](http://docs.jquery.com/Selectors/multiple)** Matches the + combined results of all the specified selectors. + +==Hierarchy== + +- **[ancestor + descendant](http://docs.jquery.com/Selectors/descendant)** Matches + all descendant elements specified by "descendant" of elements + specified by "ancestor". +- **[parent \> child](http://docs.jquery.com/Selectors/child)** + Matches all child elements specified by "child" of elements + specified by "parent". +- **[prev + next](http://docs.jquery.com/Selectors/next)** Matches all + next elements specified by "next" that are next to elements + specified by "prev". +- **[prev \~ siblings](http://docs.jquery.com/Selectors/siblings)** + Matches all sibling elements after the "prev" element that match the + filtering "siblings" selector. + +==Basic Filters== + +- **[:first](http://docs.jquery.com/Selectors/first)** Matches the + first selected element. +- **[:last](http://docs.jquery.com/Selectors/last)** Matches the last + selected element. +- **[:not(selector)](http://docs.jquery.com/Selectors/not)** Filters + out all elements matching the given selector. +- **[:even](http://docs.jquery.com/Selectors/even)** Matches even + elements, zero-indexed. +- **[:odd](http://docs.jquery.com/Selectors/odd)** Matches odd + elements, zero-indexed. +- **[:eq(index)](http://docs.jquery.com/Selectors/eq)** Matches a + single element by its index. +- **[:gt(index)](http://docs.jquery.com/Selectors/gt)** Matches all + elements with an index above the given one. +- **[:lt(index)](http://docs.jquery.com/Selectors/lt)** Matches all + elements with an index below the given one. +- **[:header](http://docs.jquery.com/Selectors/header)** Matches all + elements that are headers, like h1, h2, h3 and so on. +- **[:animated](http://docs.jquery.com/Selectors/animated)** Matches + all elements that are currently being animated. + +==Content Filters== + +- **[:contains(text)](http://docs.jquery.com/Selectors/contains)** + Matches elements which contain the given text. +- **[:empty](http://docs.jquery.com/Selectors/empty)** Matches all + elements that have no children (including text nodes). +- **[:has(selector)](http://docs.jquery.com/Selectors/has)** Matches + elements which contain at least one element that matches the + specified selector. +- **[:parent](http://docs.jquery.com/Selectors/parent)** Matches all + elements that are parents - they have child elements, including + text. + +==Visibility Filters== *none* + +Attribute Filters +----------------- + +- **[[attribute](http://docs.jquery.com/Selectors/attributeHas)]** + Matches elements that have the specified attribute. +- **[[attribute=value](http://docs.jquery.com/Selectors/attributeEquals)]** + Matches elements that have the specified attribute with a certain + value. +- **[[attribute!=value](http://docs.jquery.com/Selectors/attributeNotEqual)]** + Matches elements that don't have the specified attribute with a + certain value. +- **[[attribute\^=value](http://docs.jquery.com/Selectors/attributeStartsWith)]** + Matches elements that have the specified attribute and it starts + with a certain value. +- **[[attribute\$=value](http://docs.jquery.com/Selectors/attributeEndsWith)]** + Matches elements that have the specified attribute and it ends with + a certain value. +- **http://docs.jquery.com/Selectors/attributeContains [attributeWIKI + PARSE WARNING: unterminated '['!**=value]]**Matches elements that + have the specified attribute and it contains a certain value.WIKI + PARSE WARNING: unterminated '\*'!** +- **[[selector1](http://docs.jquery.com/Selectors/attributeMultiple)[selector2](selector2)[selectorN](selectorN)]** + Matches elements that have the specified attribute and it contains a + certain value. + +==Child Filters== + +- **[:nth-child(index/even/odd/equation)](http://docs.jquery.com/Selectors/nthChild)** + Matches all elements that are the nth-child of their parent or that + are the parent's even or odd children. +- **[:first-child](http://docs.jquery.com/Selectors/firstChild)** + Matches all elements that are the first child of their parent. +- **[:last-child](http://docs.jquery.com/Selectors/lastChild)** + Matches all elements that are the last child of their parent. +- **[:only-child](http://docs.jquery.com/Selectors/onlyChild)** + Matches all elements that are the only child of their parent. + +==Forms== + +- **[:input](http://docs.jquery.com/Selectors/input)** Matches all + input, textarea, select and button elements. +- **[:text](http://docs.jquery.com/Selectors/text)** Matches all input + elements of type text. +- **[:password](http://docs.jquery.com/Selectors/password)** Matches + all input elements of type password. +- **[:radio](http://docs.jquery.com/Selectors/radio)** Matches all + input elements of type radio. +- **[:checkbox](http://docs.jquery.com/Selectors/checkbox)** Matches + all input elements of type checkbox. +- **[:submit](http://docs.jquery.com/Selectors/submit)** Matches all + input elements of type submit. +- **[:image](http://docs.jquery.com/Selectors/image)** Matches all + input elements of type image. +- **[:reset](http://docs.jquery.com/Selectors/reset)** Matches all + input elements of type reset. +- **[:button](http://docs.jquery.com/Selectors/button)** Matches all + button elements and input elements of type button. +- **[:file](http://docs.jquery.com/Selectors/file)** Matches all input + elements of type file. +- **[:hidden](http://docs.jquery.com/Selectors/hidden)** Matches all + elements that are hidden, or input elements of type "hidden". + +==Form Filters== + +- **[:enabled](http://docs.jquery.com/Selectors/enabled)** Matches all + elements that are enabled. +- **[:disabled](http://docs.jquery.com/Selectors/disabled)** Matches + all elements that are disabled. +- **[:checked](http://docs.jquery.com/Selectors/checked)** Matches all + elements that are checked. +- **[:selected](http://docs.jquery.com/Selectors/selected)** Matches + all elements that are selected. + +Read more at [Selectors](http://docs.jquery.com/Selectors) section on +[jQuery Documentation Site](http://docs.jquery.com/). diff --git a/docs/Traversing.md b/docs/Traversing.md new file mode 100644 index 0000000..f815eb6 --- /dev/null +++ b/docs/Traversing.md @@ -0,0 +1,88 @@ +Example +------- + +``` {.prettyprint} +pq('div > p')->add('div > ul')->filter(':has(a)')->find('p:first')->nextAll()->andSelf()->... +``` + +Table of Contents +================= + +- [Filtering](#Filtering) +- [Finding](#Finding) +- [Chaining](#Chaining) + +==Filtering== + +- **[eq](http://docs.jquery.com/Traversing/eq)**[(\$index)](http://docs.jquery.com/Traversing/eq) + Reduce the set of matched elements to a single element. +- **[hasClass](http://docs.jquery.com/Traversing/hasClass)**[(\$class)](http://docs.jquery.com/Traversing/hasClass) + Checks the current selection against a class and returns true, if at + least one element of the selection has the given class. +- **[filter](http://docs.jquery.com/Traversing/filter)**[(\$expr)](http://docs.jquery.com/Traversing/filter) + Removes all elements from the set of matched elements that do not + match the specified expression(s). +- **[filter](http://docs.jquery.com/Traversing/filter)**[(\$fn)](http://docs.jquery.com/Traversing/filter) + Removes all elements from the set of matched elements that does not + match the specified function. +- **[is](http://docs.jquery.com/Traversing/is)**[(\$expr)](http://docs.jquery.com/Traversing/is) + Checks the current selection against an expression and returns true, + if at least one element of the selection fits the given expression. +- **[map](http://docs.jquery.com/Traversing/map)**[(\$callback)](http://docs.jquery.com/Traversing/map) + Translate a set of elements in the jQuery object into another set of + values in an array (which may, or may not, be elements). +- **[not](http://docs.jquery.com/Traversing/not)**[(\$expr)](http://docs.jquery.com/Traversing/not) + Removes elements matching the specified expression from the set of + matched elements. +- **[slice](http://docs.jquery.com/Traversing/slice)**[(\$start, + \$end)](http://docs.jquery.com/Traversing/slice) Selects a subset of + the matched elements. + +==Finding== + +- **[add](http://docs.jquery.com/Traversing/add)**[(\$expr)](http://docs.jquery.com/Traversing/add) + Adds more elements, matched by the given expression, to the set of + matched elements. +- **[children](http://docs.jquery.com/Traversing/children)**[(\$expr)](http://docs.jquery.com/Traversing/children) + Get a set of elements containing all of the unique immediate + children of each of the matched set of elements. +- **[contents](http://docs.jquery.com/Traversing/contents)**[()](http://docs.jquery.com/Traversing/contents) + Find all the child nodes inside the matched elements (including text + nodes), or the content document, if the element is an iframe. +- **[find](http://docs.jquery.com/Traversing/find)**[(\$expr)](http://docs.jquery.com/Traversing/find) + Searches for all elements that match the specified expression. This + method is a good way to find additional descendant elements with + which to process. +- **[next](http://docs.jquery.com/Traversing/next)**[(\$expr)](http://docs.jquery.com/Traversing/next) + Get a set of elements containing the unique next siblings of each of + the given set of elements. +- **[nextAll](http://docs.jquery.com/Traversing/nextAll)**[(\$expr)](http://docs.jquery.com/Traversing/nextAll) + Find all sibling elements after the current element. +- **[parent](http://docs.jquery.com/Traversing/parent)**[(\$expr)](http://docs.jquery.com/Traversing/parent) + Get a set of elements containing the unique parents of the matched + set of elements. +- **[parents](http://docs.jquery.com/Traversing/parents)**[(\$expr)](http://docs.jquery.com/Traversing/parents) + Get a set of elements containing the unique ancestors of the matched + set of elements (except for the root element). The matched elements + can be filtered with an optional expression. +- **[prev](http://docs.jquery.com/Traversing/prev)**[(\$expr)](http://docs.jquery.com/Traversing/prev) + Get a set of elements containing the unique previous siblings of + each of the matched set of elements. +- **[prevAll](http://docs.jquery.com/Traversing/prevAll)**[(\$expr)](http://docs.jquery.com/Traversing/prevAll) + Find all sibling elements before the current element. +- **[siblings](http://docs.jquery.com/Traversing/siblings)**[(\$expr)](http://docs.jquery.com/Traversing/siblings) + Get a set of elements containing all of the unique siblings of each + of the matched set of elements. Can be filtered with an optional + expressions. + +==Chaining== + +- **[andSelf](http://docs.jquery.com/Traversing/andSelf)**[()](http://docs.jquery.com/Traversing/andSelf) + Add the previous selection to the current selection. +- **[end](http://docs.jquery.com/Traversing/end)**[()](http://docs.jquery.com/Traversing/end) + Revert the most recent 'destructive' operation, changing the set of + matched elements to its previous state (right before the destructive + operation). + +Read more at [Traversing](http://docs.jquery.com/Traversing) section on +[jQuery Documentation Site](http://docs.jquery.com/). diff --git a/docs/Utilities.md b/docs/Utilities.md new file mode 100644 index 0000000..02279db --- /dev/null +++ b/docs/Utilities.md @@ -0,0 +1,43 @@ +Table of Contents +================= + +- [User Agent](#User_Agent) +- [Array and Object operations](#Array_and_Object_operations) +- [Test operations](#Test_operations) +- [String operations](#String_operations) + +==User Agent== *none* + +Array and Object operations +--------------------------- + +- **[phpQuery::each](http://docs.jquery.com/Utilities/jQuery.each)**[(\$object, + \$callback)](http://docs.jquery.com/Utilities/jQuery.each) A generic + iterator function, which can be used to seamlessly iterate over both + objects and arrays. +- **[phpQuery::grep](http://docs.jquery.com/Utilities/jQuery.grep)**[(\$array, + \$callback, \$invert)](http://docs.jquery.com/Utilities/jQuery.grep) + Filter items out of an array, by using a filter function. +- **[phpQuery::makeArray](http://docs.jquery.com/Utilities/jQuery.makeArray)**[(\$obj)](http://docs.jquery.com/Utilities/jQuery.makeArray) + Turns an array-like object into a true array. +- **[phpQuery::map](http://docs.jquery.com/Utilities/jQuery.map)**[(\$array, + \$callback)](http://docs.jquery.com/Utilities/jQuery.map) Translate + all items in an array to another array of items. +- **[phpQuery::inArray](http://docs.jquery.com/Utilities/jQuery.inArray)**[(\$value, + \$array)](http://docs.jquery.com/Utilities/jQuery.inArray) Determine + the index of the first parameter in the Array (-1 if not found). +- **[phpQuery::unique](http://docs.jquery.com/Utilities/jQuery.unique)**[(\$array)](http://docs.jquery.com/Utilities/jQuery.unique) + Remove all duplicate elements from an array of elements. + +==Test operations== + +- **[phpQuery::isFunction](http://docs.jquery.com/Utilities/jQuery.isFunction)**[(\$obj)](http://docs.jquery.com/Utilities/jQuery.isFunction) + Determine if the parameter passed is a function. + +==String operations== + +- **[phpQuery::trim](http://docs.jquery.com/Utilities/jQuery.trim)**[(\$str)](http://docs.jquery.com/Utilities/jQuery.trim) + Remove the whitespace from the beginning and end of a string. + +Read more at [Utilities](http://docs.jquery.com/Utilities) section on +[jQuery Documentation Site](http://docs.jquery.com/). diff --git a/docs/WebBrowser.md b/docs/WebBrowser.md new file mode 100644 index 0000000..119fc19 --- /dev/null +++ b/docs/WebBrowser.md @@ -0,0 +1,55 @@ +**Labels:**Featured,Phase-Implementation,Plugin **WebBrowser** is a +phpQuery +[plugin](http://code.google.com/p/phpquery/wiki/PluginsServerSide) that +mimics behaviors of web browser. Thanks to that developer can simulate +user's behavior inside a PHP script. + +Supported +--------- + +- Link navigation (click event) +- Form navigation (submit event) +- Cookies (thought + [Zend\_Http\_CookieJar](http://framework.zend.com/manual/en/zend.http.cookies.html)) +- Relative links +- document.location (not an object, yet) + +Use cases +--------- + +- Fill forms and submit them easly +- Login to secure pages and collect content +- Write test cases reproducing browsing proccess + +Example 1 +--------- + +Adding web browser functionality to existing phpQuery object and +submiting the form. + +``` {.prettyprint} +->WebBrowser('callback')->find('form')->submit()->... +``` + +Example 2 +--------- + +Querying Google against "search phrase": + +``` {.prettyprint} +require_once('phpQuery/phpQuery.php'); +phpQuery::browserGet('http://www.google.com/', 'success1'); +function success1($browser) { + $browser + ->WebBrowser('success2') + ->find('input[name=q]') + ->val('search phrase') + ->parents('form') + ->submit(); +} +function success2($browser) { + print $browser; +} +``` + + diff --git a/docs/jQueryDifferences.md b/docs/jQueryDifferences.md new file mode 100644 index 0000000..7861b40 --- /dev/null +++ b/docs/jQueryDifferences.md @@ -0,0 +1,2 @@ +**Labels:**Deprecated Renamed to +[jQueryPortingState](http://code.google.com/p/phpquery/wiki/jQueryPortingState). diff --git a/docs/jQueryHelpers.md b/docs/jQueryHelpers.md new file mode 100644 index 0000000..70a4c77 --- /dev/null +++ b/docs/jQueryHelpers.md @@ -0,0 +1,5 @@ +jQuery helper libraries written in PHP + +- [jquery-php](http://code.google.com/p/jquery-php/) +- [PQuery](http://www.ngcoders.com/php/pquery-php-and-jquery) + diff --git a/docs/jQueryPortingState.md b/docs/jQueryPortingState.md new file mode 100644 index 0000000..edde302 --- /dev/null +++ b/docs/jQueryPortingState.md @@ -0,0 +1,42 @@ +phpQuery is almost a full port of the [jQuery JavaScript +Library](http://jquery.com/). + +Ported Sections +--------------- + +1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) +2. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) +3. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) +4. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) +5. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) +6. [Events](http://code.google.com/p/phpquery/wiki/Events) +7. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) +8. [Plugin + ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) + +Additional methods +------------------ + +phpQuery features many additional methods comparing to jQuery: + +- htmlOuter() +- xml() +- xmlOuter() +- markup() +- markupOuter() +- getString() +- reverse() +- contentsUnwrap() +- switchWith() +- all from + [PHPSupport](http://code.google.com/p/phpquery/wiki/PHPSupport) +- all from [Basic](http://code.google.com/p/phpquery/wiki/Basic) +- all from + [MultiDocumentSupport](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) + +Other Differences +----------------- + +- [Server Side + Events](http://code.google.com/p/phpquery/wiki/Events?ts=1225458859&updated=Events#Server_Side_Events) + diff --git a/docs/jQueryServer.md b/docs/jQueryServer.md new file mode 100644 index 0000000..6ebc0cc --- /dev/null +++ b/docs/jQueryServer.md @@ -0,0 +1,29 @@ +**Labels:**Featured **jQueryServer** is a jQuery plugin giving +unobstrusive, client-side bindings to server-side implementation of +jQuery. + +Example scenario +---------------- + +1. Connect to server and make an + [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request to + somewhere ([crossdomain + allowed](http://code.google.com/p/phpquery/wiki/CrossDomainAjax)) +2. Do some manipulations, you can even trigger a [server-side + event](http://code.google.com/p/phpquery/wiki/Events#Server_Side_Events) +3. Get processed date back to the browser + +Example code +------------ + +``` {.prettyprint} +$.server({url: 'http://somesite.com'}) + .find('.my-class') + .client(function(response){ + $('.destination').html(response); +}); +``` + +Since version **0.5.1** (this is **not** phpQuery release version +number) there is a support for config file which **authorizes** +[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) hosts and referers. diff --git a/docs/jQueryServerSidePorts.md b/docs/jQueryServerSidePorts.md new file mode 100644 index 0000000..9f9055c --- /dev/null +++ b/docs/jQueryServerSidePorts.md @@ -0,0 +1,10 @@ +jQuery ports to server-side languages: + +- **PHP** - [phpQuery](http://code.google.com/p/phpquery/) +- **ActionScript** - + [as3query](http://tech.nitoyon.com/blog/2008/01/as3query_alpha.html) +- **Ruby** - [hpricot](http://code.whytheluckystiff.net/hpricot/) +- **Perl** - + [pQuery](http://search.cpan.org/~ingy/pQuery/lib/pQuery.pm) +- **Python** - [PyQuery](http://pypi.python.org/pypi/pyquery) + From 557482292892b98edd3b2e21fbcb88af9b53bb85 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 15:36:41 -0500 Subject: [PATCH 37/59] Correct the conversion of sub-headings when they lack spaces before the declarations. --- docs/Ajax.md | 22 +++++++++++++++------- docs/Attributes.md | 15 ++++++++++----- docs/Basics.md | 5 ++++- docs/Callbacks.md | 20 ++++++++++++-------- docs/Manipulation.md | 21 ++++++++++++++------- docs/MultiDocumentSupport.md | 6 ++++-- docs/PHPSupport.md | 20 ++++++++++++-------- docs/Selectors.md | 26 ++++++++++++++++++-------- docs/Traversing.md | 9 ++++++--- docs/Utilities.md | 11 ++++++++--- 10 files changed, 103 insertions(+), 52 deletions(-) diff --git a/docs/Ajax.md b/docs/Ajax.md index 178d62b..aa58a1f 100644 --- a/docs/Ajax.md +++ b/docs/Ajax.md @@ -14,9 +14,12 @@ Table of Contents - [Ajax Events](#Ajax_Events) - [Misc](#Misc) -==Server Side Ajax== Ajax, standing for *Asynchronous JavaScript and -XML* is combination of HTTP Client and XML parser which doesn't lock -program's thread (doing request in asynchronous way). +Server Side Ajax +---------------- + +Ajax, standing for *Asynchronous JavaScript and XML* is combination of +HTTP Client and XML parser which doesn't lock program's thread (doing +request in asynchronous way). **phpQuery** also offers such functionality, making use of solid quality [Zend\_Http\_Client](http://framework.zend.com/manual/en/zend.http.html). @@ -71,7 +74,8 @@ Ajax Requests \$type)](http://docs.jquery.com/Ajax/jQuery.post) Load a remote page using an HTTP POST request. -==Ajax Events== +Ajax Events +----------- - **[ajaxComplete](http://docs.jquery.com/Ajax/ajaxComplete)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxComplete) Attach a function to be executed whenever an AJAX request completes. @@ -92,7 +96,8 @@ Ajax Requests Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event. -==Misc== +Misc +---- - **[phpQuery::ajaxSetup](http://docs.jquery.com/Ajax/jQuery.ajaxSetup)**[(\$options)](http://docs.jquery.com/Ajax/jQuery.ajaxSetup) Setup global settings for AJAX requests. @@ -103,8 +108,11 @@ Ajax Requests Serializes all forms and form elements (like the .serialize() method) but returns a JSON data structure for you to work with. -==Options== Detailed options description in available at [jQuery -Documentation Site](http://docs.jquery.com/Ajax/jQuery.ajax#toptions). +Options +------- + +Detailed options description in available at [jQuery Documentation +Site](http://docs.jquery.com/Ajax/jQuery.ajax#toptions). - **`async`** `Boolean` - **`beforeSend`** `Function` diff --git a/docs/Attributes.md b/docs/Attributes.md index 33b8266..6bf3d7e 100644 --- a/docs/Attributes.md +++ b/docs/Attributes.md @@ -14,7 +14,8 @@ Table of Contents - [Text](#Text) - [Value](#Value) -==Attr== +Attr +---- - **[attr](http://docs.jquery.com/Attributes/attr)**[(\$name)](http://docs.jquery.com/Attributes/attr) Access a property on the first matched element. This method makes it @@ -32,7 +33,8 @@ Table of Contents - **[removeAttr](http://docs.jquery.com/Attributes/removeAttr)**[(\$name)](http://docs.jquery.com/Attributes/removeAttr) Remove an attribute from each of the matched elements. -==Class== +Class +----- - **[addClass](http://docs.jquery.com/Attributes/addClass)**[(\$class)](http://docs.jquery.com/Attributes/addClass) Adds the specified class(es) to each of the set of matched elements. @@ -46,7 +48,8 @@ Table of Contents Adds the specified class if it is not present, removes the specified class if it is present. -==HTML== +HTML +---- - **[html](http://docs.jquery.com/Attributes/html)**[()](http://docs.jquery.com/Attributes/html) Get the html contents (innerHTML) of the first matched element. This @@ -57,14 +60,16 @@ Table of Contents available on XML documents (although it will work for XHTML documents). -==Text== +Text +---- - **[text](http://docs.jquery.com/Attributes/text)**[()](http://docs.jquery.com/Attributes/text) Get the combined text contents of all matched elements. - **[text](http://docs.jquery.com/Attributes/text)**[(\$val)](http://docs.jquery.com/Attributes/text) Set the text contents of all matched elements. -==Value== +Value +----- - **[val](http://docs.jquery.com/Attributes/val)**[()](http://docs.jquery.com/Attributes/val) Get the content of the value attribute of the first matched element. diff --git a/docs/Basics.md b/docs/Basics.md index d792f4b..658bd83 100644 --- a/docs/Basics.md +++ b/docs/Basics.md @@ -33,7 +33,10 @@ Loading documents about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) -==pq function== **`pq($param, $context = null);`** +pq function +----------- + +**`pq($param, $context = null);`** **pq();** function is equivalent of jQuery's **\$();**. It's used for 3 type of things: diff --git a/docs/Callbacks.md b/docs/Callbacks.md index 1a28098..5d984f4 100644 --- a/docs/Callbacks.md +++ b/docs/Callbacks.md @@ -11,9 +11,12 @@ Table of Contents [Scope Pseudo-Inheritance](#Scope_Pseudo_Inheritance) -==What are callbacks== Callbacks are functions *called back* by other -functions in proper moment (eg on -[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request error). +What are callbacks +------------------ + +Callbacks are functions *called back* by other functions in proper +moment (eg on [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) +request error). In **JavaScript** this pattern can be very flexible due to [Closures](http://en.wikipedia.org/wiki/Closure_(computer_science)) @@ -81,11 +84,12 @@ Methods supporting CallbackParam **without** using Callback class: - `pq()->each()` - `pq()->map()` -===CallbackReference=== Finally, CallbackReference can be used when we -don't really want a callback, only parameter passed to it. -CallbackReference takes first parameter's value and passes it to -reference. Thanks to that, we can use **if statement** instead of -**callback function**. +### CallbackReference + +Finally, CallbackReference can be used when we don't really want a +callback, only parameter passed to it. CallbackReference takes first +parameter's value and passes it to reference. Thanks to that, we can use +**if statement** instead of **callback function**. #### Example 3 diff --git a/docs/Manipulation.md b/docs/Manipulation.md index 786a0ea..2b367c9 100644 --- a/docs/Manipulation.md +++ b/docs/Manipulation.md @@ -16,7 +16,8 @@ Table of Contents - [Removing](#Removing) - [Copying](#Copying) -==Changing Contents== +Changing Contents +----------------- - **[html](http://docs.jquery.com/Manipulation/html)**[()](http://docs.jquery.com/Manipulation/html) Get the html contents (innerHTML) of the first matched element. This @@ -31,7 +32,8 @@ Table of Contents - **[text](http://docs.jquery.com/Manipulation/text)**[(\$val)](http://docs.jquery.com/Manipulation/text) Set the text contents of all matched elements. -==Inserting Inside== +Inserting Inside +---------------- - **[append](http://docs.jquery.com/Manipulation/append)**[(\$content)](http://docs.jquery.com/Manipulation/append) Append content to the inside of every matched element. @@ -44,7 +46,8 @@ Table of Contents Prepend all of the matched elements to another, specified, set of elements. -==Inserting Outside== +Inserting Outside +----------------- - **[after](http://docs.jquery.com/Manipulation/after)**[(\$content)](http://docs.jquery.com/Manipulation/after) Insert content after each of the matched elements. @@ -57,7 +60,8 @@ Table of Contents Insert all of the matched elements before another, specified, set of elements. -==Inserting Around== +Inserting Around +---------------- - **[wrap](http://docs.jquery.com/Manipulation/wrap)**[(\$html)](http://docs.jquery.com/Manipulation/wrap) Wrap each matched element with the specified HTML content. @@ -76,7 +80,8 @@ Table of Contents Wrap the inner child contents of each matched element (including text nodes) with a DOM element. -==Replacing== +Replacing +--------- - **[replaceWith](http://docs.jquery.com/Manipulation/replaceWith)**[(\$content)](http://docs.jquery.com/Manipulation/replaceWith) Replaces all matched elements with the specified HTML or DOM @@ -85,14 +90,16 @@ Table of Contents Replaces the elements matched by the specified selector with the matched elements. -==Removing== +Removing +-------- - **[empty](http://docs.jquery.com/Manipulation/empty)**[()](http://docs.jquery.com/Manipulation/empty) Remove all child nodes from the set of matched elements. - **[remove](http://docs.jquery.com/Manipulation/remove)**[(\$expr)](http://docs.jquery.com/Manipulation/remove) Removes all matched elements from the DOM. -==Copying== +Copying +------- - **[clone](http://docs.jquery.com/Manipulation/clone)**[()](http://docs.jquery.com/Manipulation/clone) Clone matched DOM Elements and select the clones. diff --git a/docs/MultiDocumentSupport.md b/docs/MultiDocumentSupport.md index acd7b45..8c840e2 100644 --- a/docs/MultiDocumentSupport.md +++ b/docs/MultiDocumentSupport.md @@ -15,7 +15,8 @@ pointing document thought last created (or selected) document is assumed to be default in pq(); -==What MultiDocumentSupport is NOT== +What MultiDocumentSupport is NOT +-------------------------------- - it's **not possible** to fetch nodes from several document in one query @@ -67,7 +68,8 @@ Static Methods - phpQuery::**getDOMDocument**(\$source) Get DOMDocument object related to \$source -==Object Methods== +Object Methods +-------------- - \$pq-\>**getDocument**() Returns object with stack set to document root diff --git a/docs/PHPSupport.md b/docs/PHPSupport.md index e19bab5..b277568 100644 --- a/docs/PHPSupport.md +++ b/docs/PHPSupport.md @@ -91,8 +91,10 @@ where: - PHP tags inside attributes are HTML entities - PHP tags between DOM element's attributes are **not yet supported** -====Inputting PHP code==== Additional methods allows placing PHP code -inside DOM. Below each method visible is it's logic equivalent. +#### Inputting PHP code + +Additional methods allows placing PHP code inside DOM. Below each method +visible is it's logic equivalent. **attrPHP**(\$attr, \$code) @@ -149,9 +151,11 @@ inside DOM. Below each method visible is it's logic equivalent. - [replaceWith](http://docs.jquery.com/Manipulation/replaceWith)("\") -====Outputting PHP code==== Code inserted with methods above won't be -returned as valid (runnable) using classic output methods such as -**html()**. To make it work, **php()** method without parameter have to -be used. Optionaly **phpQuery::markupToPHP(\$markup)** can activate tags -in string outputed before. **REMEMBER** Outputing runnable code and -placing it on webserver is always dangerous ! +#### Outputting PHP code + +Code inserted with methods above won't be returned as valid (runnable) +using classic output methods such as **html()**. To make it work, +**php()** method without parameter have to be used. Optionaly +**phpQuery::markupToPHP(\$markup)** can activate tags in string outputed +before. **REMEMBER** Outputing runnable code and placing it on webserver +is always dangerous ! diff --git a/docs/Selectors.md b/docs/Selectors.md index d0f094b..c1d4bae 100644 --- a/docs/Selectors.md +++ b/docs/Selectors.md @@ -22,7 +22,8 @@ Table of Contents - [Forms](#Forms) - [Form Filters](#Form_Filters) -==Basics== +Basics +------ - **[\#id](http://docs.jquery.com/Selectors/id)** Matches a single element with the given id attribute. @@ -37,7 +38,8 @@ Table of Contents selectorN](http://docs.jquery.com/Selectors/multiple)** Matches the combined results of all the specified selectors. -==Hierarchy== +Hierarchy +--------- - **[ancestor descendant](http://docs.jquery.com/Selectors/descendant)** Matches @@ -53,7 +55,8 @@ Table of Contents Matches all sibling elements after the "prev" element that match the filtering "siblings" selector. -==Basic Filters== +Basic Filters +------------- - **[:first](http://docs.jquery.com/Selectors/first)** Matches the first selected element. @@ -76,7 +79,8 @@ Table of Contents - **[:animated](http://docs.jquery.com/Selectors/animated)** Matches all elements that are currently being animated. -==Content Filters== +Content Filters +--------------- - **[:contains(text)](http://docs.jquery.com/Selectors/contains)** Matches elements which contain the given text. @@ -89,7 +93,10 @@ Table of Contents elements that are parents - they have child elements, including text. -==Visibility Filters== *none* +Visibility Filters +------------------ + +*none* Attribute Filters ----------------- @@ -116,7 +123,8 @@ Attribute Filters Matches elements that have the specified attribute and it contains a certain value. -==Child Filters== +Child Filters +------------- - **[:nth-child(index/even/odd/equation)](http://docs.jquery.com/Selectors/nthChild)** Matches all elements that are the nth-child of their parent or that @@ -128,7 +136,8 @@ Attribute Filters - **[:only-child](http://docs.jquery.com/Selectors/onlyChild)** Matches all elements that are the only child of their parent. -==Forms== +Forms +----- - **[:input](http://docs.jquery.com/Selectors/input)** Matches all input, textarea, select and button elements. @@ -153,7 +162,8 @@ Attribute Filters - **[:hidden](http://docs.jquery.com/Selectors/hidden)** Matches all elements that are hidden, or input elements of type "hidden". -==Form Filters== +Form Filters +------------ - **[:enabled](http://docs.jquery.com/Selectors/enabled)** Matches all elements that are enabled. diff --git a/docs/Traversing.md b/docs/Traversing.md index f815eb6..a461ae8 100644 --- a/docs/Traversing.md +++ b/docs/Traversing.md @@ -12,7 +12,8 @@ Table of Contents - [Finding](#Finding) - [Chaining](#Chaining) -==Filtering== +Filtering +--------- - **[eq](http://docs.jquery.com/Traversing/eq)**[(\$index)](http://docs.jquery.com/Traversing/eq) Reduce the set of matched elements to a single element. @@ -38,7 +39,8 @@ Table of Contents \$end)](http://docs.jquery.com/Traversing/slice) Selects a subset of the matched elements. -==Finding== +Finding +------- - **[add](http://docs.jquery.com/Traversing/add)**[(\$expr)](http://docs.jquery.com/Traversing/add) Adds more elements, matched by the given expression, to the set of @@ -75,7 +77,8 @@ Table of Contents of the matched set of elements. Can be filtered with an optional expressions. -==Chaining== +Chaining +-------- - **[andSelf](http://docs.jquery.com/Traversing/andSelf)**[()](http://docs.jquery.com/Traversing/andSelf) Add the previous selection to the current selection. diff --git a/docs/Utilities.md b/docs/Utilities.md index 02279db..dbee086 100644 --- a/docs/Utilities.md +++ b/docs/Utilities.md @@ -6,7 +6,10 @@ Table of Contents - [Test operations](#Test_operations) - [String operations](#String_operations) -==User Agent== *none* +User Agent +---------- + +*none* Array and Object operations --------------------------- @@ -29,12 +32,14 @@ Array and Object operations - **[phpQuery::unique](http://docs.jquery.com/Utilities/jQuery.unique)**[(\$array)](http://docs.jquery.com/Utilities/jQuery.unique) Remove all duplicate elements from an array of elements. -==Test operations== +Test operations +--------------- - **[phpQuery::isFunction](http://docs.jquery.com/Utilities/jQuery.isFunction)**[(\$obj)](http://docs.jquery.com/Utilities/jQuery.isFunction) Determine if the parameter passed is a function. -==String operations== +String operations +----------------- - **[phpQuery::trim](http://docs.jquery.com/Utilities/jQuery.trim)**[(\$str)](http://docs.jquery.com/Utilities/jQuery.trim) Remove the whitespace from the beginning and end of a string. From bf9e88968caf72a4f8267869ce27c8dbc291e76d Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 16:12:44 -0500 Subject: [PATCH 38/59] Replaced the prettyprint configuration with php. #9 --- docs/Ajax.md | 4 ++-- docs/Attributes.md | 2 +- docs/Basics.md | 8 ++++---- docs/Callbacks.md | 8 ++++---- docs/CommandLineInterface.md | 4 ++-- docs/Debugging.md | 4 ++-- docs/Events.md | 2 +- docs/Manipulation.md | 2 +- docs/MultiDocumentSupport.md | 2 +- docs/PHPSupport.md | 6 +++--- docs/PluginsClientSidePorts.md | 2 +- docs/PluginsServerSide.md | 6 +++--- docs/SVNCheckout.md | 4 ++-- docs/ScriptsPlugin.md | 6 +++--- docs/Selectors.md | 2 +- docs/Traversing.md | 2 +- docs/WebBrowser.md | 4 ++-- docs/jQueryServer.md | 2 +- 18 files changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/Ajax.md b/docs/Ajax.md index aa58a1f..a87b2dc 100644 --- a/docs/Ajax.md +++ b/docs/Ajax.md @@ -1,7 +1,7 @@ Example ------- -``` {.prettyprint} +``` php pq('#element')->load('http://somesite.com/page .inline-selector')->... ``` @@ -42,7 +42,7 @@ There are 2 methods for allowing other hosts - phpQuery::**ajaxAllowURL**(\$url) - phpQuery::**ajaxAllowHost**(\$host) -``` {.prettyprint} +``` php // connect to google.com phpQuery::ajaxAllowHost('google.com'); phpQuery::get('http://google.com/ig'); diff --git a/docs/Attributes.md b/docs/Attributes.md index 6bf3d7e..d6da149 100644 --- a/docs/Attributes.md +++ b/docs/Attributes.md @@ -1,7 +1,7 @@ Example ------- -``` {.prettyprint} +``` php pq('a')->attr('href', 'newVal')->removeClass('className')->html('newHtml')->... ``` diff --git a/docs/Basics.md b/docs/Basics.md index 658bd83..545f57d 100644 --- a/docs/Basics.md +++ b/docs/Basics.md @@ -1,7 +1,7 @@ Example ------- -``` {.prettyprint} +``` php phpQuery::newDocumentFileXHTML('my-xhtml.html')->find('p'); $ul = pq('ul'); ``` @@ -43,7 +43,7 @@ type of things: 1. Importing markup -``` {.prettyprint} +``` php // Import into selected document: // doesn't accept text nodes at beginning of input string pq('
    ') @@ -57,7 +57,7 @@ pq('
    ', $pq) 1. Running queries -``` {.prettyprint} +``` php // Run query on last selected document: pq('div.myClass') // Run query on document with ID from $pq->getDocumentID(): @@ -71,7 +71,7 @@ pq('div.myClass', $pq) 1. Wrapping DOMNodes with phpQuery objects -``` {.prettyprint} +``` php foreach(pq('li') as $li) // $li is pure DOMNode, change it to phpQuery object pq($li); diff --git a/docs/Callbacks.md b/docs/Callbacks.md index 5d984f4..e12c2b9 100644 --- a/docs/Callbacks.md +++ b/docs/Callbacks.md @@ -40,7 +40,7 @@ Callback class is used for wrapping valid callbacks with params. #### Example 1 -``` {.prettyprint} +``` php function myCallback($param1, $param2) { var_dump($param1); var_dump($param2); @@ -62,7 +62,7 @@ Callback class for some methods. #### Example 2 -``` {.prettyprint} +``` php phpQuery::each( // first param is array which will be iterated array(1,2,3), @@ -93,7 +93,7 @@ parameter's value and passes it to reference. Thanks to that, we can use #### Example 3 -``` {.prettyprint} +``` php $html; phpQuery::get($url, new CallbackReference($html)); if ($html) { @@ -120,7 +120,7 @@ means *any variable you can use*). It's achieved using Look at this modified [example 2](#Example_2). Previous comments were removed. -``` {.prettyprint} +``` php $a = 'foo'; $b = 'bar'; phpQuery::each( diff --git a/docs/CommandLineInterface.md b/docs/CommandLineInterface.md index 2550612..fe3d005 100644 --- a/docs/CommandLineInterface.md +++ b/docs/CommandLineInterface.md @@ -1,6 +1,6 @@ **Labels:**Featured phpQuery features CommandLineInterface aka CLI. -``` {.prettyprint} +``` php Usage: phpquery URL --method1 arg1 arg2 argN --method2 arg1 arg2 argN ... Example: phpquery 'http://localhost' --find 'div > p' --contents Pipe: cat index.html | phpquery --find 'div > p' --contents @@ -12,7 +12,7 @@ Example Fetch number of downloads of all release packages. -``` {.prettyprint} +``` php phpquery 'http://code.google.com/p/phpquery/downloads/list?can=1' \ --find '.vt.col_4 a' --contents \ --getString null array_sum diff --git a/docs/Debugging.md b/docs/Debugging.md index 7ceef9d..b55b311 100644 --- a/docs/Debugging.md +++ b/docs/Debugging.md @@ -1,7 +1,7 @@ Enabling debugging ------------------ -``` {.prettyprint} +``` php // enable debugging messages phpQuery::$debug = 1; // enable extensive debugging messages @@ -12,7 +12,7 @@ phpQuery::$debug = 2; Debugging methods ----------------- -``` {.prettyprint} +``` php // debug inside chain pq('.foo')->dump()->...; pq('.foo')->dumpWhois()->...; diff --git a/docs/Events.md b/docs/Events.md index 703b479..81b6a59 100644 --- a/docs/Events.md +++ b/docs/Events.md @@ -11,7 +11,7 @@ Table of Contents Example ------- -``` {.prettyprint} +``` php pq('form')->bind('submit', 'submitHandler')->trigger('submit')->... function submitHandler($e) { print 'Target: '.$e->target->tagName; diff --git a/docs/Manipulation.md b/docs/Manipulation.md index 2b367c9..53da4d4 100644 --- a/docs/Manipulation.md +++ b/docs/Manipulation.md @@ -1,7 +1,7 @@ Example ------- -``` {.prettyprint} +``` php pq('div.old')->replaceWith( pq('div.new')->clone() )->appendTo('.trash')->prepend('Deleted')->... ``` diff --git a/docs/MultiDocumentSupport.md b/docs/MultiDocumentSupport.md index 8c840e2..08f6ab6 100644 --- a/docs/MultiDocumentSupport.md +++ b/docs/MultiDocumentSupport.md @@ -26,7 +26,7 @@ What MultiDocumentSupport is NOT Example ------- -``` {.prettyprint} +``` php // first three documents are wrapped inside phpQuery $doc1 = phpQuery::newDocumentFile('my-file.html'); $doc2 = phpQuery::newDocumentFile('my-file.html'); diff --git a/docs/PHPSupport.md b/docs/PHPSupport.md index b277568..e27e6bc 100644 --- a/docs/PHPSupport.md +++ b/docs/PHPSupport.md @@ -31,7 +31,7 @@ phpQuery implements some of [Standard PHP Library Iterator interface allows looping objects thou native PHP **foreach loop**. Example: -``` {.prettyprint} +``` php // get all direct LI elements from UL list of class 'im-the-list' $LIs = pq('ul.im-the-list > li'); foreach($LIs as $li) { @@ -49,7 +49,7 @@ nodes. If you like writing arrays, with phpQuery you can still do it, thanks to the ArrayAccess interface. -``` {.prettyprint} +``` php $pq = phpQuery::newDocumentFile('somefile.html'); // print first list outer HTML print $pq['ul:first']; @@ -65,7 +65,7 @@ print $pq['ul:first > li:eq(1)']; If used to do `count($something)` you can still do this that way, instead of eg `pq('p')->size()`. -``` {.prettyprint} +``` php // count all direct LIs in first list print count(pq('ul:first > li')); ``` diff --git a/docs/PluginsClientSidePorts.md b/docs/PluginsClientSidePorts.md index bf637b5..b962bca 100644 --- a/docs/PluginsClientSidePorts.md +++ b/docs/PluginsClientSidePorts.md @@ -7,7 +7,7 @@ JSON Port of [JSON](http://jollytoad.googlepages.com/json.js) plugin. -``` {.prettyprint} +``` php $jsonString = phpQuery::toJSON( pq('form')->serializeArray() ); $array = phpQuery::parseJSON('{"foo": "bar"}'); ``` diff --git a/docs/PluginsServerSide.md b/docs/PluginsServerSide.md index 03797b1..e82b3a1 100644 --- a/docs/PluginsServerSide.md +++ b/docs/PluginsServerSide.md @@ -7,7 +7,7 @@ Using plugins Plugins are loaded using **plugin** method from phpQueryObject or phpQuery static namespace. -``` {.prettyprint} +``` php // all calls to plugin below are equal phpQuery::plugin('example') phpQuery::plugin('example', 'example.php') @@ -25,7 +25,7 @@ just method calls are forwarded in static way from phpQuery. #### Extending phpQueryObject -``` {.prettyprint} +``` php /** * phpQuery plugin class extending phpQuery object. * Methods from this class are callable on every phpQuery object. @@ -65,7 +65,7 @@ abstract class phpQueryObjectPlugin_example { #### Extending phpQuery -``` {.prettyprint} +``` php /** * phpQuery plugin class extending phpQuery static namespace. * Methods from this class are callable as follows: diff --git a/docs/SVNCheckout.md b/docs/SVNCheckout.md index db2add9..dbe8d76 100644 --- a/docs/SVNCheckout.md +++ b/docs/SVNCheckout.md @@ -1,12 +1,12 @@ #### Checkout latest release -``` {.prettyprint} +``` php svn checkout http://phpquery.googlecode.com/svn/trunk/ phpQuery ``` #### Checkout developer branch -``` {.prettyprint} +``` php svn checkout http://phpquery.googlecode.com/svn/branches/dev/ phpQuery-dev ``` diff --git a/docs/ScriptsPlugin.md b/docs/ScriptsPlugin.md index 789d03a..566ffe3 100644 --- a/docs/ScriptsPlugin.md +++ b/docs/ScriptsPlugin.md @@ -7,7 +7,7 @@ Using scripts Before using any script, you need to load **Scripts** plugin, like so: -``` {.prettyprint} +``` php phpQuery::plugin('Scripts'); // or inside a chain pq('li')->plugin('Scripts'); @@ -15,7 +15,7 @@ pq('li')->plugin('Scripts'); After that, any available script can be used thou **script** method. -``` {.prettyprint} +``` php print pq('div')->script('safe_print'); ``` @@ -35,7 +35,7 @@ By default each script returns \$self aka \$this. ##### Example script -``` {.prettyprint} +``` php $return = $self->find($params[0]); ``` diff --git a/docs/Selectors.md b/docs/Selectors.md index c1d4bae..f8cff06 100644 --- a/docs/Selectors.md +++ b/docs/Selectors.md @@ -5,7 +5,7 @@ implemented (in state same as in jQuery). Example ------- -``` {.prettyprint} +``` php pq(".class ul > li[rel='foo']:first:has(a)")->appendTo('.append-target-wrapper div')->... ``` diff --git a/docs/Traversing.md b/docs/Traversing.md index a461ae8..91de0f7 100644 --- a/docs/Traversing.md +++ b/docs/Traversing.md @@ -1,7 +1,7 @@ Example ------- -``` {.prettyprint} +``` php pq('div > p')->add('div > ul')->filter(':has(a)')->find('p:first')->nextAll()->andSelf()->... ``` diff --git a/docs/WebBrowser.md b/docs/WebBrowser.md index 119fc19..42a5ead 100644 --- a/docs/WebBrowser.md +++ b/docs/WebBrowser.md @@ -27,7 +27,7 @@ Example 1 Adding web browser functionality to existing phpQuery object and submiting the form. -``` {.prettyprint} +``` php ->WebBrowser('callback')->find('form')->submit()->... ``` @@ -36,7 +36,7 @@ Example 2 Querying Google against "search phrase": -``` {.prettyprint} +``` php require_once('phpQuery/phpQuery.php'); phpQuery::browserGet('http://www.google.com/', 'success1'); function success1($browser) { diff --git a/docs/jQueryServer.md b/docs/jQueryServer.md index 6ebc0cc..2086cd2 100644 --- a/docs/jQueryServer.md +++ b/docs/jQueryServer.md @@ -16,7 +16,7 @@ Example scenario Example code ------------ -``` {.prettyprint} +``` php $.server({url: 'http://somesite.com'}) .find('.my-class') .client(function(response){ From 7c6807b4676c710d5caed7e80edb0774e33247fa Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 16:16:15 -0500 Subject: [PATCH 39/59] Eliminated the escape of the php dollar-sign. #9 --- docs/Ajax.md | 42 ++++++++++++++--------------- docs/Attributes.md | 30 ++++++++++----------- docs/Basics.md | 24 ++++++++--------- docs/Events.md | 30 ++++++++++----------- docs/Manipulation.md | 40 +++++++++++++-------------- docs/MultiDocumentSupport.md | 28 +++++++++---------- docs/PHPSupport.md | 52 ++++++++++++++++++------------------ docs/PluginsServerSide.md | 2 +- docs/ScriptsPlugin.md | 10 +++---- docs/Selectors.md | 2 +- docs/Traversing.md | 38 +++++++++++++------------- docs/Utilities.md | 24 ++++++++--------- 12 files changed, 161 insertions(+), 161 deletions(-) diff --git a/docs/Ajax.md b/docs/Ajax.md index a87b2dc..1e93a98 100644 --- a/docs/Ajax.md +++ b/docs/Ajax.md @@ -39,8 +39,8 @@ grant rights to other hosts before making an There are 2 methods for allowing other hosts -- phpQuery::**ajaxAllowURL**(\$url) -- phpQuery::**ajaxAllowHost**(\$host) +- phpQuery::**ajaxAllowURL**($url) +- phpQuery::**ajaxAllowHost**($host) ``` php // connect to google.com @@ -55,51 +55,51 @@ phpQuery::get($url); Ajax Requests ------------- -- **[phpQuery::ajax](http://docs.jquery.com/Ajax/jQuery.ajax)**[(\$options)](http://docs.jquery.com/Ajax/jQuery.ajax) +- **[phpQuery::ajax](http://docs.jquery.com/Ajax/jQuery.ajax)**[($options)](http://docs.jquery.com/Ajax/jQuery.ajax) Load a remote page using an HTTP request. -- **[load](http://docs.jquery.com/Ajax/load)**[(\$url, \$data, - \$callback)](http://docs.jquery.com/Ajax/load) Load HTML from a +- **[load](http://docs.jquery.com/Ajax/load)**[($url, $data, + $callback)](http://docs.jquery.com/Ajax/load) Load HTML from a remote file and inject it into the DOM. -- **[phpQuery::get](http://docs.jquery.com/Ajax/jQuery.get)**[(\$url, - \$data, \$callback)](http://docs.jquery.com/Ajax/jQuery.get) Load a +- **[phpQuery::get](http://docs.jquery.com/Ajax/jQuery.get)**[($url, + $data, $callback)](http://docs.jquery.com/Ajax/jQuery.get) Load a remote page using an HTTP GET request. -- **[phpQuery::getJSON](http://docs.jquery.com/Ajax/jQuery.getJSON)**[(\$url, - \$data, \$callback)](http://docs.jquery.com/Ajax/jQuery.getJSON) +- **[phpQuery::getJSON](http://docs.jquery.com/Ajax/jQuery.getJSON)**[($url, + $data, $callback)](http://docs.jquery.com/Ajax/jQuery.getJSON) Load JSON data using an HTTP GET request. -- **[phpQuery::getScript](http://docs.jquery.com/Ajax/jQuery.getScript)**[(\$url, - \$callback)](http://docs.jquery.com/Ajax/jQuery.getScript) Loads, +- **[phpQuery::getScript](http://docs.jquery.com/Ajax/jQuery.getScript)**[($url, + $callback)](http://docs.jquery.com/Ajax/jQuery.getScript) Loads, and executes, a local JavaScript file using an HTTP GET request. -- **[phpQuery::post](http://docs.jquery.com/Ajax/jQuery.post)**[(\$url, - \$data, \$callback, - \$type)](http://docs.jquery.com/Ajax/jQuery.post) Load a remote page +- **[phpQuery::post](http://docs.jquery.com/Ajax/jQuery.post)**[($url, + $data, $callback, + $type)](http://docs.jquery.com/Ajax/jQuery.post) Load a remote page using an HTTP POST request. Ajax Events ----------- -- **[ajaxComplete](http://docs.jquery.com/Ajax/ajaxComplete)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxComplete) +- **[ajaxComplete](http://docs.jquery.com/Ajax/ajaxComplete)**[($callback)](http://docs.jquery.com/Ajax/ajaxComplete) Attach a function to be executed whenever an AJAX request completes. This is an Ajax Event. -- **[ajaxError](http://docs.jquery.com/Ajax/ajaxError)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxError) +- **[ajaxError](http://docs.jquery.com/Ajax/ajaxError)**[($callback)](http://docs.jquery.com/Ajax/ajaxError) Attach a function to be executed whenever an AJAX request fails. This is an Ajax Event. -- **[ajaxSend](http://docs.jquery.com/Ajax/ajaxSend)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxSend) +- **[ajaxSend](http://docs.jquery.com/Ajax/ajaxSend)**[($callback)](http://docs.jquery.com/Ajax/ajaxSend) Attach a function to be executed before an AJAX request is sent. This is an Ajax Event. -- **[ajaxStart](http://docs.jquery.com/Ajax/ajaxStart)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxStart) +- **[ajaxStart](http://docs.jquery.com/Ajax/ajaxStart)**[($callback)](http://docs.jquery.com/Ajax/ajaxStart) Attach a function to be executed whenever an AJAX request begins and there is none already active. This is an Ajax Event. -- **[ajaxStop](http://docs.jquery.com/Ajax/ajaxStop)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxStop) +- **[ajaxStop](http://docs.jquery.com/Ajax/ajaxStop)**[($callback)](http://docs.jquery.com/Ajax/ajaxStop) Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event. -- **[ajaxSuccess](http://docs.jquery.com/Ajax/ajaxSuccess)**[(\$callback)](http://docs.jquery.com/Ajax/ajaxSuccess) +- **[ajaxSuccess](http://docs.jquery.com/Ajax/ajaxSuccess)**[($callback)](http://docs.jquery.com/Ajax/ajaxSuccess) Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event. Misc ---- -- **[phpQuery::ajaxSetup](http://docs.jquery.com/Ajax/jQuery.ajaxSetup)**[(\$options)](http://docs.jquery.com/Ajax/jQuery.ajaxSetup) +- **[phpQuery::ajaxSetup](http://docs.jquery.com/Ajax/jQuery.ajaxSetup)**[($options)](http://docs.jquery.com/Ajax/jQuery.ajaxSetup) Setup global settings for AJAX requests. - **[serialize](http://docs.jquery.com/Ajax/serialize)**[()](http://docs.jquery.com/Ajax/serialize) Serializes a set of input elements into a string of data. This will diff --git a/docs/Attributes.md b/docs/Attributes.md index d6da149..5c9eb8c 100644 --- a/docs/Attributes.md +++ b/docs/Attributes.md @@ -17,34 +17,34 @@ Table of Contents Attr ---- -- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$name)](http://docs.jquery.com/Attributes/attr) +- **[attr](http://docs.jquery.com/Attributes/attr)**[($name)](http://docs.jquery.com/Attributes/attr) Access a property on the first matched element. This method makes it easy to retrieve a property value from the first matched element. If the element does not have an attribute with such a name, undefined is returned. -- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$properties)](http://docs.jquery.com/Attributes/attr) +- **[attr](http://docs.jquery.com/Attributes/attr)**[($properties)](http://docs.jquery.com/Attributes/attr) Set a key/value object as properties to all matched elements. -- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$key, - \$value)](http://docs.jquery.com/Attributes/attr) Set a single +- **[attr](http://docs.jquery.com/Attributes/attr)**[($key, + $value)](http://docs.jquery.com/Attributes/attr) Set a single property to a value, on all matched elements. -- **[attr](http://docs.jquery.com/Attributes/attr)**[(\$key, - \$fn)](http://docs.jquery.com/Attributes/attr) Set a single property +- **[attr](http://docs.jquery.com/Attributes/attr)**[($key, + $fn)](http://docs.jquery.com/Attributes/attr) Set a single property to a computed value, on all matched elements. -- **[removeAttr](http://docs.jquery.com/Attributes/removeAttr)**[(\$name)](http://docs.jquery.com/Attributes/removeAttr) +- **[removeAttr](http://docs.jquery.com/Attributes/removeAttr)**[($name)](http://docs.jquery.com/Attributes/removeAttr) Remove an attribute from each of the matched elements. Class ----- -- **[addClass](http://docs.jquery.com/Attributes/addClass)**[(\$class)](http://docs.jquery.com/Attributes/addClass) +- **[addClass](http://docs.jquery.com/Attributes/addClass)**[($class)](http://docs.jquery.com/Attributes/addClass) Adds the specified class(es) to each of the set of matched elements. -- **[hasClass](http://docs.jquery.com/Attributes/hasClass)**[(\$class)](http://docs.jquery.com/Attributes/hasClass) +- **[hasClass](http://docs.jquery.com/Attributes/hasClass)**[($class)](http://docs.jquery.com/Attributes/hasClass) Returns true if the specified class is present on at least one of the set of matched elements. -- **[removeClass](http://docs.jquery.com/Attributes/removeClass)**[(\$class)](http://docs.jquery.com/Attributes/removeClass) +- **[removeClass](http://docs.jquery.com/Attributes/removeClass)**[($class)](http://docs.jquery.com/Attributes/removeClass) Removes all or the specified class(es) from the set of matched elements. -- **[toggleClass](http://docs.jquery.com/Attributes/toggleClass)**[(\$class)](http://docs.jquery.com/Attributes/toggleClass) +- **[toggleClass](http://docs.jquery.com/Attributes/toggleClass)**[($class)](http://docs.jquery.com/Attributes/toggleClass) Adds the specified class if it is not present, removes the specified class if it is present. @@ -55,7 +55,7 @@ HTML Get the html contents (innerHTML) of the first matched element. This property is not available on XML documents (although it will work for XHTML documents). -- **[html](http://docs.jquery.com/Attributes/html)**[(\$val)](http://docs.jquery.com/Attributes/html) +- **[html](http://docs.jquery.com/Attributes/html)**[($val)](http://docs.jquery.com/Attributes/html) Set the html contents of every matched element. This property is not available on XML documents (although it will work for XHTML documents). @@ -65,7 +65,7 @@ Text - **[text](http://docs.jquery.com/Attributes/text)**[()](http://docs.jquery.com/Attributes/text) Get the combined text contents of all matched elements. -- **[text](http://docs.jquery.com/Attributes/text)**[(\$val)](http://docs.jquery.com/Attributes/text) +- **[text](http://docs.jquery.com/Attributes/text)**[($val)](http://docs.jquery.com/Attributes/text) Set the text contents of all matched elements. Value @@ -73,9 +73,9 @@ Value - **[val](http://docs.jquery.com/Attributes/val)**[()](http://docs.jquery.com/Attributes/val) Get the content of the value attribute of the first matched element. -- **[val](http://docs.jquery.com/Attributes/val)**[(\$val)](http://docs.jquery.com/Attributes/val) +- **[val](http://docs.jquery.com/Attributes/val)**[($val)](http://docs.jquery.com/Attributes/val) Set the value attribute of every matched element. -- **[val](http://docs.jquery.com/Attributes/val)**[(\$val)](http://docs.jquery.com/Attributes/val) +- **[val](http://docs.jquery.com/Attributes/val)**[($val)](http://docs.jquery.com/Attributes/val) Checks, or selects, all the radio buttons, checkboxes, and select options that match the set of values. diff --git a/docs/Basics.md b/docs/Basics.md index 545f57d..f898c87 100644 --- a/docs/Basics.md +++ b/docs/Basics.md @@ -15,21 +15,21 @@ Table of Contents Loading documents ----------------- -- phpQuery::**newDocument**(\$html, \$contentType = null) Creates new - document from markup. If no \$contentType, autodetection is made +- phpQuery::**newDocument**($html, $contentType = null) Creates new + document from markup. If no $contentType, autodetection is made (based on markup). If it fails, text/html in utf-8 is used. -- phpQuery::**newDocumentFile**(\$file, \$contentType = null) Creates +- phpQuery::**newDocumentFile**($file, $contentType = null) Creates new document from file. Works like newDocument() -- phpQuery::**newDocumentHTML**(\$html, \$charset = 'utf-8') -- phpQuery::**newDocumentXHTML**(\$html, \$charset = 'utf-8') -- phpQuery::**newDocumentXML**(\$html, \$charset = 'utf-8') -- phpQuery::**newDocumentPHP**(\$html, \$contentType = null) Read more +- phpQuery::**newDocumentHTML**($html, $charset = 'utf-8') +- phpQuery::**newDocumentXHTML**($html, $charset = 'utf-8') +- phpQuery::**newDocumentXML**($html, $charset = 'utf-8') +- phpQuery::**newDocumentPHP**($html, $contentType = null) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) -- phpQuery::**newDocumentFileHTML**(\$file, \$charset = 'utf-8') -- phpQuery::**newDocumentFileXHTML**(\$file, \$charset = 'utf-8') -- phpQuery::**newDocumentFileXML**(\$file, \$charset = 'utf-8') -- phpQuery::**newDocumentFilePHP**(\$file, \$contentType) Read more +- phpQuery::**newDocumentFileHTML**($file, $charset = 'utf-8') +- phpQuery::**newDocumentFileXHTML**($file, $charset = 'utf-8') +- phpQuery::**newDocumentFileXML**($file, $charset = 'utf-8') +- phpQuery::**newDocumentFilePHP**($file, $contentType) Read more about it on [PHPSupport page](http://code.google.com/p/phpquery/wiki/PHPSupport) @@ -38,7 +38,7 @@ pq function **`pq($param, $context = null);`** -**pq();** function is equivalent of jQuery's **\$();**. It's used for 3 +**pq();** function is equivalent of jQuery's **$();**. It's used for 3 type of things: 1. Importing markup diff --git a/docs/Events.md b/docs/Events.md index 81b6a59..152539a 100644 --- a/docs/Events.md +++ b/docs/Events.md @@ -32,12 +32,12 @@ will be handled properly - eg submitting form with inputs' data to action URL via new [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. -\$this (`this` in JS) context for handler scope **isn't available**. You +$this (`this` in JS) context for handler scope **isn't available**. You have to use one of following manually: -- \$event-\>**target** -- \$event-\>**currentTarget** -- \$event-\>**relatedTarget** +- $event-\>**target** +- $event-\>**currentTarget** +- $event-\>**relatedTarget** Page Load --------- @@ -47,22 +47,22 @@ Page Load Event Handling -------------- -- **[bind](http://docs.jquery.com/Events/bind)**[(\$type, \$data, - \$fn)](http://docs.jquery.com/Events/bind) Binds a handler to one or +- **[bind](http://docs.jquery.com/Events/bind)**[($type, $data, + $fn)](http://docs.jquery.com/Events/bind) Binds a handler to one or more events (like click) for each matched element. Can also bind custom events. -- **[one](http://docs.jquery.com/Events/one)**[(\$type, \$data, - \$fn)](http://docs.jquery.com/Events/one) Binds a handler to one or +- **[one](http://docs.jquery.com/Events/one)**[($type, $data, + $fn)](http://docs.jquery.com/Events/one) Binds a handler to one or more events to be executed once for each matched element. -- **[trigger](http://docs.jquery.com/Events/trigger)**[(\$type , - \$data )](http://docs.jquery.com/Events/trigger) Trigger a type of +- **[trigger](http://docs.jquery.com/Events/trigger)**[($type , + $data )](http://docs.jquery.com/Events/trigger) Trigger a type of event on every matched element. -- **[triggerHandler](http://docs.jquery.com/Events/triggerHandler)**[(\$type - , \$data )](http://docs.jquery.com/Events/triggerHandler) This +- **[triggerHandler](http://docs.jquery.com/Events/triggerHandler)**[($type + , $data )](http://docs.jquery.com/Events/triggerHandler) This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. -- **[unbind](http://docs.jquery.com/Events/unbind)**[(\$type , \$data +- **[unbind](http://docs.jquery.com/Events/unbind)**[($type , $data )](http://docs.jquery.com/Events/unbind) This does the opposite of bind, it removes bound events from each of the matched elements. @@ -76,11 +76,11 @@ Event Helpers - **[change](http://docs.jquery.com/Events/change)**[()](http://docs.jquery.com/Events/change) Triggers the change event of each matched element. -- **[change](http://docs.jquery.com/Events/change)**[(\$fn)](http://docs.jquery.com/Events/change) +- **[change](http://docs.jquery.com/Events/change)**[($fn)](http://docs.jquery.com/Events/change) Binds a function to the change event of each matched element. - **[submit](http://docs.jquery.com/Events/submit)**[()](http://docs.jquery.com/Events/submit) Trigger the submit event of each matched element. -- **[submit](http://docs.jquery.com/Events/submit)**[(\$fn)](http://docs.jquery.com/Events/submit) +- **[submit](http://docs.jquery.com/Events/submit)**[($fn)](http://docs.jquery.com/Events/submit) Bind a function to the submit event of each matched element. Read more at [Events](http://docs.jquery.com/Events) section on [jQuery diff --git a/docs/Manipulation.md b/docs/Manipulation.md index 53da4d4..1245f08 100644 --- a/docs/Manipulation.md +++ b/docs/Manipulation.md @@ -23,70 +23,70 @@ Changing Contents Get the html contents (innerHTML) of the first matched element. This property is not available on XML documents (although it will work for XHTML documents). -- **[html](http://docs.jquery.com/Manipulation/html)**[(\$val)](http://docs.jquery.com/Manipulation/html) +- **[html](http://docs.jquery.com/Manipulation/html)**[($val)](http://docs.jquery.com/Manipulation/html) Set the html contents of every matched element. This property is not available on XML documents (although it will work for XHTML documents). - **[text](http://docs.jquery.com/Manipulation/text)**[()](http://docs.jquery.com/Manipulation/text) Get the combined text contents of all matched elements. -- **[text](http://docs.jquery.com/Manipulation/text)**[(\$val)](http://docs.jquery.com/Manipulation/text) +- **[text](http://docs.jquery.com/Manipulation/text)**[($val)](http://docs.jquery.com/Manipulation/text) Set the text contents of all matched elements. Inserting Inside ---------------- -- **[append](http://docs.jquery.com/Manipulation/append)**[(\$content)](http://docs.jquery.com/Manipulation/append) +- **[append](http://docs.jquery.com/Manipulation/append)**[($content)](http://docs.jquery.com/Manipulation/append) Append content to the inside of every matched element. -- **[appendTo](http://docs.jquery.com/Manipulation/appendTo)**[(\$content)](http://docs.jquery.com/Manipulation/appendTo) +- **[appendTo](http://docs.jquery.com/Manipulation/appendTo)**[($content)](http://docs.jquery.com/Manipulation/appendTo) Append all of the matched elements to another, specified, set of elements. -- **[prepend](http://docs.jquery.com/Manipulation/prepend)**[(\$content)](http://docs.jquery.com/Manipulation/prepend) +- **[prepend](http://docs.jquery.com/Manipulation/prepend)**[($content)](http://docs.jquery.com/Manipulation/prepend) Prepend content to the inside of every matched element. -- **[prependTo](http://docs.jquery.com/Manipulation/prependTo)**[(\$content)](http://docs.jquery.com/Manipulation/prependTo) +- **[prependTo](http://docs.jquery.com/Manipulation/prependTo)**[($content)](http://docs.jquery.com/Manipulation/prependTo) Prepend all of the matched elements to another, specified, set of elements. Inserting Outside ----------------- -- **[after](http://docs.jquery.com/Manipulation/after)**[(\$content)](http://docs.jquery.com/Manipulation/after) +- **[after](http://docs.jquery.com/Manipulation/after)**[($content)](http://docs.jquery.com/Manipulation/after) Insert content after each of the matched elements. -- **[before](http://docs.jquery.com/Manipulation/before)**[(\$content)](http://docs.jquery.com/Manipulation/before) +- **[before](http://docs.jquery.com/Manipulation/before)**[($content)](http://docs.jquery.com/Manipulation/before) Insert content before each of the matched elements. -- **[insertAfter](http://docs.jquery.com/Manipulation/insertAfter)**[(\$content)](http://docs.jquery.com/Manipulation/insertAfter) +- **[insertAfter](http://docs.jquery.com/Manipulation/insertAfter)**[($content)](http://docs.jquery.com/Manipulation/insertAfter) Insert all of the matched elements after another, specified, set of elements. -- **[insertBefore](http://docs.jquery.com/Manipulation/insertBefore)**[(\$content)](http://docs.jquery.com/Manipulation/insertBefore) +- **[insertBefore](http://docs.jquery.com/Manipulation/insertBefore)**[($content)](http://docs.jquery.com/Manipulation/insertBefore) Insert all of the matched elements before another, specified, set of elements. Inserting Around ---------------- -- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[(\$html)](http://docs.jquery.com/Manipulation/wrap) +- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[($html)](http://docs.jquery.com/Manipulation/wrap) Wrap each matched element with the specified HTML content. -- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[(\$elem)](http://docs.jquery.com/Manipulation/wrap) +- **[wrap](http://docs.jquery.com/Manipulation/wrap)**[($elem)](http://docs.jquery.com/Manipulation/wrap) Wrap each matched element with the specified element. -- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[(\$html)](http://docs.jquery.com/Manipulation/wrapAll) +- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[($html)](http://docs.jquery.com/Manipulation/wrapAll) Wrap all the elements in the matched set into a single wrapper element. -- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[(\$elem)](http://docs.jquery.com/Manipulation/wrapAll) +- **[wrapAll](http://docs.jquery.com/Manipulation/wrapAll)**[($elem)](http://docs.jquery.com/Manipulation/wrapAll) Wrap all the elements in the matched set into a single wrapper element. -- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[(\$html)](http://docs.jquery.com/Manipulation/wrapInner) +- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[($html)](http://docs.jquery.com/Manipulation/wrapInner) Wrap the inner child contents of each matched element (including text nodes) with an HTML structure. -- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[(\$elem)](http://docs.jquery.com/Manipulation/wrapInner) +- **[wrapInner](http://docs.jquery.com/Manipulation/wrapInner)**[($elem)](http://docs.jquery.com/Manipulation/wrapInner) Wrap the inner child contents of each matched element (including text nodes) with a DOM element. Replacing --------- -- **[replaceWith](http://docs.jquery.com/Manipulation/replaceWith)**[(\$content)](http://docs.jquery.com/Manipulation/replaceWith) +- **[replaceWith](http://docs.jquery.com/Manipulation/replaceWith)**[($content)](http://docs.jquery.com/Manipulation/replaceWith) Replaces all matched elements with the specified HTML or DOM elements. -- **[replaceAll](http://docs.jquery.com/Manipulation/replaceAll)**[(\$selector)](http://docs.jquery.com/Manipulation/replaceAll) +- **[replaceAll](http://docs.jquery.com/Manipulation/replaceAll)**[($selector)](http://docs.jquery.com/Manipulation/replaceAll) Replaces the elements matched by the specified selector with the matched elements. @@ -95,7 +95,7 @@ Removing - **[empty](http://docs.jquery.com/Manipulation/empty)**[()](http://docs.jquery.com/Manipulation/empty) Remove all child nodes from the set of matched elements. -- **[remove](http://docs.jquery.com/Manipulation/remove)**[(\$expr)](http://docs.jquery.com/Manipulation/remove) +- **[remove](http://docs.jquery.com/Manipulation/remove)**[($expr)](http://docs.jquery.com/Manipulation/remove) Removes all matched elements from the DOM. Copying @@ -103,7 +103,7 @@ Copying - **[clone](http://docs.jquery.com/Manipulation/clone)**[()](http://docs.jquery.com/Manipulation/clone) Clone matched DOM Elements and select the clones. -- **[clone](http://docs.jquery.com/Manipulation/clone)**[(\$true)](http://docs.jquery.com/Manipulation/clone) +- **[clone](http://docs.jquery.com/Manipulation/clone)**[($true)](http://docs.jquery.com/Manipulation/clone) Clone matched DOM Elements, and all their event handlers, and select the clones. diff --git a/docs/MultiDocumentSupport.md b/docs/MultiDocumentSupport.md index 08f6ab6..55f5074 100644 --- a/docs/MultiDocumentSupport.md +++ b/docs/MultiDocumentSupport.md @@ -56,25 +56,25 @@ pq('li', $doc4); Static Methods -------------- -- phpQuery::**newDocument**(\$html) Creates new document from markup -- phpQuery::**newDocumentFile**(\$file) Creates new document from file -- phpQuery::**getDocument**(\$id = null) Returns phpQueryObject - containing document with id \$id or default document (last +- phpQuery::**newDocument**($html) Creates new document from markup +- phpQuery::**newDocumentFile**($file) Creates new document from file +- phpQuery::**getDocument**($id = null) Returns phpQueryObject + containing document with id $id or default document (last created/selected) -- phpQuery::**selectDocument**(\$id) Sets default document to \$id -- phpQuery::**unloadDocuments**(\$id = null) Unloades all or specified +- phpQuery::**selectDocument**($id) Sets default document to $id +- phpQuery::**unloadDocuments**($id = null) Unloades all or specified document from memory -- phpQuery::**getDocumentID**(\$source) Returns \$source's document ID -- phpQuery::**getDOMDocument**(\$source) Get DOMDocument object - related to \$source +- phpQuery::**getDocumentID**($source) Returns $source's document ID +- phpQuery::**getDOMDocument**($source) Get DOMDocument object + related to $source Object Methods -------------- -- \$pq-\>**getDocument**() Returns object with stack set to document +- $pq-\>**getDocument**() Returns object with stack set to document root -- \$pq-\>**getDocumentID**() Get object's Document ID -- \$pq-\>**getDocumentIDRef**(&\$documentID) Saves object's DocumentID - to \$var by reference -- \$pq-\>**unloadDocument**() Unloads whole document from memory +- $pq-\>**getDocumentID**() Get object's Document ID +- $pq-\>**getDocumentIDRef**(&$documentID) Saves object's DocumentID + to $var by reference +- $pq-\>**unloadDocument**() Unloads whole document from memory diff --git a/docs/PHPSupport.md b/docs/PHPSupport.md index e27e6bc..bade84c 100644 --- a/docs/PHPSupport.md +++ b/docs/PHPSupport.md @@ -82,8 +82,8 @@ PHP Code Support #### Opening PHP files as DOM -PHP files can be opened using **phpQuery::newDocumentPHP(\$markup)** or -**phpQuery::newDocumentFilePHP(\$file)**. Such files are visible as DOM, +PHP files can be opened using **phpQuery::newDocumentPHP($markup)** or +**phpQuery::newDocumentFilePHP($file)**. Such files are visible as DOM, where: - PHP tags beetween DOM elements are available (queryable) as @@ -96,66 +96,66 @@ where: Additional methods allows placing PHP code inside DOM. Below each method visible is it's logic equivalent. -**attrPHP**(\$attr, \$code) +**attrPHP**($attr, $code) -- [attr](http://docs.jquery.com/Attributes/attr)(\$attr, "\") +- [attr](http://docs.jquery.com/Attributes/attr)($attr, "\") -**addClassPHP**(\$code) +**addClassPHP**($code) - [addClass](http://docs.jquery.com/Attributes/addClass)("\") + $code ?\>") -**beforePHP**(\$code) +**beforePHP**($code) -- [before](http://docs.jquery.com/Manipulation/before)("\") -**afterPHP**(\$code) +**afterPHP**($code) -- [after](http://docs.jquery.com/Manipulation/after)("\") -**prependPHP**(\$code) +**prependPHP**($code) - [prepend](http://docs.jquery.com/Manipulation/prepend)("\") + $code ?\>") -**appendPHP**(\$code) +**appendPHP**($code) -- [append](http://docs.jquery.com/Manipulation/append)("\") -**php**(\$code) +**php**($code) -- [html](http://docs.jquery.com/Manipulation/html)("\") -**wrapAllPHP**(\$codeBefore, \$codeAfter) +**wrapAllPHP**($codeBefore, $codeAfter) - [wrapAll](http://docs.jquery.com/Manipulation/wrapAll)("\\") + $codeBefore?\>\") -**wrapPHP**(\$codeBefore, \$codeAfter) +**wrapPHP**($codeBefore, $codeAfter) - [wrap](http://docs.jquery.com/Manipulation/wrap)("\\") + $codeBefore?\>\") -**wrapInnerPHP**(\$codeBefore, \$codeAfter) +**wrapInnerPHP**($codeBefore, $codeAfter) - [wrapInner](http://docs.jquery.com/Manipulation/wrapInner)("\\") + $codeBefore?\>\") -**replaceWithPHP**(\$code) +**replaceWithPHP**($code) - [replaceWith](http://docs.jquery.com/Manipulation/replaceWith)("\") + $code ?\>") #### Outputting PHP code Code inserted with methods above won't be returned as valid (runnable) using classic output methods such as **html()**. To make it work, **php()** method without parameter have to be used. Optionaly -**phpQuery::markupToPHP(\$markup)** can activate tags in string outputed +**phpQuery::markupToPHP($markup)** can activate tags in string outputed before. **REMEMBER** Outputing runnable code and placing it on webserver is always dangerous ! diff --git a/docs/PluginsServerSide.md b/docs/PluginsServerSide.md index e82b3a1..70f0da2 100644 --- a/docs/PluginsServerSide.md +++ b/docs/PluginsServerSide.md @@ -20,7 +20,7 @@ Writing plugins Plugin consist from 2 classes - first extending **phpQueryObjects** (result of pq(); function) and second, extending static -**phpQuery::\$plugins** namespace. Plugin classes are never intialized, +**phpQuery::$plugins** namespace. Plugin classes are never intialized, just method calls are forwarded in static way from phpQuery. #### Extending phpQueryObject diff --git a/docs/ScriptsPlugin.md b/docs/ScriptsPlugin.md index 566ffe3..4772c89 100644 --- a/docs/ScriptsPlugin.md +++ b/docs/ScriptsPlugin.md @@ -25,13 +25,13 @@ Writing scripts Scripts are placed in **/phpQuery/plugins/Scripts**. Each script has it's own file. Each file has access to 4 variables: -- **\$self** Represents \$this -- **\$params** Represents parameters passed to script() method +- **$self** Represents $this +- **$params** Represents parameters passed to script() method (without script name) -- **\$return** If not null, will be used as method result -- **\$config** Content of **config.php file +- **$return** If not null, will be used as method result +- **$config** Content of **config.php file -By default each script returns \$self aka \$this. +By default each script returns $self aka $this. ##### Example script diff --git a/docs/Selectors.md b/docs/Selectors.md index f8cff06..4938caa 100644 --- a/docs/Selectors.md +++ b/docs/Selectors.md @@ -112,7 +112,7 @@ Attribute Filters - **[[attribute\^=value](http://docs.jquery.com/Selectors/attributeStartsWith)]** Matches elements that have the specified attribute and it starts with a certain value. -- **[[attribute\$=value](http://docs.jquery.com/Selectors/attributeEndsWith)]** +- **[[attribute$=value](http://docs.jquery.com/Selectors/attributeEndsWith)]** Matches elements that have the specified attribute and it ends with a certain value. - **http://docs.jquery.com/Selectors/attributeContains [attributeWIKI diff --git a/docs/Traversing.md b/docs/Traversing.md index 91de0f7..0a952f5 100644 --- a/docs/Traversing.md +++ b/docs/Traversing.md @@ -15,64 +15,64 @@ Table of Contents Filtering --------- -- **[eq](http://docs.jquery.com/Traversing/eq)**[(\$index)](http://docs.jquery.com/Traversing/eq) +- **[eq](http://docs.jquery.com/Traversing/eq)**[($index)](http://docs.jquery.com/Traversing/eq) Reduce the set of matched elements to a single element. -- **[hasClass](http://docs.jquery.com/Traversing/hasClass)**[(\$class)](http://docs.jquery.com/Traversing/hasClass) +- **[hasClass](http://docs.jquery.com/Traversing/hasClass)**[($class)](http://docs.jquery.com/Traversing/hasClass) Checks the current selection against a class and returns true, if at least one element of the selection has the given class. -- **[filter](http://docs.jquery.com/Traversing/filter)**[(\$expr)](http://docs.jquery.com/Traversing/filter) +- **[filter](http://docs.jquery.com/Traversing/filter)**[($expr)](http://docs.jquery.com/Traversing/filter) Removes all elements from the set of matched elements that do not match the specified expression(s). -- **[filter](http://docs.jquery.com/Traversing/filter)**[(\$fn)](http://docs.jquery.com/Traversing/filter) +- **[filter](http://docs.jquery.com/Traversing/filter)**[($fn)](http://docs.jquery.com/Traversing/filter) Removes all elements from the set of matched elements that does not match the specified function. -- **[is](http://docs.jquery.com/Traversing/is)**[(\$expr)](http://docs.jquery.com/Traversing/is) +- **[is](http://docs.jquery.com/Traversing/is)**[($expr)](http://docs.jquery.com/Traversing/is) Checks the current selection against an expression and returns true, if at least one element of the selection fits the given expression. -- **[map](http://docs.jquery.com/Traversing/map)**[(\$callback)](http://docs.jquery.com/Traversing/map) +- **[map](http://docs.jquery.com/Traversing/map)**[($callback)](http://docs.jquery.com/Traversing/map) Translate a set of elements in the jQuery object into another set of values in an array (which may, or may not, be elements). -- **[not](http://docs.jquery.com/Traversing/not)**[(\$expr)](http://docs.jquery.com/Traversing/not) +- **[not](http://docs.jquery.com/Traversing/not)**[($expr)](http://docs.jquery.com/Traversing/not) Removes elements matching the specified expression from the set of matched elements. -- **[slice](http://docs.jquery.com/Traversing/slice)**[(\$start, - \$end)](http://docs.jquery.com/Traversing/slice) Selects a subset of +- **[slice](http://docs.jquery.com/Traversing/slice)**[($start, + $end)](http://docs.jquery.com/Traversing/slice) Selects a subset of the matched elements. Finding ------- -- **[add](http://docs.jquery.com/Traversing/add)**[(\$expr)](http://docs.jquery.com/Traversing/add) +- **[add](http://docs.jquery.com/Traversing/add)**[($expr)](http://docs.jquery.com/Traversing/add) Adds more elements, matched by the given expression, to the set of matched elements. -- **[children](http://docs.jquery.com/Traversing/children)**[(\$expr)](http://docs.jquery.com/Traversing/children) +- **[children](http://docs.jquery.com/Traversing/children)**[($expr)](http://docs.jquery.com/Traversing/children) Get a set of elements containing all of the unique immediate children of each of the matched set of elements. - **[contents](http://docs.jquery.com/Traversing/contents)**[()](http://docs.jquery.com/Traversing/contents) Find all the child nodes inside the matched elements (including text nodes), or the content document, if the element is an iframe. -- **[find](http://docs.jquery.com/Traversing/find)**[(\$expr)](http://docs.jquery.com/Traversing/find) +- **[find](http://docs.jquery.com/Traversing/find)**[($expr)](http://docs.jquery.com/Traversing/find) Searches for all elements that match the specified expression. This method is a good way to find additional descendant elements with which to process. -- **[next](http://docs.jquery.com/Traversing/next)**[(\$expr)](http://docs.jquery.com/Traversing/next) +- **[next](http://docs.jquery.com/Traversing/next)**[($expr)](http://docs.jquery.com/Traversing/next) Get a set of elements containing the unique next siblings of each of the given set of elements. -- **[nextAll](http://docs.jquery.com/Traversing/nextAll)**[(\$expr)](http://docs.jquery.com/Traversing/nextAll) +- **[nextAll](http://docs.jquery.com/Traversing/nextAll)**[($expr)](http://docs.jquery.com/Traversing/nextAll) Find all sibling elements after the current element. -- **[parent](http://docs.jquery.com/Traversing/parent)**[(\$expr)](http://docs.jquery.com/Traversing/parent) +- **[parent](http://docs.jquery.com/Traversing/parent)**[($expr)](http://docs.jquery.com/Traversing/parent) Get a set of elements containing the unique parents of the matched set of elements. -- **[parents](http://docs.jquery.com/Traversing/parents)**[(\$expr)](http://docs.jquery.com/Traversing/parents) +- **[parents](http://docs.jquery.com/Traversing/parents)**[($expr)](http://docs.jquery.com/Traversing/parents) Get a set of elements containing the unique ancestors of the matched set of elements (except for the root element). The matched elements can be filtered with an optional expression. -- **[prev](http://docs.jquery.com/Traversing/prev)**[(\$expr)](http://docs.jquery.com/Traversing/prev) +- **[prev](http://docs.jquery.com/Traversing/prev)**[($expr)](http://docs.jquery.com/Traversing/prev) Get a set of elements containing the unique previous siblings of each of the matched set of elements. -- **[prevAll](http://docs.jquery.com/Traversing/prevAll)**[(\$expr)](http://docs.jquery.com/Traversing/prevAll) +- **[prevAll](http://docs.jquery.com/Traversing/prevAll)**[($expr)](http://docs.jquery.com/Traversing/prevAll) Find all sibling elements before the current element. -- **[siblings](http://docs.jquery.com/Traversing/siblings)**[(\$expr)](http://docs.jquery.com/Traversing/siblings) +- **[siblings](http://docs.jquery.com/Traversing/siblings)**[($expr)](http://docs.jquery.com/Traversing/siblings) Get a set of elements containing all of the unique siblings of each of the matched set of elements. Can be filtered with an optional expressions. diff --git a/docs/Utilities.md b/docs/Utilities.md index dbee086..ed41f44 100644 --- a/docs/Utilities.md +++ b/docs/Utilities.md @@ -14,34 +14,34 @@ User Agent Array and Object operations --------------------------- -- **[phpQuery::each](http://docs.jquery.com/Utilities/jQuery.each)**[(\$object, - \$callback)](http://docs.jquery.com/Utilities/jQuery.each) A generic +- **[phpQuery::each](http://docs.jquery.com/Utilities/jQuery.each)**[($object, + $callback)](http://docs.jquery.com/Utilities/jQuery.each) A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. -- **[phpQuery::grep](http://docs.jquery.com/Utilities/jQuery.grep)**[(\$array, - \$callback, \$invert)](http://docs.jquery.com/Utilities/jQuery.grep) +- **[phpQuery::grep](http://docs.jquery.com/Utilities/jQuery.grep)**[($array, + $callback, $invert)](http://docs.jquery.com/Utilities/jQuery.grep) Filter items out of an array, by using a filter function. -- **[phpQuery::makeArray](http://docs.jquery.com/Utilities/jQuery.makeArray)**[(\$obj)](http://docs.jquery.com/Utilities/jQuery.makeArray) +- **[phpQuery::makeArray](http://docs.jquery.com/Utilities/jQuery.makeArray)**[($obj)](http://docs.jquery.com/Utilities/jQuery.makeArray) Turns an array-like object into a true array. -- **[phpQuery::map](http://docs.jquery.com/Utilities/jQuery.map)**[(\$array, - \$callback)](http://docs.jquery.com/Utilities/jQuery.map) Translate +- **[phpQuery::map](http://docs.jquery.com/Utilities/jQuery.map)**[($array, + $callback)](http://docs.jquery.com/Utilities/jQuery.map) Translate all items in an array to another array of items. -- **[phpQuery::inArray](http://docs.jquery.com/Utilities/jQuery.inArray)**[(\$value, - \$array)](http://docs.jquery.com/Utilities/jQuery.inArray) Determine +- **[phpQuery::inArray](http://docs.jquery.com/Utilities/jQuery.inArray)**[($value, + $array)](http://docs.jquery.com/Utilities/jQuery.inArray) Determine the index of the first parameter in the Array (-1 if not found). -- **[phpQuery::unique](http://docs.jquery.com/Utilities/jQuery.unique)**[(\$array)](http://docs.jquery.com/Utilities/jQuery.unique) +- **[phpQuery::unique](http://docs.jquery.com/Utilities/jQuery.unique)**[($array)](http://docs.jquery.com/Utilities/jQuery.unique) Remove all duplicate elements from an array of elements. Test operations --------------- -- **[phpQuery::isFunction](http://docs.jquery.com/Utilities/jQuery.isFunction)**[(\$obj)](http://docs.jquery.com/Utilities/jQuery.isFunction) +- **[phpQuery::isFunction](http://docs.jquery.com/Utilities/jQuery.isFunction)**[($obj)](http://docs.jquery.com/Utilities/jQuery.isFunction) Determine if the parameter passed is a function. String operations ----------------- -- **[phpQuery::trim](http://docs.jquery.com/Utilities/jQuery.trim)**[(\$str)](http://docs.jquery.com/Utilities/jQuery.trim) +- **[phpQuery::trim](http://docs.jquery.com/Utilities/jQuery.trim)**[($str)](http://docs.jquery.com/Utilities/jQuery.trim) Remove the whitespace from the beginning and end of a string. Read more at [Utilities](http://docs.jquery.com/Utilities) section on From 65a416386600379bace4b18e09a794bc462f0870 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 16:24:00 -0500 Subject: [PATCH 40/59] Translate googlecode URLs to md. #9 --- docs/Ajax.md | 3 +-- docs/Basics.md | 6 ++---- docs/Callbacks.md | 3 +-- docs/CommandLineInterface.md | 4 ++-- docs/Events.md | 3 +-- docs/LibrarySections.md | 3 +-- docs/Manual.md | 40 ++++++++++++++++-------------------- docs/PHPSupport.md | 12 +++++------ docs/WebBrowser.md | 7 +++---- docs/jQueryDifferences.md | 2 +- docs/jQueryPortingState.md | 27 +++++++++++------------- docs/jQueryServer.md | 10 ++++----- 12 files changed, 51 insertions(+), 69 deletions(-) diff --git a/docs/Ajax.md b/docs/Ajax.md index 1e93a98..db69355 100644 --- a/docs/Ajax.md +++ b/docs/Ajax.md @@ -34,8 +34,7 @@ Cross Domain Ajax For security reasons, by default **phpQuery** doesn't allow connections to hosts other than actual `$_SERVER['HTTP_HOST']`. Developer needs to -grant rights to other hosts before making an -[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request. +grant rights to other hosts before making an [Ajax](Ajax.md) request. There are 2 methods for allowing other hosts diff --git a/docs/Basics.md b/docs/Basics.md index f898c87..ebccf63 100644 --- a/docs/Basics.md +++ b/docs/Basics.md @@ -24,14 +24,12 @@ Loading documents - phpQuery::**newDocumentXHTML**($html, $charset = 'utf-8') - phpQuery::**newDocumentXML**($html, $charset = 'utf-8') - phpQuery::**newDocumentPHP**($html, $contentType = null) Read more - about it on [PHPSupport - page](http://code.google.com/p/phpquery/wiki/PHPSupport) + about it on [PHPSupport page](PHPSupport.md) - phpQuery::**newDocumentFileHTML**($file, $charset = 'utf-8') - phpQuery::**newDocumentFileXHTML**($file, $charset = 'utf-8') - phpQuery::**newDocumentFileXML**($file, $charset = 'utf-8') - phpQuery::**newDocumentFilePHP**($file, $contentType) Read more - about it on [PHPSupport - page](http://code.google.com/p/phpquery/wiki/PHPSupport) + about it on [PHPSupport page](PHPSupport.md) pq function ----------- diff --git a/docs/Callbacks.md b/docs/Callbacks.md index e12c2b9..e84aeff 100644 --- a/docs/Callbacks.md +++ b/docs/Callbacks.md @@ -15,8 +15,7 @@ What are callbacks ------------------ Callbacks are functions *called back* by other functions in proper -moment (eg on [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) -request error). +moment (eg on [Ajax](Ajax.md) request error). In **JavaScript** this pattern can be very flexible due to [Closures](http://en.wikipedia.org/wiki/Closure_(computer_science)) diff --git a/docs/CommandLineInterface.md b/docs/CommandLineInterface.md index fe3d005..aa2c351 100644 --- a/docs/CommandLineInterface.md +++ b/docs/CommandLineInterface.md @@ -4,13 +4,13 @@ Usage: phpquery URL --method1 arg1 arg2 argN --method2 arg1 arg2 argN ... Example: phpquery 'http://localhost' --find 'div > p' --contents Pipe: cat index.html | phpquery --find 'div > p' --contents -Docs: http://code.google.com/p/phpquery/wiki/ +Docs: ``` Example ------- -Fetch number of downloads of all release packages. +Fetch.md number of downloads of all release packages. ``` php phpquery 'http://code.google.com/p/phpquery/downloads/list?can=1' \ diff --git a/docs/Events.md b/docs/Events.md index 152539a..051f844 100644 --- a/docs/Events.md +++ b/docs/Events.md @@ -29,8 +29,7 @@ client-side ones. On server there isn't, of course, events such as By default, phpQuery automatically fires up only **change** event for form elements. If you load WebBrowser plugin, **submit** and **click** will be handled properly - eg submitting form with inputs' data to -action URL via new [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) -request. +action URL via new [Ajax](Ajax.md) request. $this (`this` in JS) context for handler scope **isn't available**. You have to use one of following manually: diff --git a/docs/LibrarySections.md b/docs/LibrarySections.md index 4510f6d..a59599d 100644 --- a/docs/LibrarySections.md +++ b/docs/LibrarySections.md @@ -1,2 +1 @@ -**Labels:**Deprecated Renamed to -[Manual](http://code.google.com/p/phpquery/wiki/Manual). +**Labels:**Deprecated Renamed to [Manual](Manual.md). diff --git a/docs/Manual.md b/docs/Manual.md index 7608839..6f07162 100644 --- a/docs/Manual.md +++ b/docs/Manual.md @@ -1,36 +1,32 @@ **Labels:**Featured -[Basics](http://code.google.com/p/phpquery/wiki/Basics) +[Basics](Basics.md) -[Ported jQuery -sections](http://code.google.com/p/phpquery/wiki/jQueryPortingState) +[Ported jQuery sections](jQueryPortingState.md) -1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) -2. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) -3. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) -4. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) -5. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) -6. [Events](http://code.google.com/p/phpquery/wiki/Events) -7. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) -8. [Plugin - ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) +1. [Selectors](Selectors.md) +2. [Attributes](Attributes.md) +3. [Traversing](Traversing.md) +4. [Manipulation](Manipulation.md) +5. [Ajax](Ajax.md) +6. [Events](Events.md) +7. [Utilities](Utilities.md) +8. [Plugin ports](PluginsClientSidePorts.md) -[PHP Support](http://code.google.com/p/phpquery/wiki/PHPSupport) +[PHP Support](PHPSupport.md) -[Command Line -Interface](http://code.google.com/p/phpquery/wiki/CommandLineInterface) +[Command Line Interface](CommandLineInterface.md) -[Multi document -support](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) +[Multi document support](MultiDocumentSupport.md) -[Plugins](http://code.google.com/p/phpquery/wiki/PluginsServerSide) +[Plugins](PluginsServerSide.md) -1. [WebBrowser](http://code.google.com/p/phpquery/wiki/WebBrowser) -2. [Scripts](http://code.google.com/p/phpquery/wiki/ScriptsPlugin) +1. [WebBrowser](WebBrowser.md) +2. [Scripts](ScriptsPlugin.md) -[jQueryServer](http://code.google.com/p/phpquery/wiki/jQueryServer) +[jQueryServer](jQueryServer.md) -[Debugging](http://code.google.com/p/phpquery/wiki/Debugging) +[Debugging](Debugging.md) Bootstrap file diff --git a/docs/PHPSupport.md b/docs/PHPSupport.md index bade84c..cbb1a98 100644 --- a/docs/PHPSupport.md +++ b/docs/PHPSupport.md @@ -1,7 +1,6 @@ **Labels:**Featured,Phase-Implementation Although **phpQuery** is a -[jQuery -port](http://code.google.com/p/phpquery/wiki/jQueryPortingState), there -is extensive PHP-specific support. +[jQuery port](jQueryPortingState.md), there is extensive PHP-specific +support. Table of Contents ================= @@ -12,7 +11,7 @@ Table of Contents - [ArrayAccess](#Array_Access) - [Countable Interface](#Countable) -[Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) +[Callbacks](Callbacks.md) [PHP Code Support](#PHP_Code_Support) @@ -73,9 +72,8 @@ print count(pq('ul:first > li')); Callbacks --------- -There is a special -[Callbacks](http://code.google.com/p/phpquery/wiki/Callbacks) wiki -section, to which you should refer to. +There is a special [Callbacks](Callbacks.md) wiki section, to which you +should refer to. PHP Code Support ---------------- diff --git a/docs/WebBrowser.md b/docs/WebBrowser.md index 42a5ead..04254ed 100644 --- a/docs/WebBrowser.md +++ b/docs/WebBrowser.md @@ -1,8 +1,7 @@ **Labels:**Featured,Phase-Implementation,Plugin **WebBrowser** is a -phpQuery -[plugin](http://code.google.com/p/phpquery/wiki/PluginsServerSide) that -mimics behaviors of web browser. Thanks to that developer can simulate -user's behavior inside a PHP script. +phpQuery [plugin](PluginsServerSide.md) that mimics behaviors of web +browser. Thanks to that developer can simulate user's behavior inside a +PHP script. Supported --------- diff --git a/docs/jQueryDifferences.md b/docs/jQueryDifferences.md index 7861b40..50c048b 100644 --- a/docs/jQueryDifferences.md +++ b/docs/jQueryDifferences.md @@ -1,2 +1,2 @@ **Labels:**Deprecated Renamed to -[jQueryPortingState](http://code.google.com/p/phpquery/wiki/jQueryPortingState). +[jQueryPortingState](jQueryPortingState.md). diff --git a/docs/jQueryPortingState.md b/docs/jQueryPortingState.md index edde302..bf0d187 100644 --- a/docs/jQueryPortingState.md +++ b/docs/jQueryPortingState.md @@ -4,15 +4,14 @@ Library](http://jquery.com/). Ported Sections --------------- -1. [Selectors](http://code.google.com/p/phpquery/wiki/Selectors) -2. [Attributes](http://code.google.com/p/phpquery/wiki/Attributes) -3. [Traversing](http://code.google.com/p/phpquery/wiki/Traversing) -4. [Manipulation](http://code.google.com/p/phpquery/wiki/Manipulation) -5. [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) -6. [Events](http://code.google.com/p/phpquery/wiki/Events) -7. [Utilities](http://code.google.com/p/phpquery/wiki/Utilities) -8. [Plugin - ports](http://code.google.com/p/phpquery/wiki/PluginsClientSidePorts) +1. [Selectors](Selectors.md) +2. [Attributes](Attributes.md) +3. [Traversing](Traversing.md) +4. [Manipulation](Manipulation.md) +5. [Ajax](Ajax.md) +6. [Events](Events.md) +7. [Utilities](Utilities.md) +8. [Plugin ports](PluginsClientSidePorts.md) Additional methods ------------------ @@ -28,15 +27,13 @@ phpQuery features many additional methods comparing to jQuery: - reverse() - contentsUnwrap() - switchWith() -- all from - [PHPSupport](http://code.google.com/p/phpquery/wiki/PHPSupport) -- all from [Basic](http://code.google.com/p/phpquery/wiki/Basic) -- all from - [MultiDocumentSupport](http://code.google.com/p/phpquery/wiki/MultiDocumentSupport) +- all from [PHPSupport](PHPSupport.md) +- all from [Basic](Basic.md) +- all from [MultiDocumentSupport](MultiDocumentSupport.md) Other Differences ----------------- - [Server Side - Events](http://code.google.com/p/phpquery/wiki/Events?ts=1225458859&updated=Events#Server_Side_Events) + Events](Events?ts=1225458859&updated=Events#Server_Side_Events.md) diff --git a/docs/jQueryServer.md b/docs/jQueryServer.md index 2086cd2..630003e 100644 --- a/docs/jQueryServer.md +++ b/docs/jQueryServer.md @@ -5,12 +5,10 @@ jQuery. Example scenario ---------------- -1. Connect to server and make an - [Ajax](http://code.google.com/p/phpquery/wiki/Ajax) request to - somewhere ([crossdomain - allowed](http://code.google.com/p/phpquery/wiki/CrossDomainAjax)) +1. Connect to server and make an [Ajax](Ajax.md) request to somewhere + ([crossdomain allowed](CrossDomainAjax.md)) 2. Do some manipulations, you can even trigger a [server-side - event](http://code.google.com/p/phpquery/wiki/Events#Server_Side_Events) + event](Events#Server_Side_Events.md) 3. Get processed date back to the browser Example code @@ -26,4 +24,4 @@ $.server({url: 'http://somesite.com'}) Since version **0.5.1** (this is **not** phpQuery release version number) there is a support for config file which **authorizes** -[Ajax](http://code.google.com/p/phpquery/wiki/Ajax) hosts and referers. +[Ajax](Ajax.md) hosts and referers. From 9ebef0c894dbc3c33c3befc0e8007cbcab0f9dec Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Sun, 9 Mar 2014 16:31:01 -0500 Subject: [PATCH 41/59] Removed empty doc pages. Closes #9. --- docs/CSS.md | 1 - docs/Chains.md | 1 - docs/LibrarySections.md | 1 - docs/ReleasePackages.md | 19 ------------------- docs/jQueryDifferences.md | 2 -- 5 files changed, 24 deletions(-) delete mode 100644 docs/CSS.md delete mode 100644 docs/Chains.md delete mode 100644 docs/LibrarySections.md delete mode 100644 docs/ReleasePackages.md delete mode 100644 docs/jQueryDifferences.md diff --git a/docs/CSS.md b/docs/CSS.md deleted file mode 100644 index 40a6c89..0000000 --- a/docs/CSS.md +++ /dev/null @@ -1 +0,0 @@ -Work in progress. Scheduled before 1.0. diff --git a/docs/Chains.md b/docs/Chains.md deleted file mode 100644 index 4b14c0e..0000000 --- a/docs/Chains.md +++ /dev/null @@ -1 +0,0 @@ -TODO ;) diff --git a/docs/LibrarySections.md b/docs/LibrarySections.md deleted file mode 100644 index a59599d..0000000 --- a/docs/LibrarySections.md +++ /dev/null @@ -1 +0,0 @@ -**Labels:**Deprecated Renamed to [Manual](Manual.md). diff --git a/docs/ReleasePackages.md b/docs/ReleasePackages.md deleted file mode 100644 index e005efc..0000000 --- a/docs/ReleasePackages.md +++ /dev/null @@ -1,19 +0,0 @@ -This page is TODO -================= - -Formats -------- - -- RPM -- ZIP - -Forms ------ - -Standard - -OneFile - -- Broken plugins support ? -- ZendFramework not included - diff --git a/docs/jQueryDifferences.md b/docs/jQueryDifferences.md deleted file mode 100644 index 50c048b..0000000 --- a/docs/jQueryDifferences.md +++ /dev/null @@ -1,2 +0,0 @@ -**Labels:**Deprecated Renamed to -[jQueryPortingState](jQueryPortingState.md). From 9cfd12975d687cf560e67354a9f35e652b926e69 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Thu, 13 Mar 2014 11:07:33 -0500 Subject: [PATCH 42/59] Updated README with project status. --- README.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f17f0b8..c6e25c9 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,22 @@ [![Build Status](https://travis-ci.org/wittiws/phonarc.png?branch=master)](https://travis-ci.org/wittiws/phonarc) -I am using this fork to modernize phpQuery. I am going to adjust folder structures, add namespaces and expand the unit tests. Prior to making those sweeping changes, the code came from a combination of: +## Basic usage of this fork -1. https://github.com/electrolinux/phpquery -2. https://github.com/kevee/phpquery/tree/phpquery-css +```` php +// This gives you the phpQuery object as normally used. +use PhpQuery\PhpQuery as phpQuery; -# Original README from electrolinux +// This creates the pq() function in your namespace. +PhpQuery::use_function(__NAMESPACE__); -## phpQuery, one more fork! +// This creates the pq() function in the global namespace. +PhpQuery::use_function(); +```` -My intent is to have it easily integrated in differents projects, so available on packagist. -I've gathered some fix and new features here and there, as will keep looking for new stuff on github about phpQuery +## About this fork -### github repos i've integrated: +This fork includes several modernizations: * https://github.com/ralph-tice/phpquery (one commit: added WebBrowser->browserDownload) * https://github.com/aptivate/phpquery (three commits) @@ -88,4 +91,12 @@ Source for test.html: ``` - +======= +1. Merged https://github.com/kevee/phpquery/tree/phpquery-css with https://github.com/electrolinux/phpquery +2. Removed CSSParser from this repository and included it via composer +3. Added PhpQuery\ namespace +4. Adjusted the folder structure to reflect usage of PSR-4 +5. Corrected the unit tests and integrated with travis-ci +>>>>>>> Updated README with project status. + +Beyond these adjustments, this project will be minimally maintained. For more phpQuery usage information and fork history, I highly recommend you review the https://github.com/electrolinux/phpquery README. From ef5f7889e5d8516f9e9f0b0fb7f28f8fc0948546 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Thu, 13 Mar 2014 11:11:38 -0500 Subject: [PATCH 43/59] Reflected the fork uniqueness in composer description. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 0906c8d..3222519 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { "name":"wittiws/phpquery", "type":"library", - "description":"phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library", - "version":"0.9.6", + "description":"PHP5.3+ namespaced version of phpQuery with enhanced CSS support", + "version":"0.9.6a", "keywords":[ ] @@ -36,4 +36,4 @@ "PhpQuery\\": "src/" } } -} \ No newline at end of file +} From 01e3fe06c48fcffb6ff0c13dfae2dd53451f99dd Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Tue, 25 Mar 2014 19:52:13 -0500 Subject: [PATCH 44/59] Link to QuipXml. [skip ci] --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c6e25c9..42dc141 100644 --- a/README.md +++ b/README.md @@ -100,3 +100,11 @@ Source for test.html: >>>>>>> Updated README with project status. Beyond these adjustments, this project will be minimally maintained. For more phpQuery usage information and fork history, I highly recommend you review the https://github.com/electrolinux/phpquery README. + +## My Preferred Alternative + +There are several alternatives to phpQuery out there. While several have a healthy adoption rate, I was +looking for a library that leveraged SimpleXML and focused on the PHP use case rather than building all +of the functionality from scratch and adding unnecessarily methods and selectors simply for jQuery +semantic completeness. In the end, I selected to launch a project that attempts to a be a PHP-centric +lightweight wrapper for SimpleXML. [Learn more about QuipXml.](https://github.com/wittiws/quipxml) From 463105d743a3834e66a453bfb093e524d02e3503 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Fri, 11 Apr 2014 16:00:03 -0500 Subject: [PATCH 45/59] Correctly namespacing issues (mainly on exceptions). --- src/Dom/DomDocumentWrapper.php | 8 ++++---- src/PhpQuery.php | 22 +++++++++++----------- src/PhpQueryObject.php | 10 +++++----- src/Plugin/Scripts.php | 2 +- src/Plugin/WebBrowser.php | 4 ++-- src/Proxy/jQueryServer.php | 6 +++--- src/Tests/_archive/test_callback.php | 2 +- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Dom/DomDocumentWrapper.php b/src/Dom/DomDocumentWrapper.php index f2a468b..508babd 100644 --- a/src/Dom/DomDocumentWrapper.php +++ b/src/Dom/DomDocumentWrapper.php @@ -311,7 +311,7 @@ protected function loadMarkupXML($markup, $requestedCharset = null) { return $return; } else { - throw new Exception("Error loading XML markup"); + throw new \Exception("Error loading XML markup"); } } protected function isXHTML($markup = null) { @@ -451,7 +451,7 @@ public function import($source, $sourceCharset = null) { // // string markup // $fake = $this->documentFragmentCreate($node, $sourceCharset); // if ($fake === false) - // throw new Exception("Error loading documentFragment markup"); + // throw new \Exception("Error loading documentFragment markup"); // else // $return = array_merge($return, // $this->import($fake->root->childNodes) @@ -465,7 +465,7 @@ public function import($source, $sourceCharset = null) { // // string markup // $fake = $this->documentFragmentCreate($source, $sourceCharset); // if ($fake === false) - // throw new Exception("Error loading documentFragment markup"); + // throw new \Exception("Error loading documentFragment markup"); // else // return $this->import($fake->root->childNodes); // } @@ -479,7 +479,7 @@ public function import($source, $sourceCharset = null) { // string markup $fake = $this->documentFragmentCreate($source, $sourceCharset); if ($fake === false) - throw new Exception("Error loading documentFragment markup"); + throw new \Exception("Error loading documentFragment markup"); else return $this->import($fake->root->childNodes); } diff --git a/src/PhpQuery.php b/src/PhpQuery.php index f830e77..db49c12 100644 --- a/src/PhpQuery.php +++ b/src/PhpQuery.php @@ -176,7 +176,7 @@ public static function pq($arg1, $context = null) { if (!$context) { $domId = self::$defaultDocumentID; if (!$domId) - throw new Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); + throw new \Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); // } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) } else if (is_object($context) && $context instanceof PhpQueryObject) @@ -184,14 +184,14 @@ public static function pq($arg1, $context = null) { else if ($context instanceof \DOMDocument) { $domId = self::getDocumentID($context); if (!$domId) { - //throw new Exception('Orphaned \DOMDocument'); + //throw new \Exception('Orphaned \DOMDocument'); $domId = self::newDocument($context)->getDocumentID(); } } else if ($context instanceof \DOMNode) { $domId = self::getDocumentID($context); if (!$domId) { - throw new Exception('Orphaned DOMNode'); + throw new \Exception('Orphaned DOMNode'); // $domId = self::newDocument($context->ownerDocument); } } @@ -495,7 +495,7 @@ public static function loadDocument($document) { */ protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) { if (function_exists('domxml_open_mem')) - throw new Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); + throw new \Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); // $id = $documentID // ? $documentID // : md5(microtime()); @@ -539,7 +539,7 @@ public static function extend($target, $source) { $targetRef2 = &self::$pluginsStaticMethods; break; default: - throw new Exception("Unsupported \$target type"); + throw new \Exception("Unsupported \$target type"); } if (is_string($source)) $source = array( @@ -547,12 +547,12 @@ public static function extend($target, $source) { ); foreach ($source as $method => $callback) { if (isset($targetRef[$method])) { - // throw new Exception + // throw new \Exception self::debug("Duplicate method '{$method}', can\'t extend '{$target}'"); continue; } if (isset($targetRef2[$method])) { - // throw new Exception + // throw new \Exception self::debug("Duplicate method '{$method}' from plugin '{$targetRef2[$method]}'," . " can\'t extend '{$target}'"); continue; @@ -596,7 +596,7 @@ public static function plugin($class, $file = null) { ))) continue; if (isset(self::$pluginsStaticMethods[$method])) { - throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" + throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" . self::$pluginsStaticMethods[$method] . "'"); return; } @@ -622,7 +622,7 @@ public static function plugin($class, $file = null) { ))) continue; if (isset(self::$pluginsMethods[$method])) { - throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" + throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" . self::$pluginsMethods[$method] . "'"); continue; } @@ -726,7 +726,7 @@ public static function ajax($options = array(), $xhr = null) { self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST']; $host = parse_url($options['url'], PHP_URL_HOST); if (!in_array($host, self::$ajaxAllowedHosts)) { - throw new Exception("Request not permitted, host '$host' not present in " + throw new \Exception("Request not permitted, host '$host' not present in " . "phpQuery::\$ajaxAllowedHosts"); } // JSONP @@ -1377,7 +1377,7 @@ public function __call($method, $args) { return isset($return) ? $return : $this; } else - throw new Exception("Method '{$method}' doesnt exist"); + throw new \Exception("Method '{$method}' doesnt exist"); } } // // add plugins dir and Zend framework to include path diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php index de7e75d..759d443 100644 --- a/src/PhpQueryObject.php +++ b/src/PhpQueryObject.php @@ -109,7 +109,7 @@ public function __construct($documentID) { // var_dump($id); if (!isset(phpQuery::$documents[$id])) { // var_dump(phpQuery::$documents); - throw new Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); + throw new \Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); } $this->documentID = $id; $this->documentWrapper = &phpQuery::$documents[$id]; @@ -2395,14 +2395,14 @@ public function insert($target, $type) { case 'insertBefore': case 'before': if (!$toNode->parentNode) - throw new Exception("No parentNode, can't do {$type}()"); + throw new \Exception("No parentNode, can't do {$type}()"); else $toNode->parentNode->insertBefore($insert, $toNode); break; case 'insertAfter': case 'after': if (!$toNode->parentNode) - throw new Exception("No parentNode, can't do {$type}()"); + throw new \Exception("No parentNode, can't do {$type}()"); else $toNode->parentNode->insertBefore($insert, $nextSibling); break; @@ -2557,7 +2557,7 @@ public function __call($method, $args) { ), $args); } else - throw new Exception("Method '{$method}' doesnt exist"); + throw new \Exception("Method '{$method}' doesnt exist"); } /** * Safe rename of next(). @@ -3305,7 +3305,7 @@ public function offsetSet($offset, $value) { */ public function offsetUnset($offset) { // empty - throw new Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); + throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); } // ARRAYACCESS INTERFACE END /** diff --git a/src/Plugin/Scripts.php b/src/Plugin/Scripts.php index b7b1f8c..b2ded0a 100644 --- a/src/Plugin/Scripts.php +++ b/src/Plugin/Scripts.php @@ -65,7 +65,7 @@ public static function __initialize() { */ public static function script($name, $callback) { if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name]) - throw new Exception("Script name conflict - '$name'"); + throw new \Exception("Script name conflict - '$name'"); \PhpQuery\Plugin\UtilScripts::$scriptMethods[$name] = $callback; } } diff --git a/src/Plugin/WebBrowser.php b/src/Plugin/WebBrowser.php index 75568e5..e225161 100644 --- a/src/Plugin/WebBrowser.php +++ b/src/Plugin/WebBrowser.php @@ -25,7 +25,7 @@ public static function WebBrowser($self, $callback = null, $location = null) { // FIXME tmp $self->document->WebBrowserCallback = $callback; if (! $location) - throw new Exception('Location needed to activate WebBrowser plugin !'); + throw new \Exception('Location needed to activate WebBrowser plugin !'); else { $self->bind('click', array($location, $callback), array('\PhpQuery\Plugin\UtilWebBrowser', 'hadleClick')); $self->bind('submit', array($location, $callback), array('\PhpQuery\Plugin\UtilWebBrowser', 'handleSubmit')); @@ -139,7 +139,7 @@ public static function browserGet($url, $callback, // )); return $xhr; } else { - throw new Exception("[WebBrowser] GET request failed; url: $url"); + throw new \Exception("[WebBrowser] GET request failed; url: $url"); return false; } } diff --git a/src/Proxy/jQueryServer.php b/src/Proxy/jQueryServer.php index 1b4cb1b..58624fa 100755 --- a/src/Proxy/jQueryServer.php +++ b/src/Proxy/jQueryServer.php @@ -41,7 +41,7 @@ function __construct($data) { $authorized = $referer && in_array($referer, $this->config['allowedRefererHosts']); if (!$authorized) { - throw new Exception("Host '{$_SERVER['HTTP_REFERER']}' not authorized to make requests."); + throw new \Exception("Host '{$_SERVER['HTTP_REFERER']}' not authorized to make requests."); return; } } @@ -64,7 +64,7 @@ function __construct($data) { phpQuery::ajax($ajax); } else { - throw new Exception("URL needed to download content"); + throw new \Exception("URL needed to download content"); } } public function success($response) { @@ -72,7 +72,7 @@ public function success($response) { foreach ($this->calls as $k => $r) { // check if method exists if (!method_exists(get_class($pq), $r['method'])) { - throw new Exception("Method '{$r['method']}' not implemented in phpQuery, sorry..."); + throw new \Exception("Method '{$r['method']}' not implemented in phpQuery, sorry..."); // execute method } else { diff --git a/src/Tests/_archive/test_callback.php b/src/Tests/_archive/test_callback.php index 0dace99..d38df8a 100644 --- a/src/Tests/_archive/test_callback.php +++ b/src/Tests/_archive/test_callback.php @@ -1,6 +1,6 @@ Date: Fri, 23 May 2014 21:14:49 +0400 Subject: [PATCH 46/59] multiple error fixes --- src/Dom/DomDocumentWrapper.php | 1423 ++--- src/Dom/DomEvent.php | 205 +- src/PhpQuery.php | 2816 +++++---- src/PhpQueryEvents.php | 318 +- src/PhpQueryObject.php | 7239 ++++++++++++----------- src/Plugin/Scripts.php | 51 +- src/Plugin/Scripts/__config.example.php | 3 +- src/Plugin/Scripts/example.php | 3 +- src/Plugin/Scripts/google_login.php | 5 +- src/Plugin/WebBrowser.php | 109 +- src/bootstrap.php | 49 +- 11 files changed, 6598 insertions(+), 5623 deletions(-) diff --git a/src/Dom/DomDocumentWrapper.php b/src/Dom/DomDocumentWrapper.php index 508babd..f056ce9 100644 --- a/src/Dom/DomDocumentWrapper.php +++ b/src/Dom/DomDocumentWrapper.php @@ -1,5 +1,6 @@ changes to
    * - * @todo check XML catalogs compatibility - * @author Tobiasz Cudnik + * @todo check XML catalogs compatibility + * @author Tobiasz Cudnik * @package phpQuery */ -class DOMDocumentWrapper { - /** - * @var \DOMDocument - */ - public $document; - public $id; - /** - * @todo Rewrite as method and quess if null. - * @var unknown_type - */ - public $contentType = ''; - public $xpath; - public $uuid = 0; - public $data = array(); - public $dataNodes = array(); - public $events = array(); - public $eventsNodes = array(); - public $eventsGlobal = array(); - /** - * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28 - * @var unknown_type - */ - public $frames = array(); - /** - * Document root, by default equals to document itself. - * Used by documentFragments. - * - * @var \DOMNode - */ - public $root; - public $isDocumentFragment; - public $isXML = false; - public $isXHTML = false; - public $isHTML = false; - public $charset; - public function __construct($markup = null, $contentType = null, $newDocumentID = null) { - if (isset($markup)) - $this->load($markup, $contentType, $newDocumentID); - $this->id = $newDocumentID ? $newDocumentID : md5(microtime()); - } - public function load($markup, $contentType = null, $newDocumentID = null) { - // phpQuery::$documents[$id] = $this; - $this->contentType = strtolower($contentType); - if ($markup instanceof \DOMDocument) { - $this->document = $markup; - $this->root = $this->document; - $this->charset = $this->document->encoding; - // TODO isDocumentFragment - $loaded = true; - } - else { - $loaded = $this->loadMarkup($markup); - } - if ($loaded) { - // $this->document->formatOutput = true; - $this->document->preserveWhiteSpace = true; - $this->xpath = new \DOMXPath($this->document); - $this->afterMarkupLoad(); - return true; - // remember last loaded document - // return phpQuery::selectDocument($id); - } - return false; - } - protected function afterMarkupLoad() { - if ($this->isXHTML) { - $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml"); - } - } - protected function loadMarkup($markup) { - $loaded = false; - if ($this->contentType) { - self::debug("Load markup for content type {$this->contentType}"); - // content determined by contentType - list($contentType, $charset) = $this->contentTypeToArray($this->contentType); - switch ($contentType) { - case 'text/html': - phpQuery::debug("Loading HTML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupHTML($markup, $charset); - break; - case 'text/xml': - case 'application/xhtml+xml': - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupXML($markup, $charset); - break; - default: - // for feeds or anything that sometimes doesn't use text/xml - if (strpos('xml', $this->contentType) !== false) { - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); - $loaded = $this->loadMarkupXML($markup, $charset); - } - else - phpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); - } - } - else { - // content type autodetection - if ($this->isXML($markup)) { - phpQuery::debug("Loading XML, isXML() == true"); - $loaded = $this->loadMarkupXML($markup); - if (!$loaded && $this->isXHTML) { - phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); - $loaded = $this->loadMarkupHTML($markup); - } - } - else { - phpQuery::debug("Loading HTML, isXML() == false"); - $loaded = $this->loadMarkupHTML($markup); - } - } - return $loaded; - } - protected function loadMarkupReset() { - $this->isXML = $this->isXHTML = $this->isHTML = false; - } - protected function documentCreate($charset, $version = '1.0') { - if (!$version) - $version = '1.0'; - $this->document = new \DOMDocument($version, $charset); - $this->charset = $this->document->encoding; - // $this->document->encoding = $charset; - $this->document->formatOutput = true; - $this->document->preserveWhiteSpace = true; - } - protected function loadMarkupHTML($markup, $requestedCharset = null) { - if (phpQuery::$debug) - phpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250)); - $this->loadMarkupReset(); - $this->isHTML = true; - if (!isset($this->isDocumentFragment)) - $this->isDocumentFragment = self::isDocumentFragmentHTML($markup); - $charset = null; - $documentCharset = $this->charsetFromHTML($markup); - $addDocumentCharset = false; - if ($documentCharset) { - $charset = $documentCharset; - $markup = $this->charsetFixHTML($markup); - } - else if ($requestedCharset) { - $charset = $requestedCharset; +class DOMDocumentWrapper +{ + /** + * @var \DOMDocument + */ + public $document; + public $id; + /** + * @todo Rewrite as method and quess if null. + * @var unknown_type + */ + public $contentType = ''; + public $xpath; + public $uuid = 0; + public $data = array(); + public $dataNodes = array(); + public $events = array(); + public $eventsNodes = array(); + public $eventsGlobal = array(); + /** + * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28 + * @var unknown_type + */ + public $frames = array(); + /** + * Document root, by default equals to document itself. + * Used by documentFragments. + * + * @var \DOMNode + */ + public $root; + public $isDocumentFragment; + public $isXML = false; + public $isXHTML = false; + public $isHTML = false; + public $charset; + + public function __construct($markup = null, $contentType = null, $newDocumentID = null) + { + if (isset($markup)) { + $this->load($markup, $contentType, $newDocumentID); + } + $this->id = $newDocumentID ? $newDocumentID : md5(microtime()); } - if (!$charset) - $charset = phpQuery::$defaultCharset; - // HTTP 1.1 says that the default charset is ISO-8859-1 - // @see http://www.w3.org/International/O-HTTP-charset - if (!$documentCharset) { - $documentCharset = 'ISO-8859-1'; - $addDocumentCharset = true; + + public function load($markup, $contentType = null, $newDocumentID = null) + { + // phpQuery::$documents[$id] = $this; + $this->contentType = strtolower($contentType); + if ($markup instanceof \DOMDocument) { + $this->document = $markup; + $this->root = $this->document; + $this->charset = $this->document->encoding; + // TODO isDocumentFragment + $loaded = true; + } else { + $loaded = $this->loadMarkup($markup); + } + if ($loaded) { + // $this->document->formatOutput = true; + $this->document->preserveWhiteSpace = true; + $this->xpath = new \DOMXPath($this->document); + $this->afterMarkupLoad(); + return true; + // remember last loaded document + // return phpQuery::selectDocument($id); + } + return false; } - // Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding' - // Worse, some pages can have mixed encodings... we'll try not to worry about that - $requestedCharset = strtoupper($requestedCharset); - $documentCharset = strtoupper($documentCharset); - phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); - if ($requestedCharset && $documentCharset - && $requestedCharset !== $documentCharset) { - phpQuery::debug("CHARSET CONVERT"); - // Document Encoding Conversion - // http://code.google.com/p/phpquery/issues/detail?id=86 - if (function_exists('mb_detect_encoding')) { - $possibleCharsets = array( - $documentCharset, - $requestedCharset, - 'AUTO' - ); - $docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets)); - if (!$docEncoding) - $docEncoding = $documentCharset; - // ok trust the document - phpQuery::debug("DETECTED '$docEncoding'"); - // Detected does not match what document says... - if ($docEncoding !== $documentCharset) { - // Tricky.. - } - if ($docEncoding !== $requestedCharset) { - phpQuery::debug("CONVERT $docEncoding => $requestedCharset"); - $markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding); - $markup = $this->charsetAppendToHTML($markup, $requestedCharset); - $charset = $requestedCharset; - } - } - else { - phpQuery::debug("TODO: charset conversion without mbstring..."); - } + + protected function afterMarkupLoad() + { + if ($this->isXHTML) { + $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml"); + } } - $return = false; - if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); - $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + + protected function loadMarkup($markup) + { + $loaded = false; + if ($this->contentType) { + self::debug("Load markup for content type {$this->contentType}"); + // content determined by contentType + list($contentType, $charset) = $this->contentTypeToArray($this->contentType); + switch ($contentType) { + case 'text/html': + phpQuery::debug("Loading HTML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupHTML($markup, $charset); + break; + case 'text/xml': + case 'application/xhtml+xml': + phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupXML($markup, $charset); + break; + default: + // for feeds or anything that sometimes doesn't use text/xml + if (strpos('xml', $this->contentType) !== false) { + phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + $loaded = $this->loadMarkupXML($markup, $charset); + } else { + phpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); + } + } + } else { + // content type autodetection + if ($this->isXML($markup)) { + phpQuery::debug("Loading XML, isXML() == true"); + $loaded = $this->loadMarkupXML($markup); + if (!$loaded && $this->isXHTML) { + phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); + $loaded = $this->loadMarkupHTML($markup); + } + } else { + phpQuery::debug("Loading HTML, isXML() == false"); + $loaded = $this->loadMarkupHTML($markup); + } + } + return $loaded; } - else { - if ($addDocumentCharset) { - phpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); - $markup = $this->charsetAppendToHTML($markup, $charset); - } - phpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); - $this->documentCreate($charset); - $return = phpQuery::$debug === 2 ? $this->document->loadHTML($markup) - : @$this->document->loadHTML($markup); - if ($return) - $this->root = $this->document; + + protected function loadMarkupReset() + { + $this->isXML = $this->isXHTML = $this->isHTML = false; } - if ($return && !$this->contentType) - $this->contentType = 'text/html'; - return $return; - } - protected function loadMarkupXML($markup, $requestedCharset = null) { - if (phpQuery::$debug) - phpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250)); - $this->loadMarkupReset(); - $this->isXML = true; - // check agains XHTML in contentType or markup - $isContentTypeXHTML = $this->isXHTML(); - $isMarkupXHTML = $this->isXHTML($markup); - if ($isContentTypeXHTML || $isMarkupXHTML) { - self::debug('Full markup load (XML), XHTML detected'); - $this->isXHTML = true; + + protected function documentCreate($charset, $version = '1.0') + { + if (!$version) { + $version = '1.0'; + } + $this->document = new \DOMDocument($version, $charset); + $this->charset = $this->document->encoding; + // $this->document->encoding = $charset; + $this->document->formatOutput = true; + $this->document->preserveWhiteSpace = true; } - // determine document fragment - if (!isset($this->isDocumentFragment)) - $this->isDocumentFragment = $this->isXHTML ? self::isDocumentFragmentXHTML($markup) - : self::isDocumentFragmentXML($markup); - // this charset will be used - $charset = null; - // charset from XML declaration @var string - $documentCharset = $this->charsetFromXML($markup); - if (!$documentCharset) { - if ($this->isXHTML) { - // this is XHTML, try to get charset from content-type meta header - $documentCharset = $this->charsetFromHTML($markup); + + protected function loadMarkupHTML($markup, $requestedCharset = null) + { + if (phpQuery::$debug) { + phpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250)); + } + $this->loadMarkupReset(); + $this->isHTML = true; + if (!isset($this->isDocumentFragment)) { + $this->isDocumentFragment = self::isDocumentFragmentHTML($markup); + } + $charset = null; + $documentCharset = $this->charsetFromHTML($markup); + $addDocumentCharset = false; if ($documentCharset) { - phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); - $this->charsetAppendToXML($markup, $documentCharset); - $charset = $documentCharset; - } - } - if (!$documentCharset) { - // if still no document charset... - $charset = $requestedCharset; - } - } - else if ($requestedCharset) { - $charset = $requestedCharset; - } - if (!$charset) { - $charset = phpQuery::$defaultCharset; - } - if ($requestedCharset && $documentCharset - && $requestedCharset != $documentCharset) { - // TODO place for charset conversion - // $charset = $requestedCharset; - } - $return = false; - if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); - $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + $charset = $documentCharset; + $markup = $this->charsetFixHTML($markup); + } else { + if ($requestedCharset) { + $charset = $requestedCharset; + } + } + if (!$charset) { + $charset = phpQuery::$defaultCharset; + } + // HTTP 1.1 says that the default charset is ISO-8859-1 + // @see http://www.w3.org/International/O-HTTP-charset + if (!$documentCharset) { + $documentCharset = 'ISO-8859-1'; + $addDocumentCharset = true; + } + // Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding' + // Worse, some pages can have mixed encodings... we'll try not to worry about that + $requestedCharset = strtoupper($requestedCharset); + $documentCharset = strtoupper($documentCharset); + phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); + if ($requestedCharset && $documentCharset + && $requestedCharset !== $documentCharset + ) { + phpQuery::debug("CHARSET CONVERT"); + // Document Encoding Conversion + // http://code.google.com/p/phpquery/issues/detail?id=86 + if (function_exists('mb_detect_encoding')) { + $possibleCharsets = array( + $documentCharset, + $requestedCharset, + 'AUTO' + ); + $docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets)); + if (!$docEncoding) { + $docEncoding = $documentCharset; + } + // ok trust the document + phpQuery::debug("DETECTED '$docEncoding'"); + // Detected does not match what document says... + if ($docEncoding !== $documentCharset) { + // Tricky.. + } + if ($docEncoding !== $requestedCharset) { + phpQuery::debug("CONVERT $docEncoding => $requestedCharset"); + $markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding); + $markup = $this->charsetAppendToHTML($markup, $requestedCharset); + $charset = $requestedCharset; + } + } else { + phpQuery::debug("TODO: charset conversion without mbstring..."); + } + } + $return = false; + if ($this->isDocumentFragment) { + phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); + $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + } else { + if ($addDocumentCharset) { + phpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); + $markup = $this->charsetAppendToHTML($markup, $charset); + } + phpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); + $this->documentCreate($charset); + $return = phpQuery::$debug === 2 ? $this->document->loadHTML($markup) + : @$this->document->loadHTML($markup); + if ($return) { + $this->root = $this->document; + } + } + if ($return && !$this->contentType) { + $this->contentType = 'text/html'; + } + return $return; } - else { - // FIXME ??? - if ($isContentTypeXHTML && !$isMarkupXHTML) + + protected function loadMarkupXML($markup, $requestedCharset = null) + { + if (phpQuery::$debug) { + phpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250)); + } + $this->loadMarkupReset(); + $this->isXML = true; + // check agains XHTML in contentType or markup + $isContentTypeXHTML = $this->isXHTML(); + $isMarkupXHTML = $this->isXHTML($markup); + if ($isContentTypeXHTML || $isMarkupXHTML) { + self::debug('Full markup load (XML), XHTML detected'); + $this->isXHTML = true; + } + // determine document fragment + if (!isset($this->isDocumentFragment)) { + $this->isDocumentFragment = $this->isXHTML ? self::isDocumentFragmentXHTML($markup) + : self::isDocumentFragmentXML($markup); + } + // this charset will be used + $charset = null; + // charset from XML declaration @var string + $documentCharset = $this->charsetFromXML($markup); if (!$documentCharset) { - phpQuery::debug("Full markup load (XML), appending charset '$charset'"); - $markup = $this->charsetAppendToXML($markup, $charset); - } - // see http://pl2.php.net/manual/en/book.dom.php#78929 - // LIBXML_DTDLOAD (>= PHP 5.1) - // does XML ctalogues works with LIBXML_NONET - // $this->document->resolveExternals = true; - // TODO test LIBXML_COMPACT for performance improvement - // create document - $this->documentCreate($charset); - if (phpversion() < 5.1) { - $this->document->resolveExternals = true; - $return = phpQuery::$debug === 2 ? $this->document->loadXML($markup) - : @$this->document->loadXML($markup); - } - else { - /** @link http://pl2.php.net/manual/en/libxml.constants.php */ - $libxmlStatic = phpQuery::$debug === 2 ? LIBXML_DTDLOAD - | LIBXML_DTDATTR | LIBXML_NONET - : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING - | LIBXML_NOERROR; - $return = $this->document->loadXML($markup, $libxmlStatic); - // if (! $return) - // $return = $this->document->loadHTML($markup); - } - if ($return) - $this->root = $this->document; + if ($this->isXHTML) { + // this is XHTML, try to get charset from content-type meta header + $documentCharset = $this->charsetFromHTML($markup); + if ($documentCharset) { + phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); + $this->charsetAppendToXML($markup, $documentCharset); + $charset = $documentCharset; + } + } + if (!$documentCharset) { + // if still no document charset... + $charset = $requestedCharset; + } + } else { + if ($requestedCharset) { + $charset = $requestedCharset; + } + } + if (!$charset) { + $charset = phpQuery::$defaultCharset; + } + if ($requestedCharset && $documentCharset + && $requestedCharset != $documentCharset + ) { + // TODO place for charset conversion + // $charset = $requestedCharset; + } + $return = false; + if ($this->isDocumentFragment) { + phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); + $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); + } else { + // FIXME ??? + if ($isContentTypeXHTML && !$isMarkupXHTML) { + if (!$documentCharset) { + phpQuery::debug("Full markup load (XML), appending charset '$charset'"); + $markup = $this->charsetAppendToXML($markup, $charset); + } + } + // see http://pl2.php.net/manual/en/book.dom.php#78929 + // LIBXML_DTDLOAD (>= PHP 5.1) + // does XML ctalogues works with LIBXML_NONET + // $this->document->resolveExternals = true; + // TODO test LIBXML_COMPACT for performance improvement + // create document + $this->documentCreate($charset); + if (phpversion() < 5.1) { + $this->document->resolveExternals = true; + $return = phpQuery::$debug === 2 ? $this->document->loadXML($markup) + : @$this->document->loadXML($markup); + } else { + /** @link http://pl2.php.net/manual/en/libxml.constants.php */ + $libxmlStatic = phpQuery::$debug === 2 ? LIBXML_DTDLOAD + | LIBXML_DTDATTR | LIBXML_NONET + : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING + | LIBXML_NOERROR; + $return = $this->document->loadXML($markup, $libxmlStatic); + // if (! $return) + // $return = $this->document->loadHTML($markup); + } + if ($return) { + $this->root = $this->document; + } + } + if ($return) { + if (!$this->contentType) { + if ($this->isXHTML) { + $this->contentType = 'application/xhtml+xml'; + } else { + $this->contentType = 'text/xml'; + } + } + return $return; + } else { + throw new \Exception("Error loading XML markup"); + } } - if ($return) { - if (!$this->contentType) { - if ($this->isXHTML) - $this->contentType = 'application/xhtml+xml'; - else - $this->contentType = 'text/xml'; - } - return $return; + + protected function isXHTML($markup = null) + { + if (!isset($markup)) { + return strpos($this->contentType, 'xhtml') !== false; + } + // XXX ok ? + return strpos($markup, "doctype) && is_object($dom->doctype) + // ? $dom->doctype->publicId + // : self::$defaultDoctype; } - else { - throw new \Exception("Error loading XML markup"); + + protected function isXML($markup) + { + // return strpos($markup, 'contentType, 'xhtml') !== false; + + protected function contentTypeToArray($contentType) + { + $test = null; + $test = $matches = explode(';', trim(strtolower($contentType))); + if (isset($matches[1])) { + $matches[1] = explode('=', $matches[1]); + // strip 'charset=' + $matches[1] = isset($matches[1][1]) && trim($matches[1][1]) ? $matches[1][1] + : $matches[1][0]; + } else { + $matches[1] = null; + } + return $matches; } - // XXX ok ? - return strpos($markup, "doctype) && is_object($dom->doctype) - // ? $dom->doctype->publicId - // : self::$defaultDoctype; - } - protected function isXML($markup) { - // return strpos($markup, ']+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches); + if (!isset($matches[0])) { + return array( + null, + null + ); + } + // get attr 'content' + preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches); + if (!isset($matches[0])) { + return array( + null, + null + ); + } + return $this->contentTypeToArray($matches[2]); } - else - $matches[1] = null; - return $matches; - } - /** - * - * @param $markup - * @return array contentType, charset - */ - protected function contentTypeFromHTML($markup) { - $matches = array(); - // find meta tag - preg_match('@]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches); - if (!isset($matches[0])) - return array( - null, - null - ); - // get attr 'content' - preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches); - if (!isset($matches[0])) - return array( - null, - null - ); - return $this->contentTypeToArray($matches[2]); - } - protected function charsetFromHTML($markup) { - $contentType = $this->contentTypeFromHTML($markup); - return $contentType[1]; - } - protected function charsetFromXML($markup) { - $matches; - // find declaration - preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches); - return isset($matches[2]) ? strtolower($matches[2]) : null; - } - /** - * Repositions meta[type=charset] at the start of head. Bypasses \DOMDocument bug. - * - * @link http://code.google.com/p/phpquery/issues/detail?id=80 - * @param $html - */ - protected function charsetFixHTML($markup) { - $matches = array(); - // find meta tag - preg_match('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches, PREG_OFFSET_CAPTURE); - if (!isset($matches[0])) - return; - $metaContentType = $matches[0][0]; - $markup = substr($markup, 0, $matches[0][1]) - . substr($markup, $matches[0][1] + strlen($metaContentType)); - $headStart = stripos($markup, ''); - $markup = substr($markup, 0, $headStart + 6) . $metaContentType - . substr($markup, $headStart + 6); - return $markup; - } - protected function charsetAppendToHTML($html, $charset, $xhtml = false) { - // remove existing meta[type=content-type] - $html = preg_replace('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html); - $meta = ''; - if (strpos($html, ')@s', "{$meta}", $html); - } + + protected function charsetFromHTML($markup) + { + $contentType = $this->contentTypeFromHTML($markup); + return $contentType[1]; } - else { - return preg_replace('@)@s', '' . $meta, $html); + + protected function charsetFromXML($markup) + { + $matches; + // find declaration + preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches); + return isset($matches[2]) ? strtolower($matches[2]) : null; } - } - protected function charsetAppendToXML($markup, $charset) { - $declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?' - . '>'; - return $declaration . $markup; - } - public static function isDocumentFragmentHTML($markup) { - return stripos($markup, 'documentFragmentCreate($node, $sourceCharset); - // if ($fake === false) - // throw new \Exception("Error loading documentFragment markup"); - // else - // $return = array_merge($return, - // $this->import($fake->root->childNodes) - // ); - // } else { - // $return[] = $this->document->importNode($node, true); - // } - // } - // return $return; - // } else { - // // string markup - // $fake = $this->documentFragmentCreate($source, $sourceCharset); - // if ($fake === false) - // throw new \Exception("Error loading documentFragment markup"); - // else - // return $this->import($fake->root->childNodes); - // } - if (is_array($source) || $source instanceof \DOMNodeList) { - // dom nodes - self::debug('Importing nodes to document'); - foreach ($source as $node) - $return[] = $this->document->importNode($node, true); + + /** + * Repositions meta[type=charset] at the start of head. Bypasses \DOMDocument bug. + * + * @link http://code.google.com/p/phpquery/issues/detail?id=80 + * @param $html + */ + protected function charsetFixHTML($markup) + { + $matches = array(); + // find meta tag + preg_match( + '@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', + $markup, + $matches, + PREG_OFFSET_CAPTURE + ); + if (!isset($matches[0])) { + return; + } + $metaContentType = $matches[0][0]; + $markup = substr($markup, 0, $matches[0][1]) + . substr($markup, $matches[0][1] + strlen($metaContentType)); + $headStart = stripos($markup, ''); + $markup = substr($markup, 0, $headStart + 6) . $metaContentType + . substr($markup, $headStart + 6); + return $markup; } - else { - // string markup - $fake = $this->documentFragmentCreate($source, $sourceCharset); - if ($fake === false) - throw new \Exception("Error loading documentFragment markup"); - else - return $this->import($fake->root->childNodes); + + protected function charsetAppendToHTML($html, $charset, $xhtml = false) + { + // remove existing meta[type=content-type] + $html = preg_replace('@\s*]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html); + $meta = ''; + if (strpos($html, ')@s', "{$meta}", $html); + } + } else { + return preg_replace('@)@s', '' . $meta, $html); + } } - return $return; - } - /** - * Creates new document fragment. - * - * @param $source - * @return DOMDocumentWrapper - */ - protected function documentFragmentCreate($source, $charset = null) { - $fake = new DOMDocumentWrapper(); - $fake->contentType = $this->contentType; - $fake->isXML = $this->isXML; - $fake->isHTML = $this->isHTML; - $fake->isXHTML = $this->isXHTML; - $fake->root = $fake->document; - if (!$charset) - $charset = $this->charset; - // $fake->documentCreate($this->charset); - if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) - $source = array( - $source - ); - if (is_array($source) || $source instanceof \DOMNodeList) { - // dom nodes - // load fake document - if (!$this->documentFragmentLoadMarkup($fake, $charset)) - return false; - $nodes = $fake->import($source); - foreach ($nodes as $node) - $fake->root->appendChild($node); + + protected function charsetAppendToXML($markup, $charset) + { + $declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?' + . '>'; + return $declaration . $markup; } - else { - // string markup - $this->documentFragmentLoadMarkup($fake, $charset, $source); + + public static function isDocumentFragmentHTML($markup) + { + return stripos($markup, 'isDocumentFragment = false; - if ($fragment->isXML) { - if ($fragment->isXHTML) { - // add FAKE element to set default namespace - $fragment->loadMarkupXML('' - . '' - . '' . $markup . ''); - $fragment->root = $fragment->document->firstChild->nextSibling; - } - else { - $fragment->loadMarkupXML('' . $markup . ''); - $fragment->root = $fragment->document->firstChild; - } + + public static function isDocumentFragmentXML($markup) + { + return stripos($markup, '<' . '?xml') === false; } - else { - $markup2 = phpQuery::$defaultDoctype - . ''; - $noBody = strpos($markup, 'loadMarkupHTML($markup2); - // TODO resolv body tag merging issue - $fragment->root = $noBody ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling - : $fragment->document->firstChild->nextSibling->firstChild->nextSibling; + + public static function isDocumentFragmentXHTML($markup) + { + return self::isDocumentFragmentHTML($markup); } - if (!$fragment->root) - return false; - $fragment->isDocumentFragment = true; - return true; - } - protected function documentFragmentToMarkup($fragment) { - phpQuery::debug('documentFragmentToMarkup'); - $tmp = $fragment->isDocumentFragment; - $fragment->isDocumentFragment = false; - $markup = $fragment->markup(); - if ($fragment->isXML) { - $markup = substr($markup, 0, strrpos($markup, '')); - if ($fragment->isXHTML) { - $markup = substr($markup, strpos($markup, '') + 6); - } + + public function importAttr($value) + { + // TODO + } + + /** + * + * @param $source + * @param $target + * @param $sourceCharset + * @return array Array of imported nodes. + */ + public function import($source, $sourceCharset = null) + { + // TODO charset conversions + $return = array(); + if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) { + $source = array( + $source + ); + } + // if (is_array($source)) { + // foreach($source as $node) { + // if (is_string($node)) { + // // string markup + // $fake = $this->documentFragmentCreate($node, $sourceCharset); + // if ($fake === false) + // throw new \Exception("Error loading documentFragment markup"); + // else + // $return = array_merge($return, + // $this->import($fake->root->childNodes) + // ); + // } else { + // $return[] = $this->document->importNode($node, true); + // } + // } + // return $return; + // } else { + // // string markup + // $fake = $this->documentFragmentCreate($source, $sourceCharset); + // if ($fake === false) + // throw new \Exception("Error loading documentFragment markup"); + // else + // return $this->import($fake->root->childNodes); + // } + if (is_array($source) || $source instanceof \DOMNodeList) { + // dom nodes + self::debug('Importing nodes to document'); + foreach ($source as $node) { + $return[] = $this->document->importNode($node, true); + } + } else { + // string markup + $fake = $this->documentFragmentCreate($source, $sourceCharset); + if ($fake === false) { + throw new \Exception("Error loading documentFragment markup"); + } else { + return $this->import($fake->root->childNodes); + } + } + return $return; } - else { - $markup = substr($markup, strpos($markup, '') + 6); - $markup = substr($markup, 0, strrpos($markup, '')); + + /** + * Creates new document fragment. + * + * @param $source + * @return DOMDocumentWrapper + */ + protected function documentFragmentCreate($source, $charset = null) + { + $fake = new DOMDocumentWrapper(); + $fake->contentType = $this->contentType; + $fake->isXML = $this->isXML; + $fake->isHTML = $this->isHTML; + $fake->isXHTML = $this->isXHTML; + $fake->root = $fake->document; + if (!$charset) { + $charset = $this->charset; + } + // $fake->documentCreate($this->charset); + if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) { + $source = array( + $source + ); + } + if (is_array($source) || $source instanceof \DOMNodeList) { + // dom nodes + // load fake document + if (!$this->documentFragmentLoadMarkup($fake, $charset)) { + return false; + } + $nodes = $fake->import($source); + foreach ($nodes as $node) { + $fake->root->appendChild($node); + } + } else { + // string markup + $this->documentFragmentLoadMarkup($fake, $charset, $source); + } + return $fake; } - $fragment->isDocumentFragment = $tmp; - if (phpQuery::$debug) - phpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150)); - return $markup; - } - /** - * Return document markup, starting with optional $nodes as root. - * - * @param $nodes \DOMNode|\DOMNodeList - * @return string - */ - public function markup($nodes = null, $innerMarkup = false) { - if (isset($nodes) && count($nodes) == 1 - && $nodes[0] instanceof \DOMDocument) - $nodes = null; - if (isset($nodes)) { - $markup = ''; - if (!is_array($nodes) && !($nodes instanceof \DOMNodeList)) - $nodes = array( - $nodes - ); - if ($this->isDocumentFragment && !$innerMarkup) - foreach ($nodes as $i => $node) - if ($node->isSameNode($this->root)) { - // var_dump($node); - $nodes = array_slice($nodes, 0, $i) - + phpQuery::DOMNodeListToArray($node->childNodes) - + array_slice($nodes, $i + 1); - } - if ($this->isXML && !$innerMarkup) { - self::debug("Getting outerXML with charset '{$this->charset}'"); - // we need outerXML, so we can benefit from - // $node param support in saveXML() - foreach ($nodes as $node) - $markup .= $this->document->saveXML($node); - } - else { - $loop = array(); - if ($innerMarkup) - foreach ($nodes as $node) { - if ($node->childNodes) - foreach ($node->childNodes as $child) - $loop[] = $child; - else - $loop[] = $node; - } - else - $loop = $nodes; - self::debug("Getting markup, moving selected nodes (" . count($loop) - . ") to new DocumentFragment"); - $fake = $this->documentFragmentCreate($loop); - $markup = $this->documentFragmentToMarkup($fake); - } - if ($this->isXHTML) { - self::debug("Fixing XHTML"); - $markup = self::markupFixXHTML($markup); - } - self::debug("Markup: " . substr($markup, 0, 250)); - return $markup; + + /** + * + * @param $document DOMDocumentWrapper + * @param $markup + * @return $document + */ + private function documentFragmentLoadMarkup($fragment, $charset, $markup = null) + { + // TODO error handling + // TODO copy doctype + // tempolary turn off + $fragment->isDocumentFragment = false; + if ($fragment->isXML) { + if ($fragment->isXHTML) { + // add FAKE element to set default namespace + $fragment->loadMarkupXML( + '' + . '' + . '' . $markup . '' + ); + $fragment->root = $fragment->document->firstChild->nextSibling; + } else { + $fragment->loadMarkupXML( + '' . $markup . '' + ); + $fragment->root = $fragment->document->firstChild; + } + } else { + $markup2 = phpQuery::$defaultDoctype + . ''; + $noBody = strpos($markup, 'loadMarkupHTML($markup2); + // TODO resolv body tag merging issue + $fragment->root = $noBody ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling + : $fragment->document->firstChild->nextSibling->firstChild->nextSibling; + } + if (!$fragment->root) { + return false; + } + $fragment->isDocumentFragment = true; + return true; } - else { - if ($this->isDocumentFragment) { - // documentFragment, html only... - self::debug("Getting markup, DocumentFragment detected"); - // return $this->markup( - //// $this->document->getElementsByTagName('body')->item(0) - // $this->document->root, true - // ); - $markup = $this->documentFragmentToMarkup($this); - // no need for markupFixXHTML, as it's done thought markup($nodes) method + + protected function documentFragmentToMarkup($fragment) + { + phpQuery::debug('documentFragmentToMarkup'); + $tmp = $fragment->isDocumentFragment; + $fragment->isDocumentFragment = false; + $markup = $fragment->markup(); + if ($fragment->isXML) { + $markup = substr($markup, 0, strrpos($markup, '')); + if ($fragment->isXHTML) { + $markup = substr($markup, strpos($markup, '') + 6); + } + } else { + $markup = substr($markup, strpos($markup, '') + 6); + $markup = substr($markup, 0, strrpos($markup, '')); + } + $fragment->isDocumentFragment = $tmp; + if (phpQuery::$debug) { + phpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150)); + } return $markup; - } - else { - self::debug("Getting markup (" . ($this->isXML ? 'XML' : 'HTML') - . "), final with charset '{$this->charset}'"); - $markup = $this->isXML ? $this->document->saveXML() - : $this->document->saveHTML(); - if ($this->isXHTML) { - self::debug("Fixing XHTML"); - $markup = self::markupFixXHTML($markup); + } + + /** + * Return document markup, starting with optional $nodes as root. + * + * @param $nodes \DOMNode|\DOMNodeList + * @return string + */ + public function markup($nodes = null, $innerMarkup = false) + { + if (isset($nodes) && count($nodes) == 1 + && $nodes[0] instanceof \DOMDocument + ) { + $nodes = null; + } + if (isset($nodes)) { + $markup = ''; + if (!is_array($nodes) && !($nodes instanceof \DOMNodeList)) { + $nodes = array( + $nodes + ); + } + if ($this->isDocumentFragment && !$innerMarkup) { + foreach ($nodes as $i => $node) { + if ($node->isSameNode($this->root)) { + // var_dump($node); + $nodes = array_slice($nodes, 0, $i) + + phpQuery::DOMNodeListToArray($node->childNodes) + + array_slice($nodes, $i + 1); + } + } + } + if ($this->isXML && !$innerMarkup) { + self::debug("Getting outerXML with charset '{$this->charset}'"); + // we need outerXML, so we can benefit from + // $node param support in saveXML() + foreach ($nodes as $node) { + $markup .= $this->document->saveXML($node); + } + } else { + $loop = array(); + if ($innerMarkup) { + foreach ($nodes as $node) { + if ($node->childNodes) { + foreach ($node->childNodes as $child) { + $loop[] = $child; + } + } else { + $loop[] = $node; + } + } + } else { + $loop = $nodes; + } + self::debug( + "Getting markup, moving selected nodes (" . count($loop) + . ") to new DocumentFragment" + ); + $fake = $this->documentFragmentCreate($loop); + $markup = $this->documentFragmentToMarkup($fake); + } + if ($this->isXHTML) { + self::debug("Fixing XHTML"); + $markup = self::markupFixXHTML($markup); + } + self::debug("Markup: " . substr($markup, 0, 250)); + return $markup; + } else { + if ($this->isDocumentFragment) { + // documentFragment, html only... + self::debug("Getting markup, DocumentFragment detected"); + // return $this->markup( + //// $this->document->getElementsByTagName('body')->item(0) + // $this->document->root, true + // ); + $markup = $this->documentFragmentToMarkup($this); + // no need for markupFixXHTML, as it's done thought markup($nodes) method + return $markup; + } else { + self::debug( + "Getting markup (" . ($this->isXML ? 'XML' : 'HTML') + . "), final with charset '{$this->charset}'" + ); + $markup = $this->isXML ? $this->document->saveXML() + : $this->document->saveHTML(); + if ($this->isXHTML) { + self::debug("Fixing XHTML"); + $markup = self::markupFixXHTML($markup); + } + self::debug("Markup: " . substr($markup, 0, 250)); + return $markup; + } } - self::debug("Markup: " . substr($markup, 0, 250)); + } + + protected static function markupFixXHTML($markup) + { + $markup = self::expandEmptyTag('script', $markup); + $markup = self::expandEmptyTag('select', $markup); + $markup = self::expandEmptyTag('textarea', $markup); return $markup; - } } - } - protected static function markupFixXHTML($markup) { - $markup = self::expandEmptyTag('script', $markup); - $markup = self::expandEmptyTag('select', $markup); - $markup = self::expandEmptyTag('textarea', $markup); - return $markup; - } - public static function debug($text) { - phpQuery::debug($text); - } - /** - * expandEmptyTag - * - * @param $tag - * @param $xml - * @return string - * @author mjaque at ilkebenson dot com - * @link http://php.net/manual/en/domdocument.savehtml.php#81256 - */ - public static function expandEmptyTag($tag, $xml) { - $indice = 0; - while ($indice < strlen($xml)) { - $pos = strpos($xml, "<$tag ", $indice); - if ($pos) { - $posCierre = strpos($xml, ">", $pos); - if ($xml[$posCierre - 1] == "/") { - $xml = substr_replace($xml, ">", $posCierre - 1, 2); - } - $indice = $posCierre; - } - else - break; + + public static function debug($text) + { + phpQuery::debug($text); + } + + /** + * expandEmptyTag + * + * @param $tag + * @param $xml + * @return string + * @author mjaque at ilkebenson dot com + * @link http://php.net/manual/en/domdocument.savehtml.php#81256 + */ + public static function expandEmptyTag($tag, $xml) + { + $indice = 0; + while ($indice < strlen($xml)) { + $pos = strpos($xml, "<$tag ", $indice); + if ($pos) { + $posCierre = strpos($xml, ">", $pos); + if ($xml[$posCierre - 1] == "/") { + $xml = substr_replace($xml, ">", $posCierre - 1, 2); + } + $indice = $posCierre; + } else { + break; + } + } + return $xml; } - return $xml; - } } diff --git a/src/Dom/DomEvent.php b/src/Dom/DomEvent.php index f69e9de..8704522 100644 --- a/src/Dom/DomEvent.php +++ b/src/Dom/DomEvent.php @@ -1,110 +1,117 @@ + * @link http://developer.mozilla.org/En/DOM:event + * @author Tobiasz Cudnik * @package phpQuery - * @todo implement ArrayAccess ? + * @todo implement ArrayAccess ? */ -class DOMEvent { - /** - * Returns a boolean indicating whether the event bubbles up through the DOM or not. - * - * @var unknown_type - */ - public $bubbles = true; - /** - * Returns a boolean indicating whether the event is cancelable. - * - * @var unknown_type - */ - public $cancelable = true; - /** - * Returns a reference to the currently registered target for the event. - * - * @var unknown_type - */ - public $currentTarget; - /** - * Returns detail about the event, depending on the type of event. - * - * @var unknown_type - * @link http://developer.mozilla.org/en/DOM/event.detail - */ - public $detail; // ??? - /** - * Used to indicate which phase of the event flow is currently being evaluated. - * - * NOT IMPLEMENTED - * - * @var unknown_type - * @link http://developer.mozilla.org/en/DOM/event.eventPhase - */ - public $eventPhase; // ??? - /** - * The explicit original target of the event (Mozilla-specific). - * - * NOT IMPLEMENTED - * - * @var unknown_type - */ - public $explicitOriginalTarget; // moz only - /** - * The original target of the event, before any retargetings (Mozilla-specific). - * - * NOT IMPLEMENTED - * - * @var unknown_type - */ - public $originalTarget; // moz only - /** - * Identifies a secondary target for the event. - * - * @var unknown_type - */ - public $relatedTarget; - /** - * Returns a reference to the target to which the event was originally dispatched. - * - * @var unknown_type - */ - public $target; - /** - * Returns the time that the event was created. - * - * @var unknown_type - */ - public $timeStamp; - /** - * Returns the name of the event (case-insensitive). - */ - public $type; - public $runDefault = true; - public $data = null; - public function __construct($data) { - foreach ($data as $k => $v) { - $this->$k = $v; +class DOMEvent +{ + /** + * Returns a boolean indicating whether the event bubbles up through the DOM or not. + * + * @var bool + */ + public $bubbles = true; + /** + * Returns a boolean indicating whether the event is cancelable. + * + * @var bool + */ + public $cancelable = true; + /** + * Returns a reference to the currently registered target for the event. + * + * @var bool + */ + public $currentTarget; + /** + * Returns detail about the event, depending on the type of event. + * + * @var string + * @link http://developer.mozilla.org/en/DOM/event.detail + */ + public $detail; // ??? + /** + * Used to indicate which phase of the event flow is currently being evaluated. + * + * NOT IMPLEMENTED + * + * @var string + * @link http://developer.mozilla.org/en/DOM/event.eventPhase + */ + public $eventPhase; // ??? + /** + * The explicit original target of the event (Mozilla-specific). + * + * NOT IMPLEMENTED + * + * @var string + */ + public $explicitOriginalTarget; // moz only + /** + * The original target of the event, before any retargetings (Mozilla-specific). + * + * NOT IMPLEMENTED + * + * @var string + */ + public $originalTarget; // moz only + /** + * Identifies a secondary target for the event. + * + * @var string + */ + public $relatedTarget; + /** + * Returns a reference to the target to which the event was originally dispatched. + * + * @var string + */ + public $target; + /** + * Returns the time that the event was created. + * + * @var string + */ + public $timeStamp; + /** + * Returns the name of the event (case-insensitive). + */ + public $type; + public $runDefault = true; + public $data = null; + + public function __construct($data) + { + foreach ($data as $k => $v) { + $this->$k = $v; + } + if (!$this->timeStamp) { + $this->timeStamp = time(); + } + } + + /** + * Cancels the event (if it is cancelable). + * + */ + public function preventDefault() + { + $this->runDefault = false; + } + + /** + * Stops the propagation of events further along in the DOM. + * + */ + public function stopPropagation() + { + $this->bubbles = false; } - if (!$this->timeStamp) - $this->timeStamp = time(); - } - /** - * Cancels the event (if it is cancelable). - * - */ - public function preventDefault() { - $this->runDefault = false; - } - /** - * Stops the propagation of events further along in the DOM. - * - */ - public function stopPropagation() { - $this->bubbles = false; - } } diff --git a/src/PhpQuery.php b/src/PhpQuery.php index db49c12..27d80e2 100644 --- a/src/PhpQuery.php +++ b/src/PhpQuery.php @@ -4,1382 +4,1632 @@ * Document Object Model (DOM) API based on jQuery JavaScript Library. * * @version 0.9.5 - * @link http://code.google.com/p/phpquery/ - * @link http://phpquery-library.blogspot.com/ - * @link http://jquery.com/ - * @author Tobiasz Cudnik + * @link http://code.google.com/p/phpquery/ + * @link http://phpquery-library.blogspot.com/ + * @link http://jquery.com/ + * @author Tobiasz Cudnik * @license http://www.opensource.org/licenses/mit-license.php MIT License * @package phpQuery */ namespace PhpQuery; -use PhpQuery\Dom\DomDocumentWrapper as DOMDocumentWrapper; + require_once __DIR__ . '/bootstrap.php'; /** * Shortcut to phpQuery::pq($arg1, $context) * Chainable. * - * @see phpQuery::pq() + * @see phpQuery::pq() + * @param $arg1 + * @param null $context * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @author Tobiasz Cudnik + * @author Tobiasz Cudnik * @package phpQuery */ -function pq($arg1, $context = NULL) { - return PhpQuery::pq($arg1, $context); +function pq($arg1, $context = null) +{ + return PhpQuery::pq($arg1, $context); } /** * Static namespace for phpQuery functions. * - * @author Tobiasz Cudnik + * @author Tobiasz Cudnik * @package phpQuery */ -abstract class phpQuery { - /** - * XXX: Workaround for mbstring problems - * - * @var bool - */ - public static $mbstringSupport = true; - public static $debug = false; - public static $documents = array(); - public static $defaultDocumentID = null; - // public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"'; - /** - * Applies only to HTML. - * - * @var unknown_type - */ - public static $defaultDoctype = ''; - public static $defaultCharset = 'UTF-8'; - /** - * Static namespace for plugins. - * - * @var object - */ - public static $plugins = array(); - /** - * List of loaded plugins. - * - * @var unknown_type - */ - public static $pluginsLoaded = array(); - public static $pluginsMethods = array(); - public static $pluginsStaticMethods = array(); - public static $extendMethods = array(); - /** - * @TODO implement - */ - public static $extendStaticMethods = array(); - /** - * Hosts allowed for AJAX connections. - * Dot '.' means $_SERVER['HTTP_HOST'] (if any). - * - * @var array - */ - public static $ajaxAllowedHosts = array( - '.' - ); - /** - * AJAX settings. - * - * @var array - * XXX should it be static or not ? - */ - public static $ajaxSettings = array( - 'url' => '', - //TODO - 'global' => true, - 'type' => "GET", - 'timeout' => null, - 'contentType' => "application/x-www-form-urlencoded", - 'processData' => true, - // 'async' => true, - 'data' => null, - 'username' => null, - 'password' => null, - 'dataType' => null, - 'ifModified' => null, - 'accepts' => array( - 'xml' => "application/xml, text/xml", - 'html' => "text/html", - 'script' => "text/javascript, application/javascript", - 'json' => "application/json, text/javascript", - 'text' => "text/plain", - '_default' => "*/*" - ) - ); - public static $lastModified = null; - public static $active = 0; - public static $dumpCount = 0; - public static $enableCssShorthand = FALSE; - - public static function use_function($ns = '\\', $func = 'pq') { - if ($ns{0} !== '\\') { - $ns = '\\' . $ns; + public static $defaultCharset = 'UTF-8'; + /** + * Static namespace for plugins. + * + * @var object + */ + public static $plugins = array(); + /** + * List of loaded plugins. + * + * @var unknown_type + */ + public static $pluginsLoaded = array(); + public static $pluginsMethods = array(); + public static $pluginsStaticMethods = array(); + public static $extendMethods = array(); + /** + * @TODO implement + */ + public static $extendStaticMethods = array(); + /** + * Hosts allowed for AJAX connections. + * Dot '.' means $_SERVER['HTTP_HOST'] (if any). + * + * @var array + */ + public static $ajaxAllowedHosts = array( + '.' + ); + /** + * AJAX settings. + * + * @var array + * XXX should it be static or not ? + */ + public static $ajaxSettings = array( + 'url' => '', + //TODO + 'global' => true, + 'type' => "GET", + 'timeout' => null, + 'contentType' => "application/x-www-form-urlencoded", + 'processData' => true, + // 'async' => true, + 'data' => null, + 'username' => null, + 'password' => null, + 'dataType' => null, + 'ifModified' => null, + 'accepts' => array( + 'xml' => "application/xml, text/xml", + 'html' => "text/html", + 'script' => "text/javascript, application/javascript", + 'json' => "application/json, text/javascript", + 'text' => "text/plain", + '_default' => "*/*" + ) + ); + public static $lastModified = null; + public static $active = 0; + public static $dumpCount = 0; + public static $enableCssShorthand = false; + + public static function use_function($ns = '\\', $func = 'pq') + { + if ($ns{0} !== '\\') { + $ns = '\\' . $ns; + } + if (!function_exists($ns . '\\' . $func)) { + if ($ns === '\\') { + eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }"); + } else { + $ns = substr($ns, 1); + eval("namespace $ns { function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); } }"); + } + } } - if (!function_exists($ns . '\\' . $func)) { - if ($ns === '\\') { - eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }"); - } - else { - $ns = substr($ns, 1); - eval("namespace $ns { function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); } }"); - } + + + /** + * Multi-purpose function. + * Use pq() as shortcut. + * + * In below examples, $pq is any result of pq(); function. + * + * 1. Import markup into existing document (without any attaching): + * - Import into selected document: + * pq('
    ') // DOESNT accept text nodes at beginning of input string ! + * - Import into document with ID from $pq->getDocumentID(): + * pq('
    ', $pq->getDocumentID()) + * - Import into same document as \DOMNode belongs to: + * pq('
    ', \DOMNode) + * - Import into document from phpQuery object: + * pq('
    ', $pq) + * + * 2. Run query: + * - Run query on last selected document: + * pq('div.myClass') + * - Run query on document with ID from $pq->getDocumentID(): + * pq('div.myClass', $pq->getDocumentID()) + * - Run query on same document as \DOMNode belongs to and use node(s)as root for query: + * pq('div.myClass', \DOMNode) + * - Run query on document from phpQuery object + * and use object's stack as root node(s) for query: + * pq('div.myClass', $pq) + * + * @param string|\DOMNode|\DOMNodeList|array $arg1 HTML markup, CSS Selector, \DOMNode or array of \DOMNodes + * @param string|PhpQueryObject|\DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or \DOMNode (determines also query root) + * + * @throws \Exception + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false + * phpQuery object or false in case of error. + */ + public static function pq($arg1, $context = null) + { + if ($arg1 instanceof \DOMNode && !isset($context)) { + foreach (phpQuery::$documents as $documentWrapper) { + $compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument; + if ($documentWrapper->document->isSameNode($compare)) { + $context = $documentWrapper->id; + } + } + } + if (!$context) { + $domId = self::$defaultDocumentID; + if (!$domId) { + throw new \Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); + } + // } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) + } else { + if (is_object($context) && $context instanceof PhpQueryObject) { + $domId = $context->getDocumentID(); + } else { + if ($context instanceof \DOMDocument) { + $domId = self::getDocumentID($context); + if (!$domId) { + //throw new \Exception('Orphaned \DOMDocument'); + $domId = self::newDocument($context)->getDocumentID(); + } + } else { + if ($context instanceof \DOMNode) { + $domId = self::getDocumentID($context); + if (!$domId) { + throw new \Exception('Orphaned DOMNode'); + // $domId = self::newDocument($context->ownerDocument); + } + } else { + $domId = $context; + } + } + } + } + if ($arg1 instanceof PhpQueryObject) { + // if (is_object($arg1) && (get_class($arg1) == 'PhpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'PhpQueryObject'))) { + /** + * Return $arg1 or import $arg1 stack if document differs: + * pq(pq('
    ')) + */ + if ($arg1->getDocumentID() == $domId) { + return $arg1; + } + $class = get_class($arg1); + // support inheritance by passing old object to overloaded constructor + $phpQuery = $class != 'phpQuery' ? new $class($arg1, $domId) + : new PhpQueryObject($domId); + $phpQuery->elements = array(); + foreach ($arg1->elements as $node) { + $phpQuery->elements[] = $phpQuery->document->importNode($node, true); + } + return $phpQuery; + } else { + if ($arg1 instanceof \DOMNode + || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode) + ) { + /* + * Wrap DOM nodes with phpQuery object, import into document when needed: + * pq(array($domNode1, $domNode2)) + */ + $phpQuery = new PhpQueryObject($domId); + if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) { + $arg1 = array( + $arg1 + ); + } + $phpQuery->elements = array(); + foreach ($arg1 as $node) { + $sameDocument = $node->ownerDocument instanceof \DOMDocument + && !$node->ownerDocument->isSameNode($phpQuery->document); + $phpQuery->elements[] = $sameDocument ? $phpQuery->document->importNode($node, true) + : $node; + } + return $phpQuery; + } else { + if (self::isMarkup($arg1)) { + /** + * Import HTML: + * pq('
    ') + */ + $phpQuery = new PhpQueryObject($domId); + return $phpQuery->newInstance($phpQuery->documentWrapper->import($arg1)); + } else { + /** + * Run CSS query: + * pq('div.myClass') + */ + $phpQuery = new PhpQueryObject($domId); + // if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) + if ($context && $context instanceof PhpQueryObject) { + $phpQuery->elements = $context->elements; + } else { + if ($context && $context instanceof \DOMNodeList) { + $phpQuery->elements = array(); + foreach ($context as $node) { + $phpQuery->elements[] = $node; + } + } else { + if ($context && $context instanceof \DOMNode) { + $phpQuery->elements = array( + $context + ); + } + } + } + return $phpQuery->find($arg1); + } + } + } } - } - - - /** - * Multi-purpose function. - * Use pq() as shortcut. - * - * In below examples, $pq is any result of pq(); function. - * - * 1. Import markup into existing document (without any attaching): - * - Import into selected document: - * pq('
    ') // DOESNT accept text nodes at beginning of input string ! - * - Import into document with ID from $pq->getDocumentID(): - * pq('
    ', $pq->getDocumentID()) - * - Import into same document as \DOMNode belongs to: - * pq('
    ', \DOMNode) - * - Import into document from phpQuery object: - * pq('
    ', $pq) - * - * 2. Run query: - * - Run query on last selected document: - * pq('div.myClass') - * - Run query on document with ID from $pq->getDocumentID(): - * pq('div.myClass', $pq->getDocumentID()) - * - Run query on same document as \DOMNode belongs to and use node(s)as root for query: - * pq('div.myClass', \DOMNode) - * - Run query on document from phpQuery object - * and use object's stack as root node(s) for query: - * pq('div.myClass', $pq) - * - * @param string|\DOMNode|\DOMNodeList|array $arg1 HTML markup, CSS Selector, \DOMNode or array of \DOMNodes - * @param string|PhpQueryObject|\DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or \DOMNode (determines also query root) - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false - * phpQuery object or false in case of error. - */ - public static function pq($arg1, $context = null) { - if ($arg1 instanceof \DOMNode && !isset($context)) { - foreach (phpQuery::$documents as $documentWrapper) { - $compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument; - if ($documentWrapper->document->isSameNode($compare)) - $context = $documentWrapper->id; - } + + /** + * Sets default document to $id. Document has to be loaded prior + * to using this method. + * $id can be retrived via getDocumentID() or getDocumentIDRef(). + * + * @param string $id + */ + public static function selectDocument($id) + { + $id = self::getDocumentID($id); + self::debug("Selecting document '$id' as default one"); + self::$defaultDocumentID = self::getDocumentID($id); } - if (!$context) { - $domId = self::$defaultDocumentID; - if (!$domId) - throw new \Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); - // } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) + + /** + * Returns document with id $id or last used as PhpQueryObject. + * $id can be retrived via getDocumentID() or getDocumentIDRef(). + * Chainable. + * + * @see phpQuery::selectDocument() + * @param null $id + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function getDocument($id = null) + { + if ($id) + phpQuery::selectDocument($id); + else + $id = phpQuery::$defaultDocumentID; + return new PhpQueryObject($id); } - else if (is_object($context) && $context instanceof PhpQueryObject) - $domId = $context->getDocumentID(); - else if ($context instanceof \DOMDocument) { - $domId = self::getDocumentID($context); - if (!$domId) { - //throw new \Exception('Orphaned \DOMDocument'); - $domId = self::newDocument($context)->getDocumentID(); - } + + /** + * Creates new document from markup. + * Chainable. + * + * @param null $markup + * @param null $contentType + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocument($markup = null, $contentType = null) + { + if (!$markup) + $markup = ''; + $documentID = phpQuery::createDocumentWrapper($markup, $contentType); + return new PhpQueryObject($documentID); } - else if ($context instanceof \DOMNode) { - $domId = self::getDocumentID($context); - if (!$domId) { - throw new \Exception('Orphaned DOMNode'); - // $domId = self::newDocument($context->ownerDocument); - } + + /** + * Creates new document from markup. + * Chainable. + * + * @param null $markup + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentHTML($markup = null, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "text/html{$contentType}"); } - else - $domId = $context; - if ($arg1 instanceof PhpQueryObject) { - // if (is_object($arg1) && (get_class($arg1) == 'PhpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'PhpQueryObject'))) { - /** - * Return $arg1 or import $arg1 stack if document differs: - * pq(pq('
    ')) - */ - if ($arg1->getDocumentID() == $domId) - return $arg1; - $class = get_class($arg1); - // support inheritance by passing old object to overloaded constructor - $phpQuery = $class != 'phpQuery' ? new $class($arg1, $domId) - : new PhpQueryObject($domId); - $phpQuery->elements = array(); - foreach ($arg1->elements as $node) - $phpQuery->elements[] = $phpQuery->document->importNode($node, true); - return $phpQuery; + + /** + * Creates new document from markup. + * Chainable. + * + * @param null $markup + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentXML($markup = null, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "text/xml{$contentType}"); } - else if ($arg1 instanceof \DOMNode - || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode)) { - /* - * Wrap DOM nodes with phpQuery object, import into document when needed: - * pq(array($domNode1, $domNode2)) - */ - $phpQuery = new PhpQueryObject($domId); - if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) - $arg1 = array( - $arg1 - ); - $phpQuery->elements = array(); - foreach ($arg1 as $node) { - $sameDocument = $node->ownerDocument instanceof \DOMDocument - && !$node->ownerDocument->isSameNode($phpQuery->document); - $phpQuery->elements[] = $sameDocument ? $phpQuery->document->importNode($node, true) - : $node; - } - return $phpQuery; + + /** + * Creates new document from markup. + * Chainable. + * + * @param null $markup + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentXHTML($markup = null, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocument($markup, "application/xhtml+xml{$contentType}"); } - else if (self::isMarkup($arg1)) { - /** - * Import HTML: - * pq('
    ') - */ - $phpQuery = new PhpQueryObject($domId); - return $phpQuery->newInstance($phpQuery->documentWrapper->import($arg1)); + + /** + * Creates new document from markup. + * Chainable. + * + * @param null $markup + * @param string $contentType + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentPHP($markup = null, $contentType = "text/html") + { + // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function) + $markup = phpQuery::phpToMarkup($markup, self::$defaultCharset); + return self::newDocument($markup, $contentType); } - else { - /** - * Run CSS query: - * pq('div.myClass') - */ - $phpQuery = new PhpQueryObject($domId); - // if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) - if ($context && $context instanceof PhpQueryObject) - $phpQuery->elements = $context->elements; - else if ($context && $context instanceof \DOMNodeList) { - $phpQuery->elements = array(); - foreach ($context as $node) - $phpQuery->elements[] = $node; - } - else if ($context && $context instanceof \DOMNode) - $phpQuery->elements = array( - $context + + public static function phpToMarkup($php, $charset = 'utf-8') + { + $regexes = array( + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<' + . '?php?(.*?)(?:\\?>)([^\']*)\'@s', + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<' + . '?php?(.*?)(?:\\?>)([^"]*)"@s', ); - return $phpQuery->find($arg1); - } - } - /** - * Sets default document to $id. Document has to be loaded prior - * to using this method. - * $id can be retrived via getDocumentID() or getDocumentIDRef(). - * - * @param unknown_type $id - */ - public static function selectDocument($id) { - $id = self::getDocumentID($id); - self::debug("Selecting document '$id' as default one"); - self::$defaultDocumentID = self::getDocumentID($id); - } - /** - * Returns document with id $id or last used as PhpQueryObject. - * $id can be retrived via getDocumentID() or getDocumentIDRef(). - * Chainable. - * - * @see phpQuery::selectDocument() - * @param unknown_type $id - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function getDocument($id = null) { - if ($id) - phpQuery::selectDocument($id); - else - $id = phpQuery::$defaultDocumentID; - return new PhpQueryObject($id); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocument($markup = null, $contentType = null) { - if (!$markup) - $markup = ''; - $documentID = phpQuery::createDocumentWrapper($markup, $contentType); - return new PhpQueryObject($documentID); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentHTML($markup = null, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocument($markup, "text/html{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentXML($markup = null, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocument($markup, "text/xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentXHTML($markup = null, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocument($markup, "application/xhtml+xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentPHP($markup = null, $contentType = "text/html") { - // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function) - $markup = phpQuery::phpToMarkup($markup, self::$defaultCharset); - return self::newDocument($markup, $contentType); - } - public static function phpToMarkup($php, $charset = 'utf-8') { - $regexes = array( - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<' - . '?php?(.*?)(?:\\?>)([^\']*)\'@s', - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<' - . '?php?(.*?)(?:\\?>)([^"]*)"@s', - ); - foreach ($regexes as $regex) - while (preg_match($regex, $php, $matches)) { - $php = preg_replace_callback($regex, - // create_function('$m, $charset = "'.$charset.'"', - // 'return $m[1].$m[2] - // .htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset) - // .$m[5].$m[2];' - // ), - array( - 'phpQuery', - '_phpToMarkupCallback' - ), $php); - } - $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s'; - //preg_match_all($regex, $php, $matches); - //var_dump($matches); - $php = preg_replace($regex, '\\1', $php); - return $php; - } - public static function _phpToMarkupCallback($php, $charset = 'utf-8') { - return $m[1] . $m[2] - . htmlspecialchars("<" . "?php" . $m[4] . "?" . ">", ENT_QUOTES - | ENT_NOQUOTES, $charset) . $m[5] . $m[2]; - } - public static function _markupToPHPCallback($m) { - return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">"; - } - /** - * Converts document markup containing PHP code generated by phpQuery::php() - * into valid (executable) PHP code syntax. - * - * @param string|PhpQueryObject $content - * @return string PHP code. - */ - public static function markupToPHP($content) { - if ($content instanceof PhpQueryObject) - $content = $content->markupOuter(); - /* ... to */ - $content = preg_replace_callback('@\s*\s*@s', - // create_function('$m', - // 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";' - // ), - array( - 'phpQuery', - '_markupToPHPCallback' - ), $content); - /* extra space added to save highlighters */ - $regexes = array( - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^\']*)\'@s', - '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^"]*)"@s', - ); - foreach ($regexes as $regex) - while (preg_match($regex, $content)) - $content = preg_replace_callback($regex, create_function('$m', 'return $m[1].$m[2].$m[3]."", " ", "\n", " ", "{", "$", "}", \'"\', "[", "]"), - htmlspecialchars_decode($m[4]) - ) - ." ?>".$m[5].$m[2];'), $content); - return $content; - } - /** - * Creates new document from file $file. - * Chainable. - * - * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources. - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFile($file, $contentType = null) { - $documentID = self::createDocumentWrapper(file_get_contents($file), $contentType); - return new PhpQueryObject($documentID); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileHTML($file, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocumentFile($file, "text/html{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileXML($file, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocumentFile($file, "text/xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFileXHTML($file, $charset = null) { - $contentType = $charset ? ";charset=$charset" : ''; - return self::newDocumentFile($file, "application/xhtml+xml{$contentType}"); - } - /** - * Creates new document from markup. - * Chainable. - * - * @param unknown_type $markup - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public static function newDocumentFilePHP($file, $contentType = null) { - return self::newDocumentPHP(file_get_contents($file), $contentType); - } - /** - * Reuses existing \DOMDocument object. - * Chainable. - * - * @param $document \DOMDocument - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support \DOMDocument - */ - public static function loadDocument($document) { - // TODO - die('TODO loadDocument'); - } - /** - * Enter description here... - * - * @param unknown_type $html - * @param unknown_type $domId - * @return unknown New DOM ID - * @todo support PHP tags in input - * @todo support passing \DOMDocument object from self::loadDocument - */ - protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) { - if (function_exists('domxml_open_mem')) - throw new \Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); - // $id = $documentID - // ? $documentID - // : md5(microtime()); - $document = null; - if ($html instanceof \DOMDocument) { - if (self::getDocumentID($html)) { - // document already exists in phpQuery::$documents, make a copy - $document = clone $html; - } - else { - // new document, add it to phpQuery::$documents - $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); - } - } - else { - $wrapper = new DOMDocumentWrapper($html, $contentType, $documentID); + foreach ($regexes as $regex) + while (preg_match($regex, $php, $matches)) { + $php = preg_replace_callback( + $regex, + // create_function('$m, $charset = "'.$charset.'"', + // 'return $m[1].$m[2] + // .htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset) + // .$m[5].$m[2];' + // ), + array( + 'phpQuery', + '_phpToMarkupCallback' + ), + $php + ); + } + $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s'; + //preg_match_all($regex, $php, $matches); + //var_dump($matches); + $php = preg_replace($regex, '\\1', $php); + return $php; } - // $wrapper->id = $id; - // bind document - phpQuery::$documents[$wrapper->id] = $wrapper; - // remember last loaded document - phpQuery::selectDocument($wrapper->id); - return $wrapper->id; - } - /** - * Extend class namespace. - * - * @param string|array $target - * @param array $source - * @TODO support string $source - * @return unknown_type - */ - public static function extend($target, $source) { - switch ($target) { - case 'PhpQueryObject': - $targetRef = &self::$extendMethods; - $targetRef2 = &self::$pluginsMethods; - break; - case 'phpQuery': - $targetRef = &self::$extendStaticMethods; - $targetRef2 = &self::$pluginsStaticMethods; - break; - default: - throw new \Exception("Unsupported \$target type"); + + public static function _phpToMarkupCallback($m, $charset = 'utf-8') + { + return $m[1] . $m[2] + . htmlspecialchars( + "<" . "?php" . $m[4] . "?" . ">", + ENT_QUOTES + | ENT_NOQUOTES, + $charset + ) . $m[5] . $m[2]; } - if (is_string($source)) - $source = array( - $source => $source - ); - foreach ($source as $method => $callback) { - if (isset($targetRef[$method])) { - // throw new \Exception - self::debug("Duplicate method '{$method}', can\'t extend '{$target}'"); - continue; - } - if (isset($targetRef2[$method])) { - // throw new \Exception - self::debug("Duplicate method '{$method}' from plugin '{$targetRef2[$method]}'," - . " can\'t extend '{$target}'"); - continue; - } - $targetRef[$method] = $callback; + + public static function _markupToPHPCallback($m) + { + return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">"; } - return true; - } - /** - * Extend phpQuery with $class from $file. - * - * @param string $class Extending class name. Real class name can be prepended phpQuery_. - * @param string $file Filename to include. Defaults to "{$class}.php". - */ - public static function plugin($class, $file = null) { - // TODO $class checked agains phpQuery_$class - // if (strpos($class, 'phpQuery') === 0) - // $class = substr($class, 8); - if (in_array($class, self::$pluginsLoaded)) - return true; - if (!$file) - $file = $class . '.php'; - $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class); - $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class); - if (!$objectClassExists && !$staticClassExists) - require_once($file); - self::$pluginsLoaded[] = $class; - // static methods - if (class_exists('\PhpQuery\Plugin\Util' . $class)) { - $realClass = '\PhpQuery\Plugin\Util' . $class; - $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] - : get_class_methods($realClass); - foreach ($loop as $method) { - if ($method == '__initialize') - continue; - if (!is_callable(array( - $realClass, - $method - ))) - continue; - if (isset(self::$pluginsStaticMethods[$method])) { - throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" - . self::$pluginsStaticMethods[$method] . "'"); - return; - } - self::$pluginsStaticMethods[$method] = $class; - } - if (method_exists($realClass, '__initialize')) - call_user_func_array(array( - $realClass, - '__initialize' - ), array()); + + /** + * Converts document markup containing PHP code generated by phpQuery::php() + * into valid (executable) PHP code syntax. + * + * @param string|PhpQueryObject $content + * @return string PHP code. + */ + public static function markupToPHP($content) + { + if ($content instanceof PhpQueryObject) + $content = $content->markupOuter(); + /* ... to */ + $content = preg_replace_callback( + '@\s*\s*@s', + // create_function('$m', + // 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";' + // ), + array( + 'phpQuery', + '_markupToPHPCallback' + ), + $content + ); + /* extra space added to save highlighters */ + $regexes = array( + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^\']*)\'@s', + '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:<|%3C)\\?(?:php)?(.*?)(?:\\?(?:>|%3E))([^"]*)"@s', + ); + foreach ($regexes as $regex) + while (preg_match($regex, $content)) + $content = preg_replace_callback( + $regex, + create_function( + '$m', + 'return $m[1].$m[2].$m[3]."", " ", "\n", " ", "{", "$", "}", \'"\', "[", "]"), + htmlspecialchars_decode($m[4]) + ) + ." ?>".$m[5].$m[2];' + ), + $content + ); + return $content; } - // object methods - if (class_exists('\\PhpQuery\\Plugin\\' . $class)) { - $realClass = '\\PhpQuery\\Plugin\\' . $class; - $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] - : get_class_methods($realClass); - foreach ($loop as $method) { - if (!is_callable(array( - $realClass, - $method - ))) - continue; - if (isset(self::$pluginsMethods[$method])) { - throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" - . self::$pluginsMethods[$method] . "'"); - continue; - } - self::$pluginsMethods[$method] = $class; - } + + /** + * Creates new document from file $file. + * Chainable. + * + * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources. + * @param null $contentType + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFile($file, $contentType = null) + { + $documentID = self::createDocumentWrapper(file_get_contents($file), $contentType); + return new PhpQueryObject($documentID); } - return true; - } - /** - * Unloades all or specified document from memory. - * - * @param mixed $documentID @see phpQuery::getDocumentID() for supported types. - */ - public static function unloadDocuments($id = null) { - if (isset($id)) { - if ($id = self::getDocumentID($id)) - unset(phpQuery::$documents[$id]); + + /** + * Creates new document from markup. + * Chainable. + * + * @param $file + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileHTML($file, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "text/html{$contentType}"); } - else { - foreach (phpQuery::$documents as $k => $v) { - unset(phpQuery::$documents[$k]); - } + + /** + * Creates new document from markup. + * Chainable. + * + * @param $file + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileXML($file, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "text/xml{$contentType}"); } - } - /** - * Parses phpQuery object or HTML result against PHP tags and makes them active. - * - * @param phpQuery|string $content - * @deprecated - * @return string - */ - public static function unsafePHPTags($content) { - return self::markupToPHP($content); - } - public static function DOMNodeListToArray($DOMNodeList) { - $array = array(); - if (!$DOMNodeList) - return $array; - foreach ($DOMNodeList as $node) - $array[] = $node; - return $array; - } - /** - * Checks if $input is HTML string, which has to start with '<'. - * - * @deprecated - * @param String $input - * @return Bool - * @todo still used ? - */ - public static function isMarkup($input) { - return is_string($input) && substr(trim($input), 0, 1) == '<'; - } - public static function debug($text) { - if (self::$debug) - print var_dump($text); - } - /** - * Make an AJAX request. - * - * @param array See $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions - * Additional options are: - * 'document' - document for global events, @see phpQuery::getDocumentID() - * 'referer' - implemented - * 'requested_with' - TODO; not implemented (X-Requested-With) - * @return Zend_Http_Client - * @link http://docs.jquery.com/Ajax/jQuery.ajax - * - * @TODO $options['cache'] - * @TODO $options['processData'] - * @TODO $options['xhr'] - * @TODO $options['data'] as string - * @TODO XHR interface - */ - public static function ajax($options = array(), $xhr = null) { - $options = array_merge(self::$ajaxSettings, $options); - $documentID = isset($options['document']) ? self::getDocumentID($options['document']) - : null; - if ($xhr) { - // reuse existing XHR object, but clean it up - $client = $xhr; - // $client->setParameterPost(null); - // $client->setParameterGet(null); - $client->setAuth(false); - $client->setHeaders("If-Modified-Since", null); - $client->setHeaders("Referer", null); - $client->resetParameters(); + + /** + * Creates new document from markup. + * Chainable. + * + * @param $file + * @param null $charset + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFileXHTML($file, $charset = null) + { + $contentType = $charset ? ";charset=$charset" : ''; + return self::newDocumentFile($file, "application/xhtml+xml{$contentType}"); } - else { - // create new XHR object - $client = new Zend_Http_Client(); - $client->setCookieJar(); + + /** + * Creates new document from markup. + * Chainable. + * + * @param $file + * @param null $contentType + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public static function newDocumentFilePHP($file, $contentType = null) + { + return self::newDocumentPHP(file_get_contents($file), $contentType); } - if (isset($options['timeout'])) - $client->setConfig(array( - 'timeout' => $options['timeout'], - )); - // 'maxredirects' => 0, - foreach (self::$ajaxAllowedHosts as $k => $host) - if ($host == '.' && isset($_SERVER['HTTP_HOST'])) - self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST']; - $host = parse_url($options['url'], PHP_URL_HOST); - if (!in_array($host, self::$ajaxAllowedHosts)) { - throw new \Exception("Request not permitted, host '$host' not present in " - . "phpQuery::\$ajaxAllowedHosts"); + + /** + * Reuses existing \DOMDocument object. + * Chainable. + * + * @param $document \DOMDocument + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support \DOMDocument + */ + public static function loadDocument($document) + { + // TODO + die('TODO loadDocument'); } - // JSONP - $jsre = "/=\\?(&|$)/"; - if (isset($options['dataType']) && $options['dataType'] == 'jsonp') { - $jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback'; - if (strtolower($options['type']) == 'get') { - if (!preg_match($jsre, $options['url'])) { - $sep = strpos($options['url'], '?') ? '&' : '?'; - $options['url'] .= "$sep$jsonpCallbackParam=?"; + + /** + * Enter description here... + * + * @param $html + * @param null $contentType + * @param null $documentID + * @return null|string + * @throws \Exception + * @todo support PHP tags in input + * @todo support passing \DOMDocument object from self::loadDocument + */ + protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) + { + if (function_exists('domxml_open_mem')) + throw new \Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); + // $id = $documentID + // ? $documentID + // : md5(microtime()); + $document = null; + if ($html instanceof \DOMDocument) { + if (self::getDocumentID($html)) { + // document already exists in phpQuery::$documents, make a copy + $document = clone $html; + } else { + // new document, add it to phpQuery::$documents + $wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID); + } + } else { + $wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID); } - } - else if ($options['data']) { - $jsonp = false; - foreach ($options['data'] as $n => $v) { - if ($v == '?') - $jsonp = true; + // $wrapper->id = $id; + // bind document + phpQuery::$documents[$wrapper->id] = $wrapper; + // remember last loaded document + phpQuery::selectDocument($wrapper->id); + return $wrapper->id; + } + + /** + * Extend class namespace. + * + * @param string|array $target + * @param array $source + * @throws \Exception + * @return bool + * @TODO support string $source + */ + public static function extend($target, $source) + { + switch ($target) { + case 'PhpQueryObject': + $targetRef = & self::$extendMethods; + $targetRef2 = & self::$pluginsMethods; + break; + case 'phpQuery': + $targetRef = & self::$extendStaticMethods; + $targetRef2 = & self::$pluginsStaticMethods; + break; + default: + throw new \Exception("Unsupported \$target type"); } - if (!$jsonp) { - $options['data'][$jsonpCallbackParam] = '?'; + if (is_string($source)) + $source = array( + $source => $source + ); + foreach ($source as $method => $callback) { + if (isset($targetRef[$method])) { + // throw new \Exception + self::debug("Duplicate method '{$method}', can\'t extend '{$target}'"); + continue; + } + if (isset($targetRef2[$method])) { + // throw new \Exception + self::debug( + "Duplicate method '{$method}' from plugin '{$targetRef2[$method]}'," + . " can\'t extend '{$target}'" + ); + continue; + } + $targetRef[$method] = $callback; } - } - $options['dataType'] = 'json'; + return true; } - if (isset($options['dataType']) && $options['dataType'] == 'json') { - $jsonpCallback = 'json_' . md5(microtime()); - $jsonpData = $jsonpUrl = false; - if ($options['data']) { - foreach ($options['data'] as $n => $v) { - if ($v == '?') - $jsonpData = $n; + + /** + * Extend phpQuery with $class from $file. + * + * @param string $class Extending class name. Real class name can be prepended phpQuery_. + * @param string $file Filename to include. Defaults to "{$class}.php". + * @throws \Exception + * @return bool + */ + public static function plugin($class, $file = null) + { + // TODO $class checked agains phpQuery_$class + // if (strpos($class, 'phpQuery') === 0) + // $class = substr($class, 8); + if (in_array($class, self::$pluginsLoaded)) + return true; + if (!$file) + $file = $class . '.php'; + $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class); + $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class); + if (!$objectClassExists && !$staticClassExists) + require_once($file); + self::$pluginsLoaded[] = $class; + // static methods + if (class_exists('\PhpQuery\Plugin\Util' . $class)) { + $realClass = '\PhpQuery\Plugin\Util' . $class; + $vars = get_class_vars($realClass); + $loop = isset($vars['phpQueryMethods']) + && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + : get_class_methods($realClass); + foreach ($loop as $method) { + if ($method == '__initialize') + continue; + if (!is_callable( + array( + $realClass, + $method + ) + ) + ) + continue; + if (isset(self::$pluginsStaticMethods[$method])) { + throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '" + . self::$pluginsStaticMethods[$method] . "'"); + } + self::$pluginsStaticMethods[$method] = $class; + } + if (method_exists($realClass, '__initialize')) + call_user_func_array( + array( + $realClass, + '__initialize' + ), + array() + ); } - } - if (preg_match($jsre, $options['url'])) - $jsonpUrl = true; - if ($jsonpData !== false || $jsonpUrl) { - // remember callback name for httpData() - $options['_jsonp'] = $jsonpCallback; - if ($jsonpData !== false) - $options['data'][$jsonpData] = $jsonpCallback; - if ($jsonpUrl) - $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']); - } - } - $client->setUri($options['url']); - $client->setMethod(strtoupper($options['type'])); - if (isset($options['referer']) && $options['referer']) - $client->setHeaders('Referer', $options['referer']); - $client->setHeaders(array( - // 'content-type' => $options['contentType'], - 'User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko' - . '/2008122010 Firefox/3.0.5', - // TODO custom charset - 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', - // 'Connection' => 'keep-alive', - // 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'Accept-Language' => 'en-us,en;q=0.5', - )); - if ($options['username']) - $client->setAuth($options['username'], $options['password']); - if (isset($options['ifModified']) && $options['ifModified']) - $client->setHeaders("If-Modified-Since", self::$lastModified ? self::$lastModified - : "Thu, 01 Jan 1970 00:00:00 GMT"); - $client->setHeaders("Accept", isset($options['dataType']) - && isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']] - . ", */*" : self::$ajaxSettings['accepts']['_default']); - // TODO $options['processData'] - if ($options['data'] instanceof PhpQueryObject) { - $serialized = $options['data']->serializeArray($options['data']); - $options['data'] = array(); - foreach ($serialized as $r) - $options['data'][$r['name']] = $r['value']; - } - if (strtolower($options['type']) == 'get') { - $client->setParameterGet($options['data']); + // object methods + if (class_exists('\\PhpQuery\\Plugin\\' . $class)) { + $realClass = '\\PhpQuery\\Plugin\\' . $class; + $vars = get_class_vars($realClass); + $loop = isset($vars['phpQueryMethods']) + && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + : get_class_methods($realClass); + foreach ($loop as $method) { + if (!is_callable( + array( + $realClass, + $method + ) + ) + ) + continue; + if (isset(self::$pluginsMethods[$method])) { + throw new \Exception("Duplicate method '{$method}' from plugin '{$class}' conflicts with same method from plugin '" + . self::$pluginsMethods[$method] . "'"); + continue; + } + self::$pluginsMethods[$method] = $class; + } + } + return true; } - else if (strtolower($options['type']) == 'post') { - $client->setEncType($options['contentType']); - $client->setParameterPost($options['data']); + + /** + * Unloades all or specified document from memory. + * + * @param null $id + * @internal param mixed $documentID @see phpQuery::getDocumentID() for supported types. + */ + public static function unloadDocuments($id = null) + { + if (isset($id)) { + if ($id = self::getDocumentID($id)) + unset(phpQuery::$documents[$id]); + } else { + foreach (phpQuery::$documents as $k => $v) { + unset(phpQuery::$documents[$k]); + } + } } - if (self::$active == 0 && $options['global']) - phpQueryEvents::trigger($documentID, 'ajaxStart'); - self::$active++; - // beforeSend callback - if (isset($options['beforeSend']) && $options['beforeSend']) - phpQuery::callbackRun($options['beforeSend'], array( - $client - )); - // ajaxSend event - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxSend', array( - $client, - $options - )); - if (phpQuery::$debug) { - self::debug("{$options['type']}: {$options['url']}\n"); - self::debug("Options:
    " . var_export($options, true) . "
    \n"); - // if ($client->getCookieJar()) - // self::debug("Cookies:
    ".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."
    \n"); + + /** + * Parses phpQuery object or HTML result against PHP tags and makes them active. + * + * @param phpQuery|string $content + * @deprecated + * @return string + */ + public static function unsafePHPTags($content) + { + return self::markupToPHP($content); } - // request - $response = $client->request(); - if (phpQuery::$debug) { - self::debug('Status: ' . $response->getStatus() . ' / ' - . $response->getMessage()); - self::debug($client->getLastRequest()); - self::debug($response->getHeaders()); + + public static function DOMNodeListToArray($DOMNodeList) + { + $array = array(); + if (!$DOMNodeList) + return $array; + foreach ($DOMNodeList as $node) + $array[] = $node; + return $array; } - if ($response->isSuccessful()) { - // XXX tempolary - self::$lastModified = $response->getHeader('Last-Modified'); - $data = self::httpData($response->getBody(), $options['dataType'], $options); - if (isset($options['success']) && $options['success']) - phpQuery::callbackRun($options['success'], array( - $data, - $response->getStatus(), - $options - )); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxSuccess', array( - $client, - $options - )); + + /** + * Checks if $input is HTML string, which has to start with '<'. + * + * @deprecated + * @param String $input + * @return Bool + * @todo still used ? + */ + public static function isMarkup($input) + { + return is_string($input) && substr(trim($input), 0, 1) == '<'; } - else { - if (isset($options['error']) && $options['error']) - phpQuery::callbackRun($options['error'], array( - $client, - $response->getStatus(), - $response->getMessage() - )); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxError', array( - $client, - /*$response->getStatus(),*/$response->getMessage(), - $options - )); + + public static function debug($text) + { + if (self::$debug) + print var_dump($text); } - if (isset($options['complete']) && $options['complete']) - phpQuery::callbackRun($options['complete'], array( - $client, - $response->getStatus() - )); - if ($options['global']) - phpQueryEvents::trigger($documentID, 'ajaxComplete', array( - $client, - $options - )); - if ($options['global'] && !--self::$active) - phpQueryEvents::trigger($documentID, 'ajaxStop'); - return $client; - // if (is_null($domId)) - // $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; - // return new phpQueryAjaxResponse($response, $domId); - } - protected static function httpData($data, $type, $options) { - if (isset($options['dataFilter']) && $options['dataFilter']) - $data = self::callbackRun($options['dataFilter'], array( - $data, - $type - )); - if (is_string($data)) { - if ($type == "json") { - if (isset($options['_jsonp']) && $options['_jsonp']) { - $data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data); + + /** + * Make an AJAX request. + * + * @param array $options + * @param null $xhr + * @throws \Exception + * @internal param \PhpQuery\See $array $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions + * Additional options are: + * 'document' - document for global events, @see phpQuery::getDocumentID() + * 'referer' - implemented + * 'requested_with' - TODO; not implemented (X-Requested-With) + * @return \Zend_Http_Client + * @link http://docs.jquery.com/Ajax/jQuery.ajax + * + * @TODO $options['cache'] + * @TODO $options['processData'] + * @TODO $options['xhr'] + * @TODO $options['data'] as string + * @TODO XHR interface + */ + public static function ajax($options = array(), $xhr = null) + { + $options = array_merge(self::$ajaxSettings, $options); + $documentID = isset($options['document']) ? self::getDocumentID($options['document']) + : null; + if ($xhr) { + // reuse existing XHR object, but clean it up + $client = $xhr; + // $client->setParameterPost(null); + // $client->setParameterGet(null); + $client->setAuth(false); + $client->setHeaders("If-Modified-Since", null); + $client->setHeaders("Referer", null); + $client->resetParameters(); + } else { + // create new XHR object + $client = new \Zend_Http_Client(); + $client->setCookieJar(); + } + if (isset($options['timeout'])) + $client->setConfig( + array( + 'timeout' => $options['timeout'], + ) + ); + // 'maxredirects' => 0, + foreach (self::$ajaxAllowedHosts as $k => $host) + if ($host == '.' && isset($_SERVER['HTTP_HOST'])) + self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST']; + $host = parse_url($options['url'], PHP_URL_HOST); + if (!in_array($host, self::$ajaxAllowedHosts)) { + throw new \Exception("Request not permitted, host '$host' not present in " + . "phpQuery::\$ajaxAllowedHosts"); + } + // JSONP + $jsre = "/=\\?(&|$)/"; + if (isset($options['dataType']) && $options['dataType'] == 'jsonp') { + $jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback'; + if (strtolower($options['type']) == 'get') { + if (!preg_match($jsre, $options['url'])) { + $sep = strpos($options['url'], '?') ? '&' : '?'; + $options['url'] .= "$sep$jsonpCallbackParam=?"; + } + } else if ($options['data']) { + $jsonp = false; + foreach ($options['data'] as $n => $v) { + if ($v == '?') + $jsonp = true; + } + if (!$jsonp) { + $options['data'][$jsonpCallbackParam] = '?'; + } + } + $options['dataType'] = 'json'; + } + if (isset($options['dataType']) && $options['dataType'] == 'json') { + $jsonpCallback = 'json_' . md5(microtime()); + $jsonpData = $jsonpUrl = false; + if ($options['data']) { + foreach ($options['data'] as $n => $v) { + if ($v == '?') + $jsonpData = $n; + } + } + if (preg_match($jsre, $options['url'])) + $jsonpUrl = true; + if ($jsonpData !== false || $jsonpUrl) { + // remember callback name for httpData() + $options['_jsonp'] = $jsonpCallback; + if ($jsonpData !== false) + $options['data'][$jsonpData] = $jsonpCallback; + if ($jsonpUrl) + $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']); + } + } + $client->setUri($options['url']); + $client->setMethod(strtoupper($options['type'])); + if (isset($options['referer']) && $options['referer']) + $client->setHeaders('Referer', $options['referer']); + $client->setHeaders( + array( + // 'content-type' => $options['contentType'], + 'User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko' + . '/2008122010 Firefox/3.0.5', + // TODO custom charset + 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', + // 'Connection' => 'keep-alive', + // 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Language' => 'en-us,en;q=0.5', + ) + ); + if ($options['username']) + $client->setAuth($options['username'], $options['password']); + if (isset($options['ifModified']) && $options['ifModified']) + $client->setHeaders( + "If-Modified-Since", + self::$lastModified ? self::$lastModified + : "Thu, 01 Jan 1970 00:00:00 GMT" + ); + $client->setHeaders( + "Accept", + isset($options['dataType']) + && isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']] + . ", */*" : self::$ajaxSettings['accepts']['_default'] + ); + // TODO $options['processData'] + if ($options['data'] instanceof PhpQueryObject) { + $serialized = $options['data']->serializeArray($options['data']); + $options['data'] = array(); + foreach ($serialized as $r) + $options['data'][$r['name']] = $r['value']; + } + if (strtolower($options['type']) == 'get') { + $client->setParameterGet($options['data']); + } else if (strtolower($options['type']) == 'post') { + $client->setEncType($options['contentType']); + $client->setParameterPost($options['data']); + } + if (self::$active == 0 && $options['global']) + phpQueryEvents::trigger($documentID, 'ajaxStart'); + self::$active++; + // beforeSend callback + if (isset($options['beforeSend']) && $options['beforeSend']) + phpQuery::callbackRun( + $options['beforeSend'], + array( + $client + ) + ); + // ajaxSend event + if ($options['global']) + phpQueryEvents::trigger( + $documentID, + 'ajaxSend', + array( + $client, + $options + ) + ); + if (phpQuery::$debug) { + self::debug("{$options['type']}: {$options['url']}\n"); + self::debug("Options:
    " . var_export($options, true) . "
    \n"); + // if ($client->getCookieJar()) + // self::debug("Cookies:
    ".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."
    \n"); + } + // request + $response = $client->request(); + if (phpQuery::$debug) { + self::debug( + 'Status: ' . $response->getStatus() . ' / ' + . $response->getMessage() + ); + self::debug($client->getLastRequest()); + self::debug($response->getHeaders()); + } + if ($response->isSuccessful()) { + // XXX tempolary + self::$lastModified = $response->getHeader('Last-Modified'); + $data = self::httpData($response->getBody(), $options['dataType'], $options); + if (isset($options['success']) && $options['success']) + phpQuery::callbackRun( + $options['success'], + array( + $data, + $response->getStatus(), + $options + ) + ); + if ($options['global']) + phpQueryEvents::trigger( + $documentID, + 'ajaxSuccess', + array( + $client, + $options + ) + ); + } else { + if (isset($options['error']) && $options['error']) + phpQuery::callbackRun( + $options['error'], + array( + $client, + $response->getStatus(), + $response->getMessage() + ) + ); + if ($options['global']) + phpQueryEvents::trigger( + $documentID, + 'ajaxError', + array( + $client, + /*$response->getStatus(),*/ + $response->getMessage(), + $options + ) + ); } - $data = self::parseJSON($data); - } + if (isset($options['complete']) && $options['complete']) + phpQuery::callbackRun( + $options['complete'], + array( + $client, + $response->getStatus() + ) + ); + if ($options['global']) + phpQueryEvents::trigger( + $documentID, + 'ajaxComplete', + array( + $client, + $options + ) + ); + if ($options['global'] && !--self::$active) + phpQueryEvents::trigger($documentID, 'ajaxStop'); + return $client; + // if (is_null($domId)) + // $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; + // return new phpQueryAjaxResponse($response, $domId); } - return $data; - } - /** - * Enter description here... - * - * @param array|phpQuery $data - * - */ - public static function param($data) { - return http_build_query($data, null, '&'); - } - public static function get($url, $data = null, $callback = null, $type = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; + + protected static function httpData($data, $type, $options) + { + if (isset($options['dataFilter']) && $options['dataFilter']) + $data = self::callbackRun( + $options['dataFilter'], + array( + $data, + $type + ) + ); + if (is_string($data)) { + if ($type == "json") { + if (isset($options['_jsonp']) && $options['_jsonp']) { + $data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data); + } + $data = self::parseJSON($data); + } + } + return $data; } - // TODO some array_values on this shit - return phpQuery::ajax(array( - 'type' => 'GET', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => $type, - )); - } - public static function post($url, $data = null, $callback = null, $type = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; + + /** + * Enter description here... + * + * @param array|phpQuery $data + * + * @return string + */ + public static function param($data) + { + return http_build_query($data, null, '&'); } - return phpQuery::ajax(array( - 'type' => 'POST', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => $type, - )); - } - public static function getJSON($url, $data = null, $callback = null) { - if (!is_array($data)) { - $callback = $data; - $data = null; + + public static function get($url, $data = null, $callback = null, $type = null) + { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + // TODO some array_values on this shit + return phpQuery::ajax( + array( + 'type' => 'GET', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => $type, + ) + ); } - // TODO some array_values on this shit - return phpQuery::ajax(array( - 'type' => 'GET', - 'url' => $url, - 'data' => $data, - 'success' => $callback, - 'dataType' => 'json', - )); - } - public static function ajaxSetup($options) { - self::$ajaxSettings = array_merge(self::$ajaxSettings, $options); - } - public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) { - $loop = is_array($host1) ? $host1 : func_get_args(); - foreach ($loop as $host) { - if ($host && !in_array($host, phpQuery::$ajaxAllowedHosts)) { - phpQuery::$ajaxAllowedHosts[] = $host; - } + + public static function post($url, $data = null, $callback = null, $type = null) + { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + return phpQuery::ajax( + array( + 'type' => 'POST', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => $type, + ) + ); } - } - public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) { - $loop = is_array($url1) ? $url1 : func_get_args(); - foreach ($loop as $url) - phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); - } - /** - * Returns JSON representation of $data. - * - * @static - * @param mixed $data - * @return string - */ - public static function toJSON($data) { - if (function_exists('json_encode')) - return json_encode($data); - require_once('Zend/Json/Encoder.php'); - return Zend_Json_Encoder::encode($data); - } - /** - * Parses JSON into proper PHP type. - * - * @static - * @param string $json - * @return mixed - */ - public static function parseJSON($json) { - if (function_exists('json_decode')) { - $return = json_decode(trim($json), true); - // json_decode and UTF8 issues - if (isset($return)) - return $return; + + public static function getJSON($url, $data = null, $callback = null) + { + if (!is_array($data)) { + $callback = $data; + $data = null; + } + // TODO some array_values on this shit + return phpQuery::ajax( + array( + 'type' => 'GET', + 'url' => $url, + 'data' => $data, + 'success' => $callback, + 'dataType' => 'json', + ) + ); } - require_once('Zend/Json/Decoder.php'); - return Zend_Json_Decoder::decode($json); - } - /** - * Returns source's document ID. - * - * @param $source \DOMNode|PhpQueryObject - * @return string - */ - public static function getDocumentID($source) { - if ($source instanceof \DOMDocument) { - foreach (phpQuery::$documents as $id => $document) { - if ($source->isSameNode($document->document)) - return $id; - } + + public static function ajaxSetup($options) + { + self::$ajaxSettings = array_merge(self::$ajaxSettings, $options); } - else if ($source instanceof \DOMNode) { - foreach (phpQuery::$documents as $id => $document) { - if ($source->ownerDocument->isSameNode($document->document)) - return $id; - } + + public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) + { + $loop = is_array($host1) ? $host1 : func_get_args(); + foreach ($loop as $host) { + if ($host && !in_array($host, phpQuery::$ajaxAllowedHosts)) { + phpQuery::$ajaxAllowedHosts[] = $host; + } + } } - else if ($source instanceof PhpQueryObject) - return $source->getDocumentID(); - else if (is_string($source) && isset(phpQuery::$documents[$source])) - return $source; - } - /** - * Get \DOMDocument object related to $source. - * Returns null if such document doesn't exist. - * - * @param $source \DOMNode|PhpQueryObject|string - * @return string - */ - public static function getDOMDocument($source) { - if ($source instanceof \DOMDocument) - return $source; - $source = self::getDocumentID($source); - return $source ? self::$documents[$id]['document'] : null; - } - - // UTILITIES - // http://docs.jquery.com/Utilities - - /** - * - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.makeArray - */ - public static function makeArray($obj) { - $array = array(); - if (is_object($object) && $object instanceof \DOMNodeList) { - foreach ($object as $value) - $array[] = $value; + + public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) + { + $loop = is_array($url1) ? $url1 : func_get_args(); + foreach ($loop as $url) + phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); } - else if (is_object($object) && !($object instanceof Iterator)) { - foreach (get_object_vars($object) as $name => $value) - $array[0][$name] = $value; + + /** + * Returns JSON representation of $data. + * + * @static + * @param mixed $data + * @return string + */ + public static function toJSON($data) + { + if (function_exists('json_encode')) + return json_encode($data); + require_once('Zend/Json/Encoder.php'); + return \Zend_Json_Encoder::encode($data); } - else { - foreach ($object as $name => $value) - $array[0][$name] = $value; + + /** + * Parses JSON into proper PHP type. + * + * @static + * @param string $json + * @return mixed + */ + public static function parseJSON($json) + { + if (function_exists('json_decode')) { + $return = json_decode(trim($json), true); + // json_decode and UTF8 issues + if (isset($return)) + return $return; + } + require_once('Zend/Json/Decoder.php'); + return \Zend_Json_Decoder::decode($json); } - return $array; - } - public static function inArray($value, $array) { - return in_array($value, $array); - } - /** - * - * @param $object - * @param $callback - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.each - */ - public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null) { - $paramStructure = null; - if (func_num_args() > 2) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 2); + + /** + * Returns source's document ID. + * + * @param $source \DOMNode|PhpQueryObject + * @return string + */ + public static function getDocumentID($source) + { + if ($source instanceof \DOMDocument) { + foreach (phpQuery::$documents as $id => $document) { + if ($source->isSameNode($document->document)) + return $id; + } + } else if ($source instanceof \DOMNode) { + foreach (phpQuery::$documents as $id => $document) { + if ($source->ownerDocument->isSameNode($document->document)) + return $id; + } + } else if ($source instanceof PhpQueryObject) + return $source->getDocumentID(); + else if (is_string($source) && isset(phpQuery::$documents[$source])) + return $source; } - if (is_object($object) && !($object instanceof Iterator)) { - foreach (get_object_vars($object) as $name => $value) - phpQuery::callbackRun($callback, array( - $name, - $value - ), $paramStructure); + + /** + * Get \DOMDocument object related to $source. + * Returns null if such document doesn't exist. + * + * @param $source \DOMNode|PhpQueryObject|string + * @return string + */ + public static function getDOMDocument($source) + { + if ($source instanceof \DOMDocument) + return $source; + $source = self::getDocumentID($source); + return $source ? self::$documents[$id]['document'] : null; } - else { - foreach ($object as $name => $value) - phpQuery::callbackRun($callback, array( - $name, - $value - ), $paramStructure); + + // UTILITIES + // http://docs.jquery.com/Utilities + + /** + * + * @link http://docs.jquery.com/Utilities/jQuery.makeArray + * @param $object + * @return array + */ + public static function makeArray($object) + { + $array = array(); + if (is_object($object) && $object instanceof \DOMNodeList) { + foreach ($object as $value) + $array[] = $value; + } else if (is_object($object) && !($object instanceof \Iterator)) { + foreach (get_object_vars($object) as $name => $value) + $array[0][$name] = $value; + } else { + foreach ($object as $name => $value) + $array[0][$name] = $value; + } + return $array; } - } - /** - * - * @link http://docs.jquery.com/Utilities/jQuery.map - */ - public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null) { - $result = array(); - $paramStructure = null; - if (func_num_args() > 2) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 2); + + public static function inArray($value, $array) + { + return in_array($value, $array); } - foreach ($array as $v) { - $vv = phpQuery::callbackRun($callback, array( - $v - ), $paramStructure); - // $callbackArgs = $args; - // foreach($args as $i => $arg) { - // $callbackArgs[$i] = $arg instanceof CallbackParam - // ? $v - // : $arg; - // } - // $vv = call_user_func_array($callback, $callbackArgs); - if (is_array($vv)) { - foreach ($vv as $vvv) - $result[] = $vvv; - } - else if ($vv !== null) { - $result[] = $vv; - } + + /** + * + * @param $object + * @param $callback + * @param null $param1 + * @param null $param2 + * @param null $param3 + * @link http://docs.jquery.com/Utilities/jQuery.each + */ + public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null) + { + $paramStructure = null; + if (func_num_args() > 2) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 2); + } + if (is_object($object) && !($object instanceof \Iterator)) { + foreach (get_object_vars($object) as $name => $value) + phpQuery::callbackRun( + $callback, + array( + $name, + $value + ), + $paramStructure + ); + } else { + foreach ($object as $name => $value) + phpQuery::callbackRun( + $callback, + array( + $name, + $value + ), + $paramStructure + ); + } } - return $result; - } - /** - * - * @param $callback Callback - * @param $params - * @param $paramStructure - * @return unknown_type - */ - public static function callbackRun($callback, $params = array(), $paramStructure = null) { - if (!$callback) - return; - if ($callback instanceof CallbackParameterToReference) { - // TODO support ParamStructure to select which $param push to reference - if (isset($params[0])) - $callback->callback = $params[0]; - return true; + + /** + * + * @link http://docs.jquery.com/Utilities/jQuery.map + */ + public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null) + { + $result = array(); + $paramStructure = null; + if (func_num_args() > 2) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 2); + } + foreach ($array as $v) { + $vv = phpQuery::callbackRun( + $callback, + array( + $v + ), + $paramStructure + ); + // $callbackArgs = $args; + // foreach($args as $i => $arg) { + // $callbackArgs[$i] = $arg instanceof CallbackParam + // ? $v + // : $arg; + // } + // $vv = call_user_func_array($callback, $callbackArgs); + if (is_array($vv)) { + foreach ($vv as $vvv) + $result[] = $vvv; + } else if ($vv !== null) { + $result[] = $vv; + } + } + return $result; } - if ($callback instanceof Callback) { - $paramStructure = $callback->params; - $callback = $callback->callback; + + /** + * + * @param $callback Callback + * @param $params + * @param $paramStructure + * @return bool|mixed + */ + public static function callbackRun($callback, $params = array(), $paramStructure = null) + { + if (!$callback) + return; + if ($callback instanceof \CallbackParameterToReference) { + // TODO support ParamStructure to select which $param push to reference + if (isset($params[0])) + $callback->callback = $params[0]; + return true; + } + if ($callback instanceof \Callback) { + $paramStructure = $callback->params; + $callback = $callback->callback; + } + if (!$paramStructure) + return call_user_func_array($callback, $params); + $p = 0; + foreach ($paramStructure as $i => $v) { + $paramStructure[$i] = $v instanceof \CallbackParam ? $params[$p++] : $v; + } + return call_user_func_array($callback, $paramStructure); } - if (!$paramStructure) - return call_user_func_array($callback, $params); - $p = 0; - foreach ($paramStructure as $i => $v) { - $paramStructure[$i] = $v instanceof CallbackParam ? $params[$p++] : $v; + + /** + * Merge 2 phpQuery objects. + * @param array $one + * @param array $two + * @return array + * @protected + * @todo node lists, PhpQueryObject + */ + public static function merge($one, $two) + { + $elements = $one->elements; + foreach ($two->elements as $node) { + $exists = false; + foreach ($elements as $node2) { + if ($node2->isSameNode($node)) + $exists = true; + } + if (!$exists) + $elements[] = $node; + } + return $elements; + // $one = $one->newInstance(); + // $one->elements = $elements; + // return $one; } - return call_user_func_array($callback, $paramStructure); - } - /** - * Merge 2 phpQuery objects. - * @param array $one - * @param array $two - * @protected - * @todo node lists, PhpQueryObject - */ - public static function merge($one, $two) { - $elements = $one->elements; - foreach ($two->elements as $node) { - $exists = false; - foreach ($elements as $node2) { - if ($node2->isSameNode($node)) - $exists = true; - } - if (!$exists) - $elements[] = $node; + + /** + * + * @param $array + * @param $callback + * @param $invert + * @return array + * @link http://docs.jquery.com/Utilities/jQuery.grep + */ + public static function grep($array, $callback, $invert = false) + { + $result = array(); + foreach ($array as $k => $v) { + $r = call_user_func_array( + $callback, + array( + $v, + $k + ) + ); + if ($r === !(bool) $invert) + $result[] = $v; + } + return $result; } - return $elements; - // $one = $one->newInstance(); - // $one->elements = $elements; - // return $one; - } - /** - * - * @param $array - * @param $callback - * @param $invert - * @return unknown_type - * @link http://docs.jquery.com/Utilities/jQuery.grep - */ - public static function grep($array, $callback, $invert = false) { - $result = array(); - foreach ($array as $k => $v) { - $r = call_user_func_array($callback, array( - $v, - $k - )); - if ($r === !(bool) $invert) - $result[] = $v; + + public static function unique($array) + { + return array_unique($array); } - return $result; - } - public static function unique($array) { - return array_unique($array); - } - /** - * - * @param $function - * @return unknown_type - * @TODO there are problems with non-static methods, second parameter pass it - * but doesnt verify is method is really callable - */ - public static function isFunction($function) { - return is_callable($function); - } - public static function trim($str) { - return trim($str); - } - /* PLUGINS NAMESPACE */ - /** - * - * @param $url - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return PhpQueryObject - */ - public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array( - self::$plugins, - 'browserGet' - ), $params); + + /** + * + * @param $function + * @return bool + * @TODO there are problems with non-static methods, second parameter pass it + * but doesnt verify is method is really callable + */ + public static function isFunction($function) + { + return is_callable($function); } - else { - self::debug('WebBrowser plugin not available...'); + + public static function trim($str) + { + return trim($str); + } + /* PLUGINS NAMESPACE */ + /** + * + * @param $url + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) + { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun( + array( + self::$plugins, + 'browserGet' + ), + $params + ); + } else { + self::debug('WebBrowser plugin not available...'); + } } - } - /** - * - * @param $url - * @param $data - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return PhpQueryObject - */ - public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array( - self::$plugins, - 'browserPost' - ), $params); + + /** + * + * @param $url + * @param $data + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) + { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun( + array( + self::$plugins, + 'browserPost' + ), + $params + ); + } else { + self::debug('WebBrowser plugin not available...'); + } } - else { - self::debug('WebBrowser plugin not available...'); + + /** + * + * @param $ajaxSettings + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @return PhpQueryObject + */ + public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null) + { + if (self::plugin('WebBrowser')) { + $params = func_get_args(); + return self::callbackRun( + array( + self::$plugins, + 'browser' + ), + $params + ); + } else { + self::debug('WebBrowser plugin not available...'); + } } - } - /** - * - * @param $ajaxSettings - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return PhpQueryObject - */ - public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null) { - if (self::plugin('WebBrowser')) { - $params = func_get_args(); - return self::callbackRun(array( - self::$plugins, - 'browser' - ), $params); + + /** + * + * @param $code + * @return string + */ + public static function php($code) + { + return self::code('php', $code); } - else { - self::debug('WebBrowser plugin not available...'); + + /** + * + * @param $type + * @param $code + * @return string + */ + public static function code($type, $code) + { + return "<$type>"; } - } - /** - * - * @param $code - * @return string - */ - public static function php($code) { - return self::code('php', $code); - } - /** - * - * @param $type - * @param $code - * @return string - */ - public static function code($type, $code) { - return "<$type>"; - } - - public static function __callStatic($method, $params) { - return call_user_func_array(array( - phpQuery::$plugins, - $method - ), $params); - } - protected static function dataSetupNode($node, $documentID) { - // search are return if alredy exists - foreach (phpQuery::$documents[$documentID]->dataNodes as $dataNode) { - if ($node->isSameNode($dataNode)) - return $dataNode; + + public static function __callStatic($method, $params) + { + return call_user_func_array( + array( + phpQuery::$plugins, + $method + ), + $params + ); } - // if doesn't, add it - phpQuery::$documents[$documentID]->dataNodes[] = $node; - return $node; - } - protected static function dataRemoveNode($node, $documentID) { - // search are return if alredy exists - foreach (phpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { - if ($node->isSameNode($dataNode)) { - unset(self::$documents[$documentID]->dataNodes[$k]); - unset(self::$documents[$documentID]->data[$dataNode->dataID]); - } + + protected static function dataSetupNode($node, $documentID) + { + // search are return if alredy exists + foreach (phpQuery::$documents[$documentID]->dataNodes as $dataNode) { + if ($node->isSameNode($dataNode)) + return $dataNode; + } + // if doesn't, add it + phpQuery::$documents[$documentID]->dataNodes[] = $node; + return $node; } - } - public static function data($node, $name, $data, $documentID = null) { - if (!$documentID) - // TODO check if this works - $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; - $node = self::dataSetupNode($node, $documentID); - if (!isset($node->dataID)) - $node->dataID = ++phpQuery::$documents[$documentID]->uuid; - $id = $node->dataID; - if (!isset($document->data[$id])) - $document->data[$id] = array(); - if (!is_null($data)) - $document->data[$id][$name] = $data; - if ($name) { - if (isset($document->data[$id][$name])) - return $document->data[$id][$name]; + + protected static function dataRemoveNode($node, $documentID) + { + // search are return if alredy exists + foreach (phpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { + if ($node->isSameNode($dataNode)) { + unset(self::$documents[$documentID]->dataNodes[$k]); + unset(self::$documents[$documentID]->data[$dataNode->dataID]); + } + } } - else - return $id; - } - public static function removeData($node, $name, $documentID) { - if (!$documentID) - // TODO check if this works - $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; - $node = self::dataSetupNode($node, $documentID); - $id = $node->dataID; - if ($name) { - if (isset($document->data[$id][$name])) - unset($document->data[$id][$name]); - $name = null; - foreach ($document->data[$id] as $name) - break; - if (!$name) - self::removeData($node, $name, $documentID); + + public static function data($node, $name, $data, $documentID = null) + { + if (!$documentID) + // TODO check if this works + $documentID = self::getDocumentID($node); + $document = phpQuery::$documents[$documentID]; + $node = self::dataSetupNode($node, $documentID); + if (!isset($node->dataID)) + $node->dataID = ++phpQuery::$documents[$documentID]->uuid; + $id = $node->dataID; + if (!isset($document->data[$id])) + $document->data[$id] = array(); + if (!is_null($data)) + $document->data[$id][$name] = $data; + if ($name) { + if (isset($document->data[$id][$name])) + return $document->data[$id][$name]; + } else + return $id; } - else { - self::dataRemoveNode($node, $documentID); + + public static function removeData($node, $name, $documentID) + { + if (!$documentID) + // TODO check if this works + $documentID = self::getDocumentID($node); + $document = phpQuery::$documents[$documentID]; + $node = self::dataSetupNode($node, $documentID); + $id = $node->dataID; + if ($name) { + if (isset($document->data[$id][$name])) + unset($document->data[$id][$name]); + $name = null; + foreach ($document->data[$id] as $name) + break; + if (!$name) + self::removeData($node, $name, $documentID); + } else { + self::dataRemoveNode($node, $documentID); + } } - } } + /** * Plugins static namespace class. * - * @author Tobiasz Cudnik + * @author Tobiasz Cudnik * @package phpQuery - * @todo move plugin methods here (as statics) + * @todo move plugin methods here (as statics) */ -class phpQueryPlugins { - public function __call($method, $args) { - if (isset(phpQuery::$extendStaticMethods[$method])) { - $return = call_user_func_array(phpQuery::$extendStaticMethods[$method], $args); - } - else if (isset(phpQuery::$pluginsStaticMethods[$method])) { - $class = phpQuery::$pluginsStaticMethods[$method]; - $realClass = "\PhpQuery\Plugin\Util$class"; - $return = call_user_func_array(array( - $realClass, - $method - ), $args); - return isset($return) ? $return : $this; +class phpQueryPlugins +{ + public function __call($method, $args) + { + if (isset(phpQuery::$extendStaticMethods[$method])) { + $return = call_user_func_array(phpQuery::$extendStaticMethods[$method], $args); + } else if (isset(phpQuery::$pluginsStaticMethods[$method])) { + $class = phpQuery::$pluginsStaticMethods[$method]; + $realClass = "\PhpQuery\Plugin\Util$class"; + $return = call_user_func_array( + array( + $realClass, + $method + ), + $args + ); + return isset($return) ? $return : $this; + } else + throw new \Exception("Method '{$method}' doesnt exist"); } - else - throw new \Exception("Method '{$method}' doesnt exist"); - } } + // // add plugins dir and Zend framework to include path // set_include_path( // get_include_path() @@ -1391,4 +1641,4 @@ public function __call($method, $args) { phpQuery::$plugins = new phpQueryPlugins(); // include bootstrap file (personal library config) if (file_exists(dirname(__FILE__) . '/phpQuery/bootstrap.php')) - require_once dirname(__FILE__) . '/phpQuery/bootstrap.php'; \ No newline at end of file + require_once dirname(__FILE__) . '/phpQuery/bootstrap.php'; \ No newline at end of file diff --git a/src/PhpQueryEvents.php b/src/PhpQueryEvents.php index 43a001f..6987648 100644 --- a/src/PhpQueryEvents.php +++ b/src/PhpQueryEvents.php @@ -1,161 +1,193 @@ document) - $pq->find('*')->add($pq->document)->trigger($type, $data); - } +abstract class PhpQueryEvents +{ + /** + * Trigger a type of event on every matched element. + * + * + * @TODO exclusive events (with !) + * @TODO global events (test) + * @TODO support more than event in $type (space-separated) + * @param $document + * @param $type + * @param array $data + * @param null $node + */ + public static function trigger($document, $type, $data = array(), $node = null) + { + // trigger: function(type, data, elem, donative, extra) { + $documentID = phpQuery::getDocumentID($document); + $namespace = null; + if (strpos($type, '.') !== false) { + list($name, $namespace) = explode('.', $type); + } else { + $name = $type; + } + if (!$node) { + if (self::issetGlobal($documentID, $type)) { + $pq = phpQuery::getDocument($documentID); + // TODO check add($pq->document) + $pq->find('*')->add($pq->document)->trigger($type, $data); + } + } else { + if (isset($data[0]) && $data[0] instanceof DOMEvent) { + $event = $data[0]; + $event->relatedTarget = $event->target; + $event->target = $node; + $data = array_slice($data, 1); + } else { + $event = new DOMEvent(array( + 'type' => $type, + 'target' => $node, + 'timeStamp' => time(), + )); + } + $i = 0; + while ($node) { + // TODO whois + phpQuery::debug( + "Triggering " . ($i ? "bubbled " : '') + . "event '{$type}' on " . "node \n" + ); + //.PhpQueryObject::whois($node)."\n"); + $event->currentTarget = $node; + $eventNode = self::getNode($documentID, $node); + if (isset($eventNode->eventHandlers)) { + foreach ($eventNode->eventHandlers as $eventType => $handlers) { + $eventNamespace = null; + if (strpos($type, '.') !== false) { + list($eventName, $eventNamespace) = explode('.', $eventType); + } else { + $eventName = $eventType; + } + if ($name != $eventName) { + continue; + } + if ($namespace && $eventNamespace && $namespace != $eventNamespace) { + continue; + } + foreach ($handlers as $handler) { + phpQuery::debug("Calling event handler\n"); + $event->data = $handler['data'] ? $handler['data'] : null; + $params = array_merge( + array( + $event + ), + $data + ); + $return = phpQuery::callbackRun($handler['callback'], $params); + if ($return === false) { + $event->bubbles = false; + } + } + } + } + // to bubble or not to bubble... + if (!$event->bubbles) { + break; + } + $node = $node->parentNode; + $i++; + } + } } - else { - if (isset($data[0]) && $data[0] instanceof DOMEvent) { - $event = $data[0]; - $event->relatedTarget = $event->target; - $event->target = $node; - $data = array_slice($data, 1); - } - else { - $event = new DOMEvent(array( - 'type' => $type, - 'target' => $node, - 'timeStamp' => time(), - )); - } - $i = 0; - while ($node) { - // TODO whois - phpQuery::debug("Triggering " . ($i ? "bubbled " : '') - . "event '{$type}' on " . "node \n");//.PhpQueryObject::whois($node)."\n"); - $event->currentTarget = $node; + + /** + * Binds a handler to one or more events (like click) for each matched element. + * Can also bind custom events. + * + * @param \DOMNode|PhpQueryObject|string $document + * @param $node + * @param string $type + * @param string $data Optional + * @param $callback + * + * @TODO support '!' (exclusive) events + * @TODO support more than event in $type (space-separated) + * @TODO support binding to global events + */ + public static function add($document, $node, $type, $data, $callback = null) + { + phpQuery::debug("Binding '$type' event"); + $documentID = phpQuery::getDocumentID($document); + // if (is_null($callback) && is_callable($data)) { + // $callback = $data; + // $data = null; + // } $eventNode = self::getNode($documentID, $node); - if (isset($eventNode->eventHandlers)) { - foreach ($eventNode->eventHandlers as $eventType => $handlers) { - $eventNamespace = null; - if (strpos($type, '.') !== false) - list($eventName, $eventNamespace) = explode('.', $eventType); - else - $eventName = $eventType; - if ($name != $eventName) - continue; - if ($namespace && $eventNamespace && $namespace != $eventNamespace) - continue; - foreach ($handlers as $handler) { - phpQuery::debug("Calling event handler\n"); - $event->data = $handler['data'] ? $handler['data'] : null; - $params = array_merge(array( - $event - ), $data); - $return = phpQuery::callbackRun($handler['callback'], $params); - if ($return === false) { - $event->bubbles = false; - } + if (!$eventNode) { + $eventNode = self::setNode($documentID, $node); + } + if (!isset($eventNode->eventHandlers[$type])) { + $eventNode->eventHandlers[$type] = array(); + } + $eventNode->eventHandlers[$type][] = array( + 'callback' => $callback, + 'data' => $data, + ); + } + + /** + * Enter description here... + * + * @param \DOMNode|PhpQueryObject|string $document + * @param $node + * @param string $type + * @param $callback + * + * @TODO namespace events + * @TODO support more than event in $type (space-separated) + */ + public static function remove($document, $node, $type = null, $callback = null) + { + $documentID = phpQuery::getDocumentID($document); + $eventNode = self::getNode($documentID, $node); + if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) { + if ($callback) { + foreach ($eventNode->eventHandlers[$type] as $k => $handler) { + if ($handler['callback'] == $callback) { + unset($eventNode->eventHandlers[$type][$k]); + } + } + } else { + unset($eventNode->eventHandlers[$type]); + } + } + } + + protected static function getNode($documentID, $node) + { + foreach (phpQuery::$documents[$documentID]->eventsNodes as $eventNode) { + if ($node->isSameNode($eventNode)) { + return $eventNode; } - } } - // to bubble or not to bubble... - if (!$event->bubbles) - break; - $node = $node->parentNode; - $i++; - } } - } - /** - * Binds a handler to one or more events (like click) for each matched element. - * Can also bind custom events. - * - * @param DOMNode|PhpQueryObject|string $document - * @param unknown_type $type - * @param unknown_type $data Optional - * @param unknown_type $callback - * - * @TODO support '!' (exclusive) events - * @TODO support more than event in $type (space-separated) - * @TODO support binding to global events - */ - public static function add($document, $node, $type, $data, $callback = null) { - phpQuery::debug("Binding '$type' event"); - $documentID = phpQuery::getDocumentID($document); - // if (is_null($callback) && is_callable($data)) { - // $callback = $data; - // $data = null; - // } - $eventNode = self::getNode($documentID, $node); - if (!$eventNode) - $eventNode = self::setNode($documentID, $node); - if (!isset($eventNode->eventHandlers[$type])) - $eventNode->eventHandlers[$type] = array(); - $eventNode->eventHandlers[$type][] = array( - 'callback' => $callback, - 'data' => $data, - ); - } - /** - * Enter description here... - * - * @param DOMNode|PhpQueryObject|string $document - * @param unknown_type $type - * @param unknown_type $callback - * - * @TODO namespace events - * @TODO support more than event in $type (space-separated) - */ - public static function remove($document, $node, $type = null, $callback = null) { - $documentID = phpQuery::getDocumentID($document); - $eventNode = self::getNode($documentID, $node); - if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) { - if ($callback) { - foreach ($eventNode->eventHandlers[$type] as $k => $handler) - if ($handler['callback'] == $callback) - unset($eventNode->eventHandlers[$type][$k]); - } - else { - unset($eventNode->eventHandlers[$type]); - } + + protected static function setNode($documentID, $node) + { + phpQuery::$documents[$documentID]->eventsNodes[] = $node; + return phpQuery::$documents[$documentID]->eventsNodes[count(phpQuery::$documents[$documentID]->eventsNodes) + - 1]; } - } - protected static function getNode($documentID, $node) { - foreach (phpQuery::$documents[$documentID]->eventsNodes as $eventNode) { - if ($node->isSameNode($eventNode)) - return $eventNode; + + protected static function issetGlobal($documentID, $type) + { + return isset(phpQuery::$documents[$documentID]) ? in_array( + $type, + phpQuery::$documents[$documentID]->eventsGlobal + ) + : false; } - } - protected static function setNode($documentID, $node) { - phpQuery::$documents[$documentID]->eventsNodes[] = $node; - return phpQuery::$documents[$documentID]->eventsNodes[count(phpQuery::$documents[$documentID]->eventsNodes) - - 1]; - } - protected static function issetGlobal($documentID, $type) { - return isset(phpQuery::$documents[$documentID]) ? in_array($type, phpQuery::$documents[$documentID]->eventsGlobal) - : false; - } } diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php index 759d443..4b1f8bf 100644 --- a/src/PhpQueryObject.php +++ b/src/PhpQueryObject.php @@ -1,972 +1,1063 @@ + * @author Tobiasz Cudnik * @package phpQuery * @method PhpQueryObject clone() clone() * @method PhpQueryObject empty() empty() - * @method PhpQueryObject next() next($selector = null) - * @method PhpQueryObject prev() prev($selector = null) * @property Int $length */ -class PhpQueryObject implements \Iterator, \Countable, \ArrayAccess { - public $documentID = null; - /** - * \DOMDocument class. - * - * @var \DOMDocument - */ - public $document = null; - public $charset = null; - /** - * - * @var DOMDocumentWrapper - */ - public $documentWrapper = null; - /** - * XPath interface. - * - * @var DOMXPath - */ - public $xpath = null; - /** - * Stack of selected elements. - * @TODO refactor to ->nodes - * @var array - */ - public $elements = array(); - /** - * @access private - */ - protected $elementsBackup = array(); - /** - * @access private - */ - protected $previous = null; - /** - * @access private - * @TODO deprecate - */ - protected $root = array(); - /** - * Indicated if doument is just a fragment (no tag). - * - * Every document is realy a full document, so even documentFragments can - * be queried against , but getDocument(id)->htmlOuter() will return - * only contents of . - * - * @var bool - */ - public $documentFragment = true; - /** - * Iterator interface helper - * @access private - */ - protected $elementsInterator = array(); - /** - * Iterator interface helper - * @access private - */ - protected $valid = false; - /** - * Iterator interface helper - * @access private - */ - protected $current = null; - - /** - * Indicates whether CSS has been parsed or not. We only parse CSS if needed. - * @access private - */ - protected $cssIsParsed = array(); - /** - * A collection of complete CSS selector strings. - * @access private; - */ - protected $cssString = array(); - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - - protected $attribute_css_mapping = array( - 'bgcolor' => 'background-color', - 'text' => 'color', - 'width' => 'width', - 'height' => 'height' - ); - - public function __construct($documentID) { - // if ($documentID instanceof self) - // var_dump($documentID->getDocumentID()); - $id = $documentID instanceof self ? $documentID->getDocumentID() - : $documentID; - // var_dump($id); - if (!isset(phpQuery::$documents[$id])) { - // var_dump(phpQuery::$documents); - throw new \Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); - } - $this->documentID = $id; - $this->documentWrapper = &phpQuery::$documents[$id]; - $this->document = &$this->documentWrapper->document; - $this->xpath = &$this->documentWrapper->xpath; - $this->charset = &$this->documentWrapper->charset; - $this->documentFragment = &$this->documentWrapper->isDocumentFragment; - // TODO check $this->DOM->documentElement; - // $this->root = $this->document->documentElement; - $this->root = &$this->documentWrapper->root; - // $this->toRoot(); - $this->elements = array( - $this->root - ); - } - /** - * - * @access private - * @param $attr - * @return unknown_type - */ - public function __get($attr) { - switch ($attr) { - // FIXME doesnt work at all ? - case 'length': - return $this->size(); - break; - default: - return $this->$attr; - } - } - /** - * Saves actual object to $var by reference. - * Useful when need to break chain. - * @param PhpQueryObject $var - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toReference(&$var) { - return $var = $this; - } - public function documentFragment($state = null) { - if ($state) { - phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; - return $this; - } - return $this->documentFragment; - } - /** - * @access private - * @TODO documentWrapper - */ - protected function isRoot($node) { - // return $node instanceof \DOMDocument || $node->tagName == 'html'; - return $node instanceof \DOMDocument - || ($node instanceof \DOMElement && $node->tagName == 'html') - || $this->root->isSameNode($node); - } - /** - * @access private - */ - protected function stackIsRoot() { - return $this->size() == 1 && $this->isRoot($this->elements[0]); - } - /** - * Enter description here... - * NON JQUERY METHOD - * - * Watch out, it doesn't creates new instance, can be reverted with end(). - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toRoot() { - $this->elements = array( - $this->root - ); - return $this; - // return $this->newInstance(array($this->root)); - } - /** - * Saves object's DocumentID to $var by reference. - * - * $myDocumentId; - * phpQuery::newDocument('
    ') - * ->getDocumentIDRef($myDocumentId) - * ->find('div')->... - * - * - * @param unknown_type $domId - * @see phpQuery::newDocument - * @see phpQuery::newDocumentFile - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocumentIDRef(&$documentID) { - $documentID = $this->getDocumentID(); - return $this; - } - /** - * Returns object with stack set to document root. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocument() { - return phpQuery::getDocument($this->getDocumentID()); - } - /** - * - * @return \DOMDocument - */ - public function getDOMDocument() { - return $this->document; - } - /** - * Get object's Document ID. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function getDocumentID() { - return $this->documentID; - } - /** - * Unloads whole document from memory. - * CAUTION! None further operations will be possible on this document. - * All objects refering to it will be useless. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function unloadDocument() { - phpQuery::unloadDocuments($this->getDocumentID()); - } - public function isHTML() { - return $this->documentWrapper->isHTML; - } - public function isXHTML() { - return $this->documentWrapper->isXHTML; - } - public function isXML() { - return $this->documentWrapper->isXML; - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/serialize - * @return string - */ - public function serialize() { - return phpQuery::param($this->serializeArray()); - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/serializeArray - * @return array - */ - public function serializeArray($submit = null) { - $source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not('form'); - $return = array(); - // $source->dumpDie(); - foreach ($source as $input) { - $input = phpQuery::pq($input); - if ($input->is('[disabled]')) - continue; - if (!$input->is('[name]')) - continue; - if ($input->is('[type=checkbox]') && !$input->is('[checked]')) - continue; - // jquery diff - if ($submit && $input->is('[type=submit]')) { - if ($submit instanceof \DOMElement - && !$input->elements[0]->isSameNode($submit)) - continue; - else if (is_string($submit) && $input->attr('name') != $submit) - continue; - } - $return[] = array( - 'name' => $input->attr('name'), - 'value' => $input->val(), - ); - } - return $return; - } - /** - * @access private - */ - protected function debug($in) { - if (!phpQuery::$debug) - return; - print('
    ');
    -    print_r($in);
    -    // file debug
    -    //		file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
    -    // quite handy debug trace
    -    //		if ( is_array($in))
    -    //			print_r(array_slice(debug_backtrace(), 3));
    -    print("
    \n"); - } - /** - * @access private - */ - protected function isRegexp($pattern) { - return in_array($pattern[mb_strlen($pattern) - 1], array( - '^', - '*', - '$' - )); - } - /** - * Determines if $char is really a char. - * - * @param string $char - * @return bool - * @todo rewrite me to charcode range ! ;) - * @access private - */ - protected function isChar($char) { - return extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_eregi('\w', $char) - : preg_match('@\w@', $char); - } - /** - * @access private - */ - protected function parseSelector($query) { - // clean spaces - // TODO include this inside parsing ? - $query = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query))); - $queries = array( - array() - ); - if (!$query) - return $queries; - $return = &$queries[0]; - $specialChars = array( - '>', - ' ' - ); - // $specialCharsMapping = array('/' => '>'); - $specialCharsMapping = array(); - $strlen = mb_strlen($query); - $classChars = array( - '.', - '-' - ); - $pseudoChars = array( - '-' - ); - $tagChars = array( - '*', - '|', - '-' +class PhpQueryObject implements \Iterator, \Countable, \ArrayAccess +{ + public $documentID = null; + /** + * \DOMDocument class. + * + * @var \DOMDocument + */ + public $document = null; + public $charset = null; + /** + * + * @var Dom\DOMDocumentWrapper + */ + public $documentWrapper = null; + /** + * XPath interface. + * + * @var \DOMXPath + */ + public $xpath = null; + /** + * Stack of selected elements. + * @TODO refactor to ->nodes + * @var array + */ + public $elements = array(); + /** + * @access private + */ + protected $elementsBackup = array(); + /** + * @access private + */ + protected $previous = null; + /** + * @access private + * @TODO deprecate + */ + protected $root = array(); + /** + * Indicated if doument is just a fragment (no tag). + * + * Every document is realy a full document, so even documentFragments can + * be queried against , but getDocument(id)->htmlOuter() will return + * only contents of . + * + * @var bool + */ + public $documentFragment = true; + /** + * Iterator interface helper + * @access private + */ + protected $elementsInterator = array(); + /** + * Iterator interface helper + * @access private + */ + protected $valid = false; + /** + * Iterator interface helper + * @access private + */ + protected $current = null; + + /** + * Indicates whether CSS has been parsed or not. We only parse CSS if needed. + * @access private + */ + protected $cssIsParsed = array(); + /** + * A collection of complete CSS selector strings. + * @access private; + */ + protected $cssString = array(); + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + + protected $attribute_css_mapping = array( + 'bgcolor' => 'background-color', + 'text' => 'color', + 'width' => 'width', + 'height' => 'height' ); - // split multibyte string - // http://code.google.com/p/phpquery/issues/detail?id=76 - $_query = array(); - for ($i = 0; $i < $strlen; $i++) - $_query[] = mb_substr($query, $i, 1); - $query = $_query; - // it works, but i dont like it... - $i = 0; - while ($i < $strlen) { - $c = $query[$i]; - $tmp = ''; - // TAG - if ($this->isChar($c) || in_array($c, $tagChars)) { - while (isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) { - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // IDs - } - else if ($c == '#') { - $i++; - while (isset($query[$i]) - && ($this->isChar($query[$i]) || $query[$i] == '-')) { - $tmp .= $query[$i]; - $i++; - } - $return[] = '#' . $tmp; - // SPECIAL CHARS - } - else if (in_array($c, $specialChars)) { - $return[] = $c; - $i++; - // MAPPED SPECIAL MULTICHARS - // } else if ( $c.$query[$i+1] == '//') { - // $return[] = ' '; - // $i = $i+2; - // MAPPED SPECIAL CHARS - } - else if (isset($specialCharsMapping[$c])) { - $return[] = $specialCharsMapping[$c]; - $i++; - // COMMA - } - else if ($c == ',') { - $queries[] = array(); - $return = &$queries[count($queries) - 1]; - $i++; - while (isset($query[$i]) && $query[$i] == ' ') - $i++; - // CLASSES - } - else if ($c == '.') { - while (isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) { - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // ~ General Sibling Selector - } - else if ($c == '~') { - $spaceAllowed = true; - $tmp .= $query[$i++]; - while (isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) - || $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) { - if ($query[$i] != ' ') - $spaceAllowed = false; - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // + Adjacent sibling selectors - } - else if ($c == '+') { - $spaceAllowed = true; - $tmp .= $query[$i++]; - while (isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) - || $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) { - if ($query[$i] != ' ') - $spaceAllowed = false; - $tmp .= $query[$i]; - $i++; - } - $return[] = $tmp; - // ATTRS - } - else if ($c == '[') { - $stack = 1; - $tmp .= $c; - while (isset($query[++$i])) { - $tmp .= $query[$i]; - if ($query[$i] == '[') { - $stack++; - } - else if ($query[$i] == ']') { - $stack--; - if (!$stack) - break; - } + + public function __construct($documentID) + { + // if ($documentID instanceof self) + // var_dump($documentID->getDocumentID()); + $id = $documentID instanceof self ? $documentID->getDocumentID() + : $documentID; + // var_dump($id); + if (!isset(phpQuery::$documents[$id])) { + // var_dump(phpQuery::$documents); + throw new \Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); } - $return[] = $tmp; - $i++; - // PSEUDO CLASSES - } - else if ($c == ':') { - $stack = 1; - $tmp .= $query[$i++]; - while (isset($query[$i]) - && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) { - $tmp .= $query[$i]; - $i++; - } - // with arguments ? - if (isset($query[$i]) && $query[$i] == '(') { - $tmp .= $query[$i]; - $stack = 1; - while (isset($query[++$i])) { - $tmp .= $query[$i]; - if ($query[$i] == '(') { - $stack++; - } - else if ($query[$i] == ')') { - $stack--; - if (!$stack) + $this->documentID = $id; + $this->documentWrapper = & phpQuery::$documents[$id]; + $this->document = & $this->documentWrapper->document; + $this->xpath = & $this->documentWrapper->xpath; + $this->charset = & $this->documentWrapper->charset; + $this->documentFragment = & $this->documentWrapper->isDocumentFragment; + // TODO check $this->DOM->documentElement; + // $this->root = $this->document->documentElement; + $this->root = & $this->documentWrapper->root; + // $this->toRoot(); + $this->elements = array( + $this->root + ); + } + + /** + * + * @access private + * @param $attr + * @return \PhpQuery\PhpQueryObject|\PhpQuery\QueryTemplatesParse|\PhpQuery\QueryTemplatesSource|\PhpQuery\QueryTemplatesSourceQuery + */ + public function __get($attr) + { + switch ($attr) { + // FIXME doesnt work at all ? + case 'length': + return $this->size(); break; - } - } - $return[] = $tmp; - $i++; + default: + return $this->$attr; } - else { - $return[] = $tmp; - } - } - else { - $i++; - } - } - foreach ($queries as $k => $q) { - if (isset($q[0])) { - if (isset($q[0][0]) && $q[0][0] == ':') - array_unshift($queries[$k], '*'); - if ($q[0] != '>') - array_unshift($queries[$k], ' '); - } - } - return $queries; - } - /** - * Return matched DOM nodes. - * - * @param int $index - * @return array|\DOMElement Single \DOMElement or array of \DOMElement. - */ - public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index] - : null) : $this->elements; - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - foreach ($args as $callback) { - if (is_array($return)) - foreach ($return as $k => $v) - $return[$k] = phpQuery::callbackRun($callback, array( - $v - )); - else - $return = phpQuery::callbackRun($callback, array( - $return - )); - } - return $return; - } - /** - * Return matched DOM nodes. - * jQuery difference. - * - * @param int $index - * @return array|string Returns string if $index != null - * @todo implement callbacks - * @todo return only arrays ? - * @todo maybe other name... - */ - public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index) - $return = $this->eq($index)->text(); - else { - $return = array(); - for ($i = 0; $i < $this->size(); $i++) { - $return[] = $this->eq($i)->text(); - } - } - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - foreach ($args as $callback) { - $return = phpQuery::callbackRun($callback, array( - $return - )); - } - return $return; - } - /** - * Return matched DOM nodes. - * jQuery difference. - * - * @param int $index - * @return array|string Returns string if $index != null - * @todo implement callbacks - * @todo return only arrays ? - * @todo maybe other name... - */ - public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if ($index) - $return = $this->eq($index)->text(); - else { - $return = array(); - for ($i = 0; $i < $this->size(); $i++) { - $return[] = $this->eq($i)->text(); - } - // pass thou callbacks - $args = func_get_args(); - $args = array_slice($args, 1); - } - foreach ($args as $callback) { - if (is_array($return)) - foreach ($return as $k => $v) - $return[$k] = phpQuery::callbackRun($callback, array( - $v - )); - else - $return = phpQuery::callbackRun($callback, array( - $return - )); - } - return $return; - } - /** - * Returns new instance of actual class. - * - * @param array $newStack Optional. Will replace old stack with new and move old one to history.c - */ - public function newInstance($newStack = null) { - $class = get_class($this); - // support inheritance by passing old object to overloaded constructor - $new = $class != 'phpQuery' ? new $class($this, $this->getDocumentID()) - : new PhpQueryObject($this->getDocumentID()); - $new->previous = $this; - if (is_null($newStack)) { - $new->elements = $this->elements; - if ($this->elementsBackup) - $this->elements = $this->elementsBackup; - } - else if (is_string($newStack)) { - $new->elements = phpQuery::pq($newStack, $this->getDocumentID())->stack(); - } - else { - $new->elements = $newStack; - } - return $new; - } - /** - * Enter description here... - * - * In the future, when PHP will support XLS 2.0, then we would do that this way: - * contains(tokenize(@class, '\s'), "something") - * @param unknown_type $class - * @param unknown_type $node - * @return boolean - * @access private - */ - protected function matchClasses($class, $node) { - // multi-class - if (mb_strpos($class, '.', 1)) { - $classes = explode('.', substr($class, 1)); - $classesCount = count($classes); - $nodeClasses = explode(' ', $node->getAttribute('class')); - $nodeClassesCount = count($nodeClasses); - if ($classesCount > $nodeClassesCount) - return false; - $diff = count(array_diff($classes, $nodeClasses)); - if (!$diff) - return true; - // single-class - } - else { - return in_array( - // strip leading dot from class name - substr($class, 1), - // get classes for element as array - explode(' ', $node->getAttribute('class'))); - } - } - /** - * @access private - */ - protected function runQuery($XQuery, $selector = null, $compare = null) { - if ($compare && !method_exists($this, $compare)) - return false; - $stack = array(); - if (!$this->elements) - $this->debug('Stack empty, skipping...'); - // var_dump($this->elements[0]->nodeType); - // element, document - foreach ($this->stack(array( - 1, - 9, - 13 - )) as $k => $stackNode) { - $detachAfter = false; - // to work on detached nodes we need temporary place them somewhere - // thats because context xpath queries sucks ;] - $testNode = $stackNode; - while ($testNode) { - if (!$testNode->parentNode && !$this->isRoot($testNode)) { - $this->root->appendChild($testNode); - $detachAfter = $testNode; - break; - } - $testNode = isset($testNode->parentNode) ? $testNode->parentNode : null; - } - // XXX tmp ? - $xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html') - : $this->getNodeXpath($stackNode); - // FIXME pseudoclasses-only query, support XML - $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*' - : $xpath . $XQuery; - $this->debug("XPATH: {$query}"); - // run query, get elements - $nodes = $this->xpath->query($query); - $this->debug("QUERY FETCHED"); - if (!$nodes->length) - $this->debug('Nothing found'); - $debug = array(); - foreach ($nodes as $node) { - $matched = false; - if ($compare) { - phpQuery::$debug ? $this->debug("Found: " . $this->whois($node) - . ", comparing with {$compare}()") : null; - $phpQueryDebug = phpQuery::$debug; - phpQuery::$debug = false; - // TODO ??? use phpQuery::callbackRun() - if (call_user_func_array(array( - $this, - $compare - ), array( - $selector, - $node - ))) - $matched = true; - phpQuery::$debug = $phpQueryDebug; + } + + /** + * Saves actual object to $var by reference. + * Useful when need to break chain. + * @param PhpQueryObject $var + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toReference(&$var) + { + return $var = $this; + } + + public function documentFragment($state = null) + { + if ($state) { + phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; + return $this; } - else { - $matched = true; - } - if ($matched) { - if (phpQuery::$debug) - $debug[] = $this->whois($node); - $stack[] = $node; - } - } - if (phpQuery::$debug) { - $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug)); - } - if ($detachAfter) - $this->root->removeChild($detachAfter); - } - $this->elements = $stack; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function find($selectors, $context = null, $noHistory = false) { - if (!$noHistory) - // backup last stack /for end()/ - $this->elementsBackup = $this->elements; - // allow to define context - // TODO combine code below with phpQuery::pq() context guessing code - // as generic function - if (isset($context)) { - if (!is_array($context) && $context instanceof \DOMElement) { + return $this->documentFragment; + } + + /** + * @access private + * @TODO documentWrapper + */ + protected function isRoot($node) + { + // return $node instanceof \DOMDocument || $node->tagName == 'html'; + return $node instanceof \DOMDocument + || ($node instanceof \DOMElement && $node->tagName == 'html') + || $this->root->isSameNode($node); + } + + /** + * @access private + */ + protected function stackIsRoot() + { + return $this->size() == 1 && $this->isRoot($this->elements[0]); + } + + /** + * Enter description here... + * NON JQUERY METHOD + * + * Watch out, it doesn't creates new instance, can be reverted with end(). + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toRoot() + { $this->elements = array( - $context + $this->root + ); + return $this; + // return $this->newInstance(array($this->root)); + } + + /** + * Saves object's DocumentID to $var by reference. + * + * $myDocumentId; + * phpQuery::newDocument('
    ') + * ->getDocumentIDRef($myDocumentId) + * ->find('div')->... + * + * + * @param $documentID + * @internal param string $domId + * @see phpQuery::newDocument + * @see phpQuery::newDocumentFile + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocumentIDRef(&$documentID) + { + $documentID = $this->getDocumentID(); + return $this; + } + + /** + * Returns object with stack set to document root. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocument() + { + return phpQuery::getDocument($this->getDocumentID()); + } + + /** + * + * @return \DOMDocument + */ + public function getDOMDocument() + { + return $this->document; + } + + /** + * Get object's Document ID. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function getDocumentID() + { + return $this->documentID; + } + + /** + * Unloads whole document from memory. + * CAUTION! None further operations will be possible on this document. + * All objects refering to it will be useless. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function unloadDocument() + { + phpQuery::unloadDocuments($this->getDocumentID()); + } + + public function isHTML() + { + return $this->documentWrapper->isHTML; + } + + public function isXHTML() + { + return $this->documentWrapper->isXHTML; + } + + public function isXML() + { + return $this->documentWrapper->isXML; + } + + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/serialize + * @return string + */ + public function serialize() + { + return phpQuery::param($this->serializeArray()); + } + + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/serializeArray + * @return array + */ + public function serializeArray($submit = null) + { + $source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not( + 'form' ); - } - elseif (is_array($context)) { - $this->elements = array(); - foreach ($context as $c) - if ($c instanceof \DOMElement) - $this->elements[] = $c; - } - elseif ($context instanceof PhpQueryObject) { - $this->elements = $context->elements; - } - } - - $queries = $this->parseSelector($selectors); - - $this->debug(array( - 'FIND', - $selectors, - $queries - )); - $XQuery = ''; - // remember stack state because of multi-queries - $oldStack = $this->elements; - // here we will be keeping found elements - $stack = array(); - foreach ($queries as $selector) { - $this->elements = $oldStack; - $delimiterBefore = false; - foreach ($selector as $s) { - // TAG - $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s) - || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*'; - if ($isTag) { - if ($this->isXML()) { - // namespace support - if (mb_strpos($s, '|') !== false) { - $ns = $tag = null; - list($ns, $tag) = explode('|', $s); - $XQuery .= "$ns:$tag"; + $return = array(); + // $source->dumpDie(); + foreach ($source as $input) { + $input = phpQuery::pq($input); + if ($input->is('[disabled]')) { + continue; } - else if ($s == '*') { - $XQuery .= "*"; + if (!$input->is('[name]')) { + continue; } - else { - $XQuery .= "*[local-name()='$s']"; + if ($input->is('[type=checkbox]') && !$input->is('[checked]')) { + continue; } - } - else { - $XQuery .= $s; - } - // ID - } - else if ($s[0] == '#') { - if ($delimiterBefore) - $XQuery .= '*'; - $XQuery .= "[@id='" . substr($s, 1) . "']"; - // ATTRIBUTES - } - else if ($s[0] == '[') { - if ($delimiterBefore) - $XQuery .= '*'; - // strip side brackets - $attr = trim($s, ']['); - $execute = false; - // attr with specifed value - if (mb_strpos($s, '=')) { - $value = null; - list($attr, $value) = explode('=', $attr); - $value = trim($value, "'\""); - if ($this->isRegexp($attr)) { - // cut regexp character - $attr = substr($attr, 0, -1); - $execute = true; - $XQuery .= "[@{$attr}]"; + // jquery diff + if ($submit && $input->is('[type=submit]')) { + if ($submit instanceof \DOMElement + && !$input->elements[0]->isSameNode($submit) + ) { + continue; + } else { + if (is_string($submit) && $input->attr('name') != $submit) { + continue; + } + } + } + $return[] = array( + 'name' => $input->attr('name'), + 'value' => $input->val(), + ); + } + return $return; + } + + /** + * @access private + */ + protected function debug($in) + { + if (!phpQuery::$debug) { + return; + } + print('
    ');
    +        print_r($in);
    +        // file debug
    +        //		file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
    +        // quite handy debug trace
    +        //		if ( is_array($in))
    +        //			print_r(array_slice(debug_backtrace(), 3));
    +        print("
    \n"); + } + + /** + * @access private + */ + protected function isRegexp($pattern) + { + return in_array( + $pattern[mb_strlen($pattern) - 1], + array( + '^', + '*', + '$' + ) + ); + } + + /** + * Determines if $char is really a char. + * + * @param string $char + * @return bool + * @todo rewrite me to charcode range ! ;) + * @access private + */ + protected function isChar($char) + { + return extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_eregi('\w', $char) + : preg_match('@\w@', $char); + } + + /** + * @access private + */ + protected function parseSelector($query) + { + // clean spaces + // TODO include this inside parsing ? + $query = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query))); + $queries = array( + array() + ); + if (!$query) { + return $queries; + } + $return = & $queries[0]; + $specialChars = array( + '>', + ' ' + ); + // $specialCharsMapping = array('/' => '>'); + $specialCharsMapping = array(); + $strlen = mb_strlen($query); + $classChars = array( + '.', + '-' + ); + $pseudoChars = array( + '-' + ); + $tagChars = array( + '*', + '|', + '-' + ); + // split multibyte string + // http://code.google.com/p/phpquery/issues/detail?id=76 + $_query = array(); + for ($i = 0; $i < $strlen; $i++) { + $_query[] = mb_substr($query, $i, 1); + } + $query = $_query; + // it works, but i dont like it... + $i = 0; + while ($i < $strlen) { + $c = $query[$i]; + $tmp = ''; + // TAG + if ($this->isChar($c) || in_array($c, $tagChars)) { + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) { + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // IDs + } else if ($c == '#') { + $i++; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || $query[$i] == '-')) { + $tmp .= $query[$i]; + $i++; + } + $return[] = '#' . $tmp; + // SPECIAL CHARS + } else if (in_array($c, $specialChars)) { + $return[] = $c; + $i++; + // MAPPED SPECIAL MULTICHARS + // } else if ( $c.$query[$i+1] == '//') { + // $return[] = ' '; + // $i = $i+2; + // MAPPED SPECIAL CHARS + } else if (isset($specialCharsMapping[$c])) { + $return[] = $specialCharsMapping[$c]; + $i++; + // COMMA + } else if ($c == ',') { + $queries[] = array(); + $return = & $queries[count($queries) - 1]; + $i++; + while (isset($query[$i]) && $query[$i] == ' ') { + $i++; + } + // CLASSES + } else if ($c == '.') { + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) { + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // ~ General Sibling Selector + } else if ($c == '~') { + $spaceAllowed = true; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) + || $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) { + if ($query[$i] != ' ') { + $spaceAllowed = false; + } + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // + Adjacent sibling selectors + } else { + if ($c == '+') { + $spaceAllowed = true; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $classChars) + || $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) { + if ($query[$i] != ' ') { + $spaceAllowed = false; + } + $tmp .= $query[$i]; + $i++; + } + $return[] = $tmp; + // ATTRS + } else { + if ($c == '[') { + $stack = 1; + $tmp .= $c; + while (isset($query[++$i])) { + $tmp .= $query[$i]; + if ($query[$i] == '[') { + $stack++; + } else { + if ($query[$i] == ']') { + $stack--; + if (!$stack) { + break; + } + } + } + } + $return[] = $tmp; + $i++; + // PSEUDO CLASSES + } else { + if ($c == ':') { + $stack = 1; + $tmp .= $query[$i++]; + while (isset($query[$i]) + && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) { + $tmp .= $query[$i]; + $i++; + } + // with arguments ? + if (isset($query[$i]) && $query[$i] == '(') { + $tmp .= $query[$i]; + $stack = 1; + while (isset($query[++$i])) { + $tmp .= $query[$i]; + if ($query[$i] == '(') { + $stack++; + } else { + if ($query[$i] == ')') { + $stack--; + if (!$stack) { + break; + } + } + } + } + $return[] = $tmp; + $i++; + } else { + $return[] = $tmp; + } + } else { + $i++; + } + } + } } - else { - $XQuery .= "[@{$attr}='{$value}']"; + } + foreach ($queries as $k => $q) { + if (isset($q[0])) { + if (isset($q[0][0]) && $q[0][0] == ':') + array_unshift($queries[$k], '*'); + if ($q[0] != '>') + array_unshift($queries[$k], ' '); } - // attr without specified value - } - else { - $XQuery .= "[@{$attr}]"; - } - if ($execute) { - $this->runQuery($XQuery, $s, 'is'); - $XQuery = ''; - if (!$this->length()) - break; - } - // CLASSES - } - else if ($s[0] == '.') { - // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]"); - // thx wizDom ;) - if ($delimiterBefore) - $XQuery .= '*'; - $XQuery .= '[@class]'; - $this->runQuery($XQuery, $s, 'matchClasses'); - $XQuery = ''; - if (!$this->length()) - break; - // ~ General Sibling Selector - } - else if ($s[0] == '~') { - $this->runQuery($XQuery); - $XQuery = ''; - $this->elements = $this->siblings(substr($s, 1))->elements; - if (!$this->length()) - break; - // + Adjacent sibling selectors - } - else if ($s[0] == '+') { - // TODO /following-sibling:: - $this->runQuery($XQuery); - $XQuery = ''; - $subSelector = substr($s, 1); - $subElements = $this->elements; - $this->elements = array(); - foreach ($subElements as $node) { - // search first \DOMElement sibling - $test = $node->nextSibling; - while ($test && !($test instanceof \DOMElement)) - $test = $test->nextSibling; - if ($test && $this->is($subSelector, $test)) - $this->elements[] = $test; - } - if (!$this->length()) - break; - // PSEUDO CLASSES - } - else if ($s[0] == ':') { - // TODO optimization for :first :last - if ($XQuery) { - $this->runQuery($XQuery); - $XQuery = ''; - } - if (!$this->length()) - break; - $this->pseudoClasses($s); - if (!$this->length()) - break; - // DIRECT DESCENDANDS - } - else if ($s == '>') { - $XQuery .= '/'; - $delimiterBefore = 2; - // ALL DESCENDANDS - } - else if ($s == ' ') { - $XQuery .= '//'; - $delimiterBefore = 2; - // ERRORS } + return $queries; + } + + /** + * Return matched DOM nodes. + * + * @param int $index + * @return array|\DOMElement Single \DOMElement or array of \DOMElement. + */ + public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + $return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index] + : null) : $this->elements; + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + foreach ($args as $callback) { + if (is_array($return)) + foreach ($return as $k => $v) + $return[$k] = phpQuery::callbackRun( + $callback, + array( + $v + ) + ); + else + $return = phpQuery::callbackRun( + $callback, + array( + $return + ) + ); + } + return $return; + } + + /** + * Return matched DOM nodes. + * jQuery difference. + * + * @param int $index + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return array|string Returns string if $index != null + * @todo implement callbacks + * @todo return only arrays ? + * @todo maybe other name... + */ + public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + if ($index) + $return = $this->eq($index)->text(); + else { + $return = array(); + for ($i = 0; $i < $this->size(); $i++) { + $return[] = $this->eq($i)->text(); + } + } + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + foreach ($args as $callback) { + $return = phpQuery::callbackRun( + $callback, + array( + $return + ) + ); + } + return $return; + } + + /** + * Return matched DOM nodes. + * jQuery difference. + * + * @param int $index + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return array|string Returns string if $index != null + * @todo implement callbacks + * @todo return only arrays ? + * @todo maybe other name... + */ + public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + if ($index) + $return = $this->eq($index)->text(); else { - phpQuery::debug("Unrecognized token '$s'"); + $return = array(); + for ($i = 0; $i < $this->size(); $i++) { + $return[] = $this->eq($i)->text(); + } + // pass thou callbacks + $args = func_get_args(); + $args = array_slice($args, 1); + } + foreach ($args as $callback) { + if (is_array($return)) + foreach ($return as $k => $v) + $return[$k] = phpQuery::callbackRun( + $callback, + array( + $v + ) + ); + else + $return = phpQuery::callbackRun( + $callback, + array( + $return + ) + ); + } + return $return; + } + + /** + * Returns new instance of actual class. + * + * @param array $newStack Optional. Will replace old stack with new and move old one to history.c + * @return \PhpQuery\PhpQueryObject + */ + public function newInstance($newStack = null) + { + $class = get_class($this); + // support inheritance by passing old object to overloaded constructor + $new = $class != 'phpQuery' ? new $class($this, $this->getDocumentID()) + : new PhpQueryObject($this->getDocumentID()); + $new->previous = $this; + if (is_null($newStack)) { + $new->elements = $this->elements; + if ($this->elementsBackup) + $this->elements = $this->elementsBackup; + } else if (is_string($newStack)) { + $new->elements = phpQuery::pq($newStack, $this->getDocumentID())->stack(); + } else { + $new->elements = $newStack; + } + return $new; + } + + /** + * Enter description here... + * + * In the future, when PHP will support XLS 2.0, then we would do that this way: + * contains(tokenize(@class, '\s'), "something") + * @param string $class + * @param string $node + * @return boolean + * @access private + */ + protected function matchClasses($class, $node) + { + // multi-class + if (mb_strpos($class, '.', 1)) { + $classes = explode('.', substr($class, 1)); + $classesCount = count($classes); + $nodeClasses = explode(' ', $node->getAttribute('class')); + $nodeClassesCount = count($nodeClasses); + if ($classesCount > $nodeClassesCount) + return false; + $diff = count(array_diff($classes, $nodeClasses)); + if (!$diff) + return true; + // single-class + } else { + return in_array( + // strip leading dot from class name + substr($class, 1), + // get classes for element as array + explode(' ', $node->getAttribute('class')) + ); + } + } + + /** + * @access private + */ + protected function runQuery($XQuery, $selector = null, $compare = null) + { + if ($compare && !method_exists($this, $compare)) + return false; + $stack = array(); + if (!$this->elements) + $this->debug('Stack empty, skipping...'); + // var_dump($this->elements[0]->nodeType); + // element, document + foreach ($this->stack( + array( + 1, + 9, + 13 + ) + ) as $k => $stackNode) { + $detachAfter = false; + // to work on detached nodes we need temporary place them somewhere + // thats because context xpath queries sucks ;] + $testNode = $stackNode; + while ($testNode) { + if (!$testNode->parentNode && !$this->isRoot($testNode)) { + $this->root->appendChild($testNode); + $detachAfter = $testNode; + break; + } + $testNode = isset($testNode->parentNode) ? $testNode->parentNode : null; + } + // XXX tmp ? + $xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html') + : $this->getNodeXpath($stackNode); + // FIXME pseudoclasses-only query, support XML + $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*' + : $xpath . $XQuery; + $this->debug("XPATH: {$query}"); + // run query, get elements + $nodes = $this->xpath->query($query); + $this->debug("QUERY FETCHED"); + if (!$nodes->length) + $this->debug('Nothing found'); + $debug = array(); + foreach ($nodes as $node) { + $matched = false; + if ($compare) { + phpQuery::$debug ? $this->debug( + "Found: " . $this->whois($node) + . ", comparing with {$compare}()" + ) : null; + $phpQueryDebug = phpQuery::$debug; + phpQuery::$debug = false; + // TODO ??? use phpQuery::callbackRun() + if (call_user_func_array( + array( + $this, + $compare + ), + array( + $selector, + $node + ) + ) + ) + $matched = true; + phpQuery::$debug = $phpQueryDebug; + } else { + $matched = true; + } + if ($matched) { + if (phpQuery::$debug) + $debug[] = $this->whois($node); + $stack[] = $node; + } + } + if (phpQuery::$debug) { + $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug)); + } + if ($detachAfter) + $this->root->removeChild($detachAfter); } - $delimiterBefore = $delimiterBefore === 2; - } - // run query if any - if ($XQuery && $XQuery != '//') { - $this->runQuery($XQuery); + $this->elements = $stack; + } + + /** + * Enter description here... + * + * @param $selectors + * @param null $context + * @param bool $noHistory + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function find($selectors, $context = null, $noHistory = false) + { + if (!$noHistory) + // backup last stack /for end()/ + $this->elementsBackup = $this->elements; + // allow to define context + // TODO combine code below with phpQuery::pq() context guessing code + // as generic function + if (isset($context)) { + if (!is_array($context) && $context instanceof \DOMElement) { + $this->elements = array( + $context + ); + } elseif (is_array($context)) { + $this->elements = array(); + foreach ($context as $c) + if ($c instanceof \DOMElement) + $this->elements[] = $c; + } elseif ($context instanceof PhpQueryObject) { + $this->elements = $context->elements; + } + } + + $queries = $this->parseSelector($selectors); + + $this->debug( + array( + 'FIND', + $selectors, + $queries + ) + ); $XQuery = ''; - } - foreach ($this->elements as $node) - if (!$this->elementsContainsNode($node, $stack)) - $stack[] = $node; - } - $this->elements = $stack; - return $this->newInstance(); - } - /** - * @todo create API for classes with pseudoselectors - * @access private - */ - protected function pseudoClasses($class) { - // TODO clean args parsing ? - $class = ltrim($class, ':'); - $haveArgs = mb_strpos($class, '('); - if ($haveArgs !== false) { - $args = substr($class, $haveArgs + 1, -1); - $class = substr($class, 0, $haveArgs); - } - switch ($class) { - case 'even': - case 'odd': + // remember stack state because of multi-queries + $oldStack = $this->elements; + // here we will be keeping found elements $stack = array(); - foreach ($this->elements as $i => $node) { - if ($class == 'even' && ($i % 2) == 0) - $stack[] = $node; - else if ($class == 'odd' && $i % 2) - $stack[] = $node; + foreach ($queries as $selector) { + $this->elements = $oldStack; + $delimiterBefore = false; + foreach ($selector as $s) { + // TAG + $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s) + || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*'; + if ($isTag) { + if ($this->isXML()) { + // namespace support + if (mb_strpos($s, '|') !== false) { + $ns = $tag = null; + list($ns, $tag) = explode('|', $s); + $XQuery .= "$ns:$tag"; + } else if ($s == '*') { + $XQuery .= "*"; + } else { + $XQuery .= "*[local-name()='$s']"; + } + } else { + $XQuery .= $s; + } + // ID + } else if ($s[0] == '#') { + if ($delimiterBefore) + $XQuery .= '*'; + $XQuery .= "[@id='" . substr($s, 1) . "']"; + // ATTRIBUTES + } else if ($s[0] == '[') { + if ($delimiterBefore) + $XQuery .= '*'; + // strip side brackets + $attr = trim($s, ']['); + $execute = false; + // attr with specifed value + if (mb_strpos($s, '=')) { + $value = null; + list($attr, $value) = explode('=', $attr); + $value = trim($value, "'\""); + if ($this->isRegexp($attr)) { + // cut regexp character + $attr = substr($attr, 0, -1); + $execute = true; + $XQuery .= "[@{$attr}]"; + } else { + $XQuery .= "[@{$attr}='{$value}']"; + } + // attr without specified value + } else { + $XQuery .= "[@{$attr}]"; + } + if ($execute) { + $this->runQuery($XQuery, $s, 'is'); + $XQuery = ''; + if (!$this->length()) + break; + } + // CLASSES + } else if ($s[0] == '.') { + // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]"); + // thx wizDom ;) + if ($delimiterBefore) + $XQuery .= '*'; + $XQuery .= '[@class]'; + $this->runQuery($XQuery, $s, 'matchClasses'); + $XQuery = ''; + if (!$this->length()) + break; + // ~ General Sibling Selector + } else if ($s[0] == '~') { + $this->runQuery($XQuery); + $XQuery = ''; + $this->elements = $this->siblings(substr($s, 1))->elements; + if (!$this->length()) + break; + // + Adjacent sibling selectors + } else if ($s[0] == '+') { + // TODO /following-sibling:: + $this->runQuery($XQuery); + $XQuery = ''; + $subSelector = substr($s, 1); + $subElements = $this->elements; + $this->elements = array(); + foreach ($subElements as $node) { + // search first \DOMElement sibling + $test = $node->nextSibling; + while ($test && !($test instanceof \DOMElement)) + $test = $test->nextSibling; + if ($test && $this->is($subSelector, $test)) + $this->elements[] = $test; + } + if (!$this->length()) + break; + // PSEUDO CLASSES + } else if ($s[0] == ':') { + // TODO optimization for :first :last + if ($XQuery) { + $this->runQuery($XQuery); + $XQuery = ''; + } + if (!$this->length()) + break; + $this->pseudoClasses($s); + if (!$this->length()) + break; + // DIRECT DESCENDANDS + } else if ($s == '>') { + $XQuery .= '/'; + $delimiterBefore = 2; + // ALL DESCENDANDS + } else if ($s == ' ') { + $XQuery .= '//'; + $delimiterBefore = 2; + // ERRORS + } else { + phpQuery::debug("Unrecognized token '$s'"); + } + $delimiterBefore = $delimiterBefore === 2; + } + // run query if any + if ($XQuery && $XQuery != '//') { + $this->runQuery($XQuery); + $XQuery = ''; + } + foreach ($this->elements as $node) + if (!$this->elementsContainsNode($node, $stack)) + $stack[] = $node; } $this->elements = $stack; - break; - case 'eq': - $k = intval($args); - $this->elements = isset($this->elements[$k]) ? array( - $this->elements[$k] - ) : array(); - break; - case 'gt': - $this->elements = array_slice($this->elements, $args + 1); - break; - case 'lt': - $this->elements = array_slice($this->elements, 0, $args + 1); - break; - case 'first': - if (isset($this->elements[0])) - $this->elements = array( - $this->elements[0] - ); - break; - case 'last': - if ($this->elements) - $this->elements = array( - $this->elements[count($this->elements) - 1] - ); - break; - /*case 'parent': + return $this->newInstance(); + } + + /** + * @todo create API for classes with pseudoselectors + * @access private + */ + protected function pseudoClasses($class) + { + // TODO clean args parsing ? + $class = ltrim($class, ':'); + $haveArgs = mb_strpos($class, '('); + if ($haveArgs !== false) { + $args = substr($class, $haveArgs + 1, -1); + $class = substr($class, 0, $haveArgs); + } + switch ($class) { + case 'even': + case 'odd': + $stack = array(); + foreach ($this->elements as $i => $node) { + if ($class == 'even' && ($i % 2) == 0) + $stack[] = $node; + else if ($class == 'odd' && $i % 2) + $stack[] = $node; + } + $this->elements = $stack; + break; + case 'eq': + $k = intval($args); + $this->elements = isset($this->elements[$k]) ? array( + $this->elements[$k] + ) : array(); + break; + case 'gt': + $this->elements = array_slice($this->elements, $args + 1); + break; + case 'lt': + $this->elements = array_slice($this->elements, 0, $args + 1); + break; + case 'first': + if (isset($this->elements[0])) + $this->elements = array( + $this->elements[0] + ); + break; + case 'last': + if ($this->elements) + $this->elements = array( + $this->elements[count($this->elements) - 1] + ); + break; + /*case 'parent': $stack = array(); foreach($this->elements as $node) { if ( $node->childNodes->length ) @@ -974,141 +1065,201 @@ protected function pseudoClasses($class) { } $this->elements = $stack; break;*/ - case 'contains': - $text = trim($args, "\"'"); - $stack = array(); - foreach ($this->elements as $node) { - if (mb_stripos($node->textContent, $text) === false) - continue; - $stack[] = $node; - } - $this->elements = $stack; - break; - case 'not': - $selector = self::unQuote($args); - $this->elements = $this->not($selector)->stack(); - break; - case 'slice': - // TODO jQuery difference ? - $args = explode(',', str_replace(', ', ',', trim($args, "\"'"))); - $start = $args[0]; - $end = isset($args[1]) ? $args[1] : null; - if ($end > 0) - $end = $end - $start; - $this->elements = array_slice($this->elements, $start, $end); - break; - case 'has': - $selector = trim($args, "\"'"); - $stack = array(); - foreach ($this->stack(1) as $el) { - if ($this->find($selector, $el, true)->length) - $stack[] = $el; - } - $this->elements = $stack; - break; - case 'submit': - case 'reset': - $this->elements = phpQuery::merge($this->map(array( - $this, - 'is' - ), "input[type=$class]", new CallbackParam()), $this->map(array( - $this, - 'is' - ), "button[type=$class]", new CallbackParam())); - break; - // $stack = array(); - // foreach($this->elements as $node) - // if ($node->is('input[type=submit]') || $node->is('button[type=submit]')) - // $stack[] = $el; - // $this->elements = $stack; - case 'input': - $this->elements = $this->map(array( - $this, - 'is' - ), 'input', new CallbackParam())->elements; - break; - case 'password': - case 'checkbox': - case 'radio': - case 'hidden': - case 'image': - case 'file': - $this->elements = $this->map(array( - $this, - 'is' - ), "input[type=$class]", new CallbackParam())->elements; - break; - case 'parent': - $this->elements = $this->map(create_function('$node', ' + case 'contains': + $text = trim($args, "\"'"); + $stack = array(); + foreach ($this->elements as $node) { + if (mb_stripos($node->textContent, $text) === false) + continue; + $stack[] = $node; + } + $this->elements = $stack; + break; + case 'not': + $selector = self::unQuote($args); + $this->elements = $this->not($selector)->stack(); + break; + case 'slice': + // TODO jQuery difference ? + $args = explode(',', str_replace(', ', ',', trim($args, "\"'"))); + $start = $args[0]; + $end = isset($args[1]) ? $args[1] : null; + if ($end > 0) + $end = $end - $start; + $this->elements = array_slice($this->elements, $start, $end); + break; + case 'has': + $selector = trim($args, "\"'"); + $stack = array(); + foreach ($this->stack(1) as $el) { + if ($this->find($selector, $el, true)->length) + $stack[] = $el; + } + $this->elements = $stack; + break; + case 'submit': + case 'reset': + $this->elements = phpQuery::merge( + $this->map( + array( + $this, + 'is' + ), + "input[type=$class]", + new \CallbackParam() + ), + $this->map( + array( + $this, + 'is' + ), + "button[type=$class]", + new \CallbackParam() + ) + ); + break; + // $stack = array(); + // foreach($this->elements as $node) + // if ($node->is('input[type=submit]') || $node->is('button[type=submit]')) + // $stack[] = $el; + // $this->elements = $stack; + case 'input': + $this->elements = $this->map( + array( + $this, + 'is' + ), + 'input', + new \CallbackParam() + )->elements; + break; + case 'password': + case 'checkbox': + case 'radio': + case 'hidden': + case 'image': + case 'file': + $this->elements = $this->map( + array( + $this, + 'is' + ), + "input[type=$class]", + new \CallbackParam() + )->elements; + break; + case 'parent': + $this->elements = $this->map( + create_function( + '$node', + ' return $node instanceof \DOMElement && $node->childNodes->length - ? $node : null;'))->elements; - break; - case 'empty': - $this->elements = $this->map(create_function('$node', ' + ? $node : null;' + ) + )->elements; + break; + case 'empty': + $this->elements = $this->map( + create_function( + '$node', + ' return $node instanceof \DOMElement && $node->childNodes->length - ? null : $node;'))->elements; - break; - case 'disabled': - case 'selected': - case 'checked': - $this->elements = $this->map(array( - $this, - 'is' - ), "[$class]", new CallbackParam())->elements; - break; - case 'enabled': - $this->elements = $this->map(create_function('$node', ' - return pq($node)->not(":disabled") ? $node : null;'))->elements; - break; - case 'header': - $this->elements = $this->map(create_function('$node', '$isHeader = isset($node->tagName) && in_array($node->tagName, array( + ? null : $node;' + ) + )->elements; + break; + case 'disabled': + case 'selected': + case 'checked': + $this->elements = $this->map( + array( + $this, + 'is' + ), + "[$class]", + new \CallbackParam() + )->elements; + break; + case 'enabled': + $this->elements = $this->map( + create_function( + '$node', + ' + return pq($node)->not(":disabled") ? $node : null;' + ) + )->elements; + break; + case 'header': + $this->elements = $this->map( + create_function( + '$node', + '$isHeader = isset($node->tagName) && in_array($node->tagName, array( "h1", "h2", "h3", "h4", "h5", "h6", "h7" )); return $isHeader ? $node - : null;'))->elements; - // $this->elements = $this->map( - // create_function('$node', '$node = pq($node); - // return $node->is("h1") - // || $node->is("h2") - // || $node->is("h3") - // || $node->is("h4") - // || $node->is("h5") - // || $node->is("h6") - // || $node->is("h7") - // ? $node - // : null;') - // )->elements; - break; - case 'only-child': - $this->elements = $this->map(create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;'))->elements; - break; - case 'first-child': - $this->elements = $this->map(create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;'))->elements; - break; - case 'last-child': - $this->elements = $this->map(create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;'))->elements; - break; - case 'nth-child': - $param = trim($args, "\"'"); - if (!$param) - break; - // nth-child(n+b) to nth-child(1n+b) - if ($param{0} == 'n') - $param = '1' . $param; - // :nth-child(index/even/odd/equation) - if ($param == 'even' || $param == 'odd') - $mapped = $this->map(create_function('$node, $param', '$index = pq($node)->prevAll()->size()+1; + : null;' + ) + )->elements; + // $this->elements = $this->map( + // create_function('$node', '$node = pq($node); + // return $node->is("h1") + // || $node->is("h2") + // || $node->is("h3") + // || $node->is("h4") + // || $node->is("h5") + // || $node->is("h6") + // || $node->is("h7") + // ? $node + // : null;') + // )->elements; + break; + case 'only-child': + $this->elements = $this->map( + create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;') + )->elements; + break; + case 'first-child': + $this->elements = $this->map( + create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;') + )->elements; + break; + case 'last-child': + $this->elements = $this->map( + create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;') + )->elements; + break; + case 'nth-child': + $param = trim($args, "\"'"); + if (!$param) + break; + // nth-child(n+b) to nth-child(1n+b) + if ($param{0} == 'n') + $param = '1' . $param; + // :nth-child(index/even/odd/equation) + if ($param == 'even' || $param == 'odd') + $mapped = $this->map( + create_function( + '$node, $param', + '$index = pq($node)->prevAll()->size()+1; if ($param == "even" && ($index%2) == 0) return $node; else if ($param == "odd" && $index%2 == 1) return $node; else - return null;'), new CallbackParam(), $param); - else if (mb_strlen($param) > 1 - && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1) - // an+b - $mapped = $this->map(create_function('$node, $param', '$prevs = pq($node)->prevAll()->size(); + return null;' + ), + new \CallbackParam(), + $param + ); + else if (mb_strlen($param) > 1 + && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1 + ) + // an+b + $mapped = $this->map( + create_function( + '$node, $param', + '$prevs = pq($node)->prevAll()->size(); $index = 1+$prevs; preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches); @@ -1143,2307 +1294,2719 @@ protected function pseudoClasses($class) { // return ($index-$b)%$a == 0 // ? $node // : null; - '), new CallbackParam(), $param); - else - // index - $mapped = $this->map(create_function('$node, $index', '$prevs = pq($node)->prevAll()->size(); + ' + ), + new \CallbackParam(), + $param + ); + else + // index + $mapped = $this->map( + create_function( + '$node, $index', + '$prevs = pq($node)->prevAll()->size(); if ($prevs && $prevs == $index-1) return $node; else if (! $prevs && $index == 1) return $node; else - return null;'), new CallbackParam(), $param); - $this->elements = $mapped->elements; - break; - default: - $this->debug("Unknown pseudoclass '{$class}', skipping..."); - } - } - /** - * @access private - */ - protected function __pseudoClassParam($paramsString) { - // TODO; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function is($selector, $nodes = null) { - phpQuery::debug(array( - "Is:", - $selector - )); - if (!$selector) - return false; - $oldStack = $this->elements; - $returnArray = false; - if ($nodes && is_array($nodes)) { - $this->elements = $nodes; - } - else if ($nodes) - $this->elements = array( - $nodes - ); - $this->filter($selector, true); - $stack = $this->elements; - $this->elements = $oldStack; - if ($nodes) - return $stack ? $stack : null; - return (bool) count($stack); - } - /** - * Enter description here... - * jQuery difference. - * - * Callback: - * - $index int - * - $node DOMNode - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @link http://docs.jquery.com/Traversing/filter - */ - public function filterCallback($callback, $_skipHistory = false) { - if (!$_skipHistory) { - $this->elementsBackup = $this->elements; - $this->debug("Filtering by callback"); - } - $newStack = array(); - foreach ($this->elements as $index => $node) { - $result = phpQuery::callbackRun($callback, array( - $index, - $node - )); - if (is_null($result) || (!is_null($result) && $result)) - $newStack[] = $node; - } - $this->elements = $newStack; - return $_skipHistory ? $this : $this->newInstance(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @link http://docs.jquery.com/Traversing/filter - */ - public function filter($selectors, $_skipHistory = false) { - if ($selectors instanceof Callback OR $selectors instanceof Closure) - return $this->filterCallback($selectors, $_skipHistory); - if (!$_skipHistory) - $this->elementsBackup = $this->elements; - $notSimpleSelector = array( - ' ', - '>', - '~', - '+', - '/' - ); - if (!is_array($selectors)) - $selectors = $this->parseSelector($selectors); - if (!$_skipHistory) - $this->debug(array( - "Filtering:", - $selectors - )); - $finalStack = array(); - foreach ($selectors as $selector) { - $stack = array(); - if (!$selector) - break; - // avoid first space or / - if (in_array($selector[0], $notSimpleSelector)) - $selector = array_slice($selector, 1); - // PER NODE selector chunks - foreach ($this->stack() as $node) { - $break = false; - foreach ($selector as $s) { - if (!($node instanceof \DOMElement)) { - // all besides \DOMElement - if ($s[0] == '[') { - $attr = trim($s, '[]'); - if (mb_strpos($attr, '=')) { - list($attr, $val) = explode('=', $attr); - if ($attr == 'nodeType' && $node->nodeType != $val) - $break = true; - } + return null;' + ), + new \CallbackParam(), + $param + ); + $this->elements = $mapped->elements; + break; + default: + $this->debug("Unknown pseudoclass '{$class}', skipping..."); + } + } + + /** + * @access private + */ + protected function __pseudoClassParam($paramsString) + { + // TODO; + } + + /** + * Enter description here... + * + * @param $selector + * @param null $nodes + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function is($selector, $nodes = null) + { + phpQuery::debug( + array( + "Is:", + $selector + ) + ); + if (!$selector) + return false; + $oldStack = $this->elements; + $returnArray = false; + if ($nodes && is_array($nodes)) { + $this->elements = $nodes; + } else if ($nodes) + $this->elements = array( + $nodes + ); + $this->filter($selector, true); + $stack = $this->elements; + $this->elements = $oldStack; + if ($nodes) + return $stack ? $stack : null; + return (bool) count($stack); + } + + /** + * Enter description here... + * jQuery difference. + * + * Callback: + * - $index int + * - $node DOMNode + * + * @param $callback + * @param bool $_skipHistory + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @link http://docs.jquery.com/Traversing/filter + */ + public function filterCallback($callback, $_skipHistory = false) + { + if (!$_skipHistory) { + $this->elementsBackup = $this->elements; + $this->debug("Filtering by callback"); + } + $newStack = array(); + foreach ($this->elements as $index => $node) { + $result = phpQuery::callbackRun( + $callback, + array( + $index, + $node + ) + ); + if (is_null($result) || (!is_null($result) && $result)) + $newStack[] = $node; + } + $this->elements = $newStack; + return $_skipHistory ? $this : $this->newInstance(); + } + + /** + * Enter description here... + * + * @param $selectors + * @param bool $_skipHistory + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @link http://docs.jquery.com/Traversing/filter + */ + public function filter($selectors, $_skipHistory = false) + { + if ($selectors instanceof \Callback OR $selectors instanceof \Closure) + return $this->filterCallback($selectors, $_skipHistory); + if (!$_skipHistory) + $this->elementsBackup = $this->elements; + $notSimpleSelector = array( + ' ', + '>', + '~', + '+', + '/' + ); + if (!is_array($selectors)) + $selectors = $this->parseSelector($selectors); + if (!$_skipHistory) + $this->debug( + array( + "Filtering:", + $selectors + ) + ); + $finalStack = array(); + foreach ($selectors as $selector) { + $stack = array(); + if (!$selector) + break; + // avoid first space or / + if (in_array($selector[0], $notSimpleSelector)) + $selector = array_slice($selector, 1); + // PER NODE selector chunks + foreach ($this->stack() as $node) { + $break = false; + foreach ($selector as $s) { + if (!($node instanceof \DOMElement)) { + // all besides \DOMElement + if ($s[0] == '[') { + $attr = trim($s, '[]'); + if (mb_strpos($attr, '=')) { + list($attr, $val) = explode('=', $attr); + if ($attr == 'nodeType' && $node->nodeType != $val) + $break = true; + } + } else + $break = true; + } else { + // \DOMElement only + // ID + if ($s[0] == '#') { + if ($node->getAttribute('id') != substr($s, 1)) + $break = true; + // CLASSES + } else if ($s[0] == '.') { + if (!$this->matchClasses($s, $node)) + $break = true; + // ATTRS + } else if ($s[0] == '[') { + // strip side brackets + $attr = trim($s, '[]'); + if (mb_strpos($attr, '=')) { + list($attr, $val) = explode('=', $attr); + $val = self::unQuote($val); + if ($attr == 'nodeType') { + if ($val != $node->nodeType) + $break = true; + } else if ($this->isRegexp($attr)) { + $val = extension_loaded('mbstring') + && phpQuery::$mbstringSupport ? quotemeta(trim($val, '"\'')) + : preg_quote(trim($val, '"\''), '@'); + // switch last character + switch (substr($attr, -1)) { + // quotemeta used insted of preg_quote + // http://code.google.com/p/phpquery/issues/detail?id=76 + case '^': + $pattern = '^' . $val; + break; + case '*': + $pattern = '.*' . $val . '.*'; + break; + case '$': + $pattern = '.*' . $val . '$'; + break; + } + // cut last character + $attr = substr($attr, 0, -1); + $isMatch = extension_loaded('mbstring') + && phpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr)) + : preg_match("@{$pattern}@", $node->getAttribute($attr)); + if (!$isMatch) + $break = true; + } else if ($node->getAttribute($attr) != $val) + $break = true; + } else if (!$node->hasAttribute($attr)) + $break = true; + // PSEUDO CLASSES + } else if ($s[0] == ':') { + // skip + // TAG + } else if (trim($s)) { + if ($s != '*') { + // TODO namespaces + if (isset($node->tagName)) { + if ($node->tagName != $s) + $break = true; + } else if ($s == 'html' && !$this->isRoot($node)) + $break = true; + } + // AVOID NON-SIMPLE SELECTORS + } else if (in_array($s, $notSimpleSelector)) { + $break = true; + $this->debug( + array( + 'Skipping non simple selector', + $selector + ) + ); + } + } + if ($break) + break; + } + // if element passed all chunks of selector - add it to new stack + if (!$break) + $stack[] = $node; } + $tmpStack = $this->elements; + $this->elements = $stack; + // PER ALL NODES selector chunks + foreach ($selector as $s) + // PSEUDO CLASSES + if ($s[0] == ':') + $this->pseudoClasses($s); + foreach ($this->elements as $node) + // XXX it should be merged without duplicates + // but jQuery doesnt do that + $finalStack[] = $node; + $this->elements = $tmpStack; + } + $this->elements = $finalStack; + if ($_skipHistory) { + return $this; + } else { + $this->debug("Stack length after filter(): " . count($finalStack)); + return $this->newInstance(); + } + } + + /** + * + * @param $value + * @return unknown_type + * @TODO implement in all methods using passed parameters + */ + protected static function unQuote($value) + { + return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1) + : $value; + } + + /** + * Enter description here... + * + * @link http://docs.jquery.com/Ajax/load + * @param $url + * @param null $data + * @param null $callback + * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo Support $selector + */ + public function load($url, $data = null, $callback = null) + { + if ($data && !is_array($data)) { + $callback = $data; + $data = null; + } + if (mb_strpos($url, ' ') !== false) { + $matches = null; + if (extension_loaded('mbstring') && phpQuery::$mbstringSupport) + mb_ereg('^([^ ]+) (.*)$', $url, $matches); else - $break = true; - } - else { - // \DOMElement only - // ID - if ($s[0] == '#') { - if ($node->getAttribute('id') != substr($s, 1)) - $break = true; - // CLASSES - } - else if ($s[0] == '.') { - if (!$this->matchClasses($s, $node)) - $break = true; - // ATTRS + preg_match('@^([^ ]+) (.*)$@', $url, $matches); + $url = $matches[1]; + $selector = $matches[2]; + // FIXME this sucks, pass as callback param + $this->_loadSelector = $selector; + } + $ajax = array( + 'url' => $url, + 'type' => $data ? 'POST' : 'GET', + 'data' => $data, + 'complete' => $callback, + 'success' => array( + $this, + '__loadSuccess' + ) + ); + phpQuery::ajax($ajax); + return $this; + } + + /** + * @access private + * @param $html + */ + public function __loadSuccess($html) + { + if ($this->_loadSelector) { + $html = phpQuery::newDocument($html)->find($this->_loadSelector); + unset($this->_loadSelector); + } + foreach ($this->stack(1) as $node) { + phpQuery::pq($node, $this->getDocumentID())->markup($html); + } + } + + /** + * Allows users to enter strings of CSS selectors. Useful + * when the CSS is loaded via style or @imports that phpQuery can't load + * because it doesn't know the URL context of the request. + */ + public function addCSS($string) + { + if (!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = ''; + } + $this->cssString[$this->getDocumentID()] .= $string; + $this->parseCSS(); + } + + /** + * Either sets the CSS property of an object or retrieves the + * CSS property of a proejct. + * + * @param $property_name + * @param bool $value + * @return string of css property value + * @todo + */ + public function css($property_name, $value = false) + { + if (!isset($this->cssIsParsed[$this->getDocumentID()]) + || $this->cssIsParsed[$this->getDocumentID()] = false + ) { + $this->parseCSS(); + } + $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); + if (!$value) { + if (isset($data[$property_name])) { + return $data[$property_name]['value']; } - else if ($s[0] == '[') { - // strip side brackets - $attr = trim($s, '[]'); - if (mb_strpos($attr, '=')) { - list($attr, $val) = explode('=', $attr); - $val = self::unQuote($val); - if ($attr == 'nodeType') { - if ($val != $node->nodeType) - $break = true; - } - else if ($this->isRegexp($attr)) { - $val = extension_loaded('mbstring') - && phpQuery::$mbstringSupport ? quotemeta(trim($val, '"\'')) - : preg_quote(trim($val, '"\''), '@'); - // switch last character - switch (substr($attr, -1)) { - // quotemeta used insted of preg_quote - // http://code.google.com/p/phpquery/issues/detail?id=76 - case '^': - $pattern = '^' . $val; - break; - case '*': - $pattern = '.*' . $val . '.*'; - break; - case '$': - $pattern = '.*' . $val . '$'; - break; - } - // cut last character - $attr = substr($attr, 0, -1); - $isMatch = extension_loaded('mbstring') - && phpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr)) - : preg_match("@{$pattern}@", $node->getAttribute($attr)); - if (!$isMatch) - $break = true; + return null; + } + $specificity = (isset($data[$property_name])) ? $data[$property_name]['specificity'] + + 1 : 1000; + $data[$property_name] = array( + 'specificity' => $specificity, + 'value' => $value + ); + phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); + $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); + + if ($specificity >= 1000) { + $styles = array(); + foreach ($this->data('phpquery_css') as $k => $v) { + if ($v['specificity'] >= 1000) { + $styles[$k] = trim($k) . ':' . trim($v['value']); } - else if ($node->getAttribute($attr) != $val) - $break = true; - } - else if (!$node->hasAttribute($attr)) - $break = true; - // PSEUDO CLASSES } - else if ($s[0] == ':') { - // skip - // TAG + ksort($styles); + if (empty($styles)) { + $this->removeAttr('style'); + } elseif (phpQuery::$enableCssShorthand) { + $parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}'); + $doc = $parser->parse(); + $doc->createShorthands(); + $style = trim($doc->__toString(), "\n\r\t {}"); + } else { + $style = join(';', $styles); } - else if (trim($s)) { - if ($s != '*') { - // TODO namespaces - if (isset($node->tagName)) { - if ($node->tagName != $s) - $break = true; + $this->attr('style', $style); + } + } + + public function parseCSS() + { + if (!isset($this->cssString[$this->getDocumentID()])) { + $this->cssString[$this->getDocumentID()] = file_get_contents( + dirname(__FILE__) + . '/Resources/default.css' + ); + } + foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) { + $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); + } + + $CssParser = new CssParser($this->cssString[$this->getDocumentID()]); + $CssDocument = $CssParser->parse(); + foreach ($CssDocument->getAllRuleSets() as $ruleset) { + foreach ($ruleset->getSelector() as $selector) { + $specificity = $selector->getSpecificity(); + foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || $existing[$rule]['specificity'] <= $specificity + ) { + $value = $value->getValue(); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => $specificity, + 'value' => $value + ); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); } - else if ($s == 'html' && !$this->isRoot($node)) - $break = true; - } - // AVOID NON-SIMPLE SELECTORS } - else if (in_array($s, $notSimpleSelector)) { - $break = true; - $this->debug(array( - 'Skipping non simple selector', - $selector - )); + } + foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) { + $existing = pq($el)->data('phpquery_css'); + $style = pq($el)->attr('style'); + $style = strlen($style) ? explode(';', $style) : array(); + foreach ($this->attribute_css_mapping as $map => $css_equivalent) { + if ($el->hasAttribute($map)) { + $style[] = $css_equivalent . ':' . pq($el)->attr($map); + } } - } - if ($break) - break; - } - // if element passed all chunks of selector - add it to new stack - if (!$break) - $stack[] = $node; - } - $tmpStack = $this->elements; - $this->elements = $stack; - // PER ALL NODES selector chunks - foreach ($selector as $s) - // PSEUDO CLASSES - if ($s[0] == ':') - $this->pseudoClasses($s); - foreach ($this->elements as $node) - // XXX it should be merged without duplicates - // but jQuery doesnt do that - $finalStack[] = $node; - $this->elements = $tmpStack; - } - $this->elements = $finalStack; - if ($_skipHistory) { - return $this; - } - else { - $this->debug("Stack length after filter(): " . count($finalStack)); - return $this->newInstance(); - } - } - /** - * - * @param $value - * @return unknown_type - * @TODO implement in all methods using passed parameters - */ - protected static function unQuote($value) { - return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1) - : $value; - } - /** - * Enter description here... - * - * @link http://docs.jquery.com/Ajax/load - * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo Support $selector - */ - public function load($url, $data = null, $callback = null) { - if ($data && !is_array($data)) { - $callback = $data; - $data = null; - } - if (mb_strpos($url, ' ') !== false) { - $matches = null; - if (extension_loaded('mbstring') && phpQuery::$mbstringSupport) - mb_ereg('^([^ ]+) (.*)$', $url, $matches); - else - preg_match('@^([^ ]+) (.*)$@', $url, $matches); - $url = $matches[1]; - $selector = $matches[2]; - // FIXME this sucks, pass as callback param - $this->_loadSelector = $selector; - } - $ajax = array( - 'url' => $url, - 'type' => $data ? 'POST' : 'GET', - 'data' => $data, - 'complete' => $callback, - 'success' => array( - $this, - '__loadSuccess' - ) - ); - phpQuery::ajax($ajax); - return $this; - } - /** - * @access private - * @param $html - * @return unknown_type - */ - public function __loadSuccess($html) { - if ($this->_loadSelector) { - $html = phpQuery::newDocument($html)->find($this->_loadSelector); - unset($this->_loadSelector); - } - foreach ($this->stack(1) as $node) { - phpQuery::pq($node, $this->getDocumentID())->markup($html); - } - } - - /** - * Allows users to enter strings of CSS selectors. Useful - * when the CSS is loaded via style or @imports that phpQuery can't load - * because it doesn't know the URL context of the request. - */ - public function addCSS($string) { - if (!isset($this->cssString[$this->getDocumentID()])) { - $this->cssString[$this->getDocumentID()] = ''; - } - $this->cssString[$this->getDocumentID()] .= $string; - $this->parseCSS(); - } - /** - * Either sets the CSS property of an object or retrieves the - * CSS property of a proejct. - * - * @return string of css property value - * @todo - */ - public function css($property_name, $value = FALSE) { - if (!isset($this->cssIsParsed[$this->getDocumentID()]) - || $this->cssIsParsed[$this->getDocumentID()] = false) { - $this->parseCSS(); - } - $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID()); - if (!$value) { - if (isset($data[$property_name])) { - return $data[$property_name]['value']; - } - return null; - } - $specificity = (isset($data[$property_name])) ? $data[$property_name]['specificity'] - + 1 : 1000; - $data[$property_name] = array( - 'specificity' => $specificity, - 'value' => $value - ); - phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID()); - $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID())); - - if ($specificity >= 1000) { - $styles = array(); - foreach ($this->data('phpquery_css') as $k => $v) { - if ($v['specificity'] >= 1000) { - $styles[$k] = trim($k) . ':' . trim($v['value']); - } - } - ksort($styles); - if (empty($styles)) { - $this->removeAttr('style'); - } - elseif (phpQuery::$enableCssShorthand) { - $parser = new Sabberworm\CSS\Parser('{' . join(';', $styles) . '}'); - $doc = $parser->parse(); - $doc->createShorthands(); - $style = trim($doc->__toString(), "\n\r\t {}"); - } - else { - $style = join(';', $styles); - } - $this->attr('style', $style); - } - } - - public function parseCSS() { - if (!isset($this->cssString[$this->getDocumentID()])) { - $this->cssString[$this->getDocumentID()] = file_get_contents(dirname(__FILE__) - . '/Resources/default.css'); - } - foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) { - $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text(); - } - - $CssParser = new CssParser($this->cssString[$this->getDocumentID()]); - $CssDocument = $CssParser->parse(); - foreach ($CssDocument->getAllRuleSets() as $ruleset) { - foreach ($ruleset->getSelector() as $selector) { - $specificity = $selector->getSpecificity(); - foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - if (phpQuery::$enableCssShorthand) { - $ruleset->expandShorthands(); - } - foreach ($ruleset->getRules() as $value) { - $rule = $value->getRule(); - if (!isset($existing[$rule]) - || $existing[$rule]['specificity'] <= $specificity) { - $value = $value->getValue(); - $value = (is_object($value)) ? $value->__toString() : $value; - $existing[$rule] = array( - 'specificity' => $specificity, - 'value' => $value - ); + if (count($style)) { + $CssParser = new CssParser('#ruleset {' . implode(';', $style) . '}'); + $CssDocument = $CssParser->parse(); + $ruleset = $CssDocument->getAllRulesets(); + $ruleset = reset($ruleset); + if (phpQuery::$enableCssShorthand) { + $ruleset->expandShorthands(); + } + foreach ($ruleset->getRules() as $value) { + $rule = $value->getRule(); + if (!isset($existing[$rule]) + || 1000 >= $existing[$rule]['specificity'] + ) { + $value = $value->getValue(); + $value = (is_object($value)) ? $value->__toString() : $value; + $existing[$rule] = array( + 'specificity' => 1000, + 'value' => $value + ); + } + } + phpQuery::pq($el)->data('phpquery_css', $existing); + $this->bubbleCSS(phpQuery::pq($el)); } - } - phpQuery::pq($el)->data('phpquery_css', $existing); - $this->bubbleCSS(phpQuery::pq($el)); - } - } - } - foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) { - $existing = pq($el)->data('phpquery_css'); - $style = pq($el)->attr('style'); - $style = strlen($style) ? explode(';', $style) : array(); - foreach ($this->attribute_css_mapping as $map => $css_equivalent) { - if ($el->hasAttribute($map)) { - $style[] = $css_equivalent . ':' . pq($el)->attr($map); - } - } - if (count($style)) { - $CssParser = new CssParser('#ruleset {' . implode(';', $style) . '}'); - $CssDocument = $CssParser->parse(); - $ruleset = $CssDocument->getAllRulesets(); - $ruleset = reset($ruleset); - if (phpQuery::$enableCssShorthand) { - $ruleset->expandShorthands(); - } - foreach ($ruleset->getRules() as $value) { - $rule = $value->getRule(); - if (!isset($existing[$rule]) - || 1000 >= $existing[$rule]['specificity']) { - $value = $value->getValue(); - $value = (is_object($value)) ? $value->__toString() : $value; - $existing[$rule] = array( - 'specificity' => 1000, - 'value' => $value - ); - } } - phpQuery::pq($el)->data('phpquery_css', $existing); - $this->bubbleCSS(phpQuery::pq($el)); - } - } - } - - protected function bubbleCSS($element) { - $style = $element->data('phpquery_css'); - foreach ($element->children() as $element_child) { - $existing = phpQuery::pq($element_child)->data('phpquery_css'); - foreach ($style as $rule => $value) { - if (!isset($existing[$rule]) - || $value['specificity'] > $existing[$rule]['specificity']) { - $existing[$rule] = $value; - } - } - phpQuery::pq($element_child)->data('phpquery_css', $existing); - if (phpQuery::pq($element_child)->children()->length) { - $this->bubbleCSS(phpQuery::pq($element_child)); - } - } - } - - /** - * @todo - * - */ - public function show() { - $display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state') - : 'block'; - $this->css('display', $display); - return $this; - } - /** - * @todo - * - */ - public function hide() { - $this->data('phpquery_display_state', $this->css('display')); - $this->css('display', 'none'); - return $this; - } - /** - * Trigger a type of event on every matched element. - * - * @param unknown_type $type - * @param unknown_type $data - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support more than event in $type (space-separated) - */ - public function trigger($type, $data = array()) { - foreach ($this->elements as $node) - PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node); - return $this; - } - /** - * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. - * - * @param unknown_type $type - * @param unknown_type $data - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO - */ - public function triggerHandler($type, $data = array()) { - // TODO; - } - /** - * Binds a handler to one or more events (like click) for each matched element. - * Can also bind custom events. - * - * @param unknown_type $type - * @param unknown_type $data Optional - * @param unknown_type $callback - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO support '!' (exclusive) events - * @TODO support more than event in $type (space-separated) - */ - public function bind($type, $data, $callback = null) { - // TODO check if $data is callable, not using is_callable - if (!isset($callback)) { - $callback = $data; - $data = null; - } - foreach ($this->elements as $node) - PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback); - return $this; - } - /** - * Enter description here... - * - * @param unknown_type $type - * @param unknown_type $callback - * @return unknown - * @TODO namespace events - * @TODO support more than event in $type (space-separated) - */ - public function unbind($type = null, $callback = null) { - foreach ($this->elements as $node) - PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback); - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function change($callback = null) { - if ($callback) - return $this->bind('change', $callback); - return $this->trigger('change'); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function submit($callback = null) { - if ($callback) - return $this->bind('submit', $callback); - return $this->trigger('submit'); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function click($callback = null) { - if ($callback) - return $this->bind('click', $callback); - return $this->trigger('click'); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAllOld($wrapper) { - $wrapper = pq($wrapper)->_clone(); - if (!$wrapper->length() || !$this->length()) - return $this; - $wrapper->insertBefore($this->elements[0]); - $deepest = $wrapper->elements[0]; - while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) - $deepest = $deepest->firstChild; - pq($deepest)->append($this); - return $this; - } - /** - * Enter description here... - * - * TODO testme... - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAll($wrapper) { - if (!$this->length()) - return $this; - return phpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(array( - $this, - '___wrapAllCallback' - ))->append($this); - } - /** - * - * @param $node - * @return unknown_type - * @access private - */ - public function ___wrapAllCallback($node) { - $deepest = $node; - while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) - $deepest = $deepest->firstChild; - return $deepest; - } - /** - * Enter description here... - * NON JQUERY METHOD - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapAllPHP($codeBefore, $codeAfter) { - return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end(); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrap($wrapper) { - foreach ($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapPHP($codeBefore, $codeAfter) { - foreach ($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapInner($wrapper) { - foreach ($this->stack() as $node) - phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper); - return $this; - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function wrapInnerPHP($codeBefore, $codeAfter) { - foreach ($this->stack(1) as $node) - phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter); - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @testme Support for text nodes - */ - public function contents() { - $stack = array(); - foreach ($this->stack(1) as $el) { - // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56 - // if (! isset($el->childNodes)) - // continue; - foreach ($el->childNodes as $node) { - $stack[] = $node; - } - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * jQuery difference. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function contentsUnwrap() { - foreach ($this->stack(1) as $node) { - if (!$node->parentNode) - continue; - $childNodes = array(); - // any modification in DOM tree breaks childNodes iteration, so cache them first - foreach ($node->childNodes as $chNode) - $childNodes[] = $chNode; - foreach ($childNodes as $chNode) - // $node->parentNode->appendChild($chNode); - $node->parentNode->insertBefore($chNode, $node); - $node->parentNode->removeChild($node); - } - return $this; - } - /** - * Enter description here... - * - * jQuery difference. - */ - public function switchWith($markup) { - $markup = pq($markup, $this->getDocumentID()); - $content = null; - foreach ($this->stack(1) as $node) { - pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content)); - } - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function eq($num) { - $oldStack = $this->elements; - $this->elementsBackup = $this->elements; - $this->elements = array(); - if (isset($oldStack[$num])) - $this->elements[] = $oldStack[$num]; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function size() { - return count($this->elements); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @deprecated Use length as attribute - */ - public function length() { - return $this->size(); - } - public function count() { - return $this->size(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo $level - */ - public function end($level = 1) { - // $this->elements = array_pop( $this->history ); - // return $this; - // $this->previous->DOM = $this->DOM; - // $this->previous->XPath = $this->XPath; - return $this->previous ? $this->previous : $this; - } - /** - * Enter description here... - * Normal use ->clone() . - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _clone() { - $newStack = array(); - //pr(array('copy... ', $this->whois())); - //$this->dumpHistory('copy'); - $this->elementsBackup = $this->elements; - foreach ($this->elements as $node) { - $newStack[] = $node->cloneNode(true); - } - $this->elements = $newStack; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function replaceWithPHP($code) { - return $this->replaceWith(phpQuery::php($code)); - } - /** - * Enter description here... - * - * @param String|phpQuery $content - * @link http://docs.jquery.com/Manipulation/replaceWith#content - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function replaceWith($content) { - return $this->after($content)->remove(); - } - /** - * Enter description here... - * - * @param String $selector - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo this works ? - */ - public function replaceAll($selector) { - foreach (phpQuery::pq($selector, $this->getDocumentID()) as $node) - phpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove(); - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function remove($selector = null) { - $loop = $selector ? $this->filter($selector)->elements : $this->elements; - foreach ($loop as $node) { - if (!$node->parentNode) - continue; - if (isset($node->tagName)) - $this->debug("Removing '{$node->tagName}'"); - $node->parentNode->removeChild($node); - // Mutation event - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'DOMNodeRemoved' - )); - PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( - $event - ), $node); - } - return $this; - } - protected function markupEvents($newMarkup, $oldMarkup, $node) { - if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( - $event - ), $node); - } - } - /** - * jQuey difference - * - * @param $markup - * @return unknown_type - * @TODO trigger change event for textarea - */ - public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - if ($this->documentWrapper->isXML) - return call_user_func_array(array( - $this, - 'xml' - ), $args); - else - return call_user_func_array(array( - $this, - 'html' - ), $args); - } - /** - * jQuey difference - * - * @param $markup - * @return unknown_type - */ - public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - if ($this->documentWrapper->isXML) - return call_user_func_array(array( - $this, - 'xmlOuter' - ), $args); - else - return call_user_func_array(array( - $this, - 'htmlOuter' - ), $args); - } - /** - * Enter description here... - * - * @param unknown_type $html - * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @TODO force html result - */ - public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (isset($html)) { - // INSERT - $nodes = $this->documentWrapper->import($html); - $this->empty(); - foreach ($this->stack(1) as $alreadyAdded => $node) { - // for now, limit events for textarea - if (($this->isXHTML() || $this->isHTML()) - && $node->tagName == 'textarea') - $oldHtml = pq($node, $this->getDocumentID())->markup(); - foreach ($nodes as $newNode) { - $node->appendChild($alreadyAdded ? $newNode->cloneNode(true) - : $newNode); - } - // for now, limit events for textarea - if (($this->isXHTML() || $this->isHTML()) - && $node->tagName == 'textarea') - $this->markupEvents($html, $oldHtml, $node); - } - return $this; - } - else { - // FETCH - $return = $this->documentWrapper->markup($this->elements, true); - $args = func_get_args(); - foreach (array_slice($args, 1) as $callback) { - $return = phpQuery::callbackRun($callback, array( - $return - )); - } - return $return; - } - } - /** - * @TODO force xml result - */ - public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - return call_user_func_array(array( - $this, - 'html' - ), $args); - } - /** - * Enter description here... - * @TODO force html result - * - * @return String - */ - public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $markup = $this->documentWrapper->markup($this->elements); - // pass thou callbacks - $args = func_get_args(); - foreach ($args as $callback) { - $markup = phpQuery::callbackRun($callback, array( - $markup - )); - } - return $markup; - } - /** - * @TODO force xml result - */ - public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null) { - $args = func_get_args(); - return call_user_func_array(array( - $this, - 'htmlOuter' - ), $args); - } - public function __toString() { - return $this->markupOuter(); - } - /** - * Just like html(), but returns markup with VALID (dangerous) PHP tags. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo support returning markup with PHP tags when called without param - */ - public function php($code = null) { - return $this->markupPHP($code); - } - /** - * Enter description here... - * - * @param $code - * @return unknown_type - */ - public function markupPHP($code = null) { - return isset($code) ? $this->markup(phpQuery::php($code)) - : phpQuery::markupToPHP($this->markup()); - } - /** - * Enter description here... - * - * @param $code - * @return unknown_type - */ - public function markupOuterPHP() { - return phpQuery::markupToPHP($this->markupOuter()); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function children($selector = null) { - $stack = array(); - foreach ($this->stack(1) as $node) { - // foreach($node->getElementsByTagName('*') as $newNode) { - foreach ($node->childNodes as $newNode) { - if ($newNode->nodeType != 1) - continue; - if ($selector && !$this->is($selector, $newNode)) - continue; - if ($this->elementsContainsNode($newNode, $stack)) - continue; - $stack[] = $newNode; - } - } - $this->elementsBackup = $this->elements; - $this->elements = $stack; - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function ancestors($selector = null) { - return $this->children($selector); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function append($content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function appendPHP($content) { - return $this->insert("", 'append'); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function appendTo($seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prepend($content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @todo accept many arguments, which are joined, arrays maybe also - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prependPHP($content) { - return $this->insert("", 'prepend'); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prependTo($seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function before($content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function beforePHP($content) { - return $this->insert("", 'before'); - } - /** - * Enter description here... - * - * @param String|phpQuery - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function insertBefore($seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function after($content) { - return $this->insert($content, __FUNCTION__); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function afterPHP($content) { - return $this->insert("", 'after'); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function insertAfter($seletor) { - return $this->insert($seletor, __FUNCTION__); - } - /** - * Internal insert method. Don't use it. - * - * @param unknown_type $target - * @param unknown_type $type - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function insert($target, $type) { - $this->debug("Inserting data with '{$type}'"); - $to = false; - switch ($type) { - case 'appendTo': - case 'prependTo': - case 'insertBefore': - case 'insertAfter': - $to = true; - } - switch (gettype($target)) { - case 'string': - $insertFrom = $insertTo = array(); - if ($to) { - // INSERT TO - $insertFrom = $this->elements; - if (phpQuery::isMarkup($target)) { - // $target is new markup, import it - $insertTo = $this->documentWrapper->import($target); - // insert into selected element - } - else { - // $tagret is a selector - $thisStack = $this->elements; - $this->toRoot(); - $insertTo = $this->find($target)->elements; - $this->elements = $thisStack; - } + } + + protected function bubbleCSS($element) + { + $style = $element->data('phpquery_css'); + foreach ($element->children() as $element_child) { + $existing = phpQuery::pq($element_child)->data('phpquery_css'); + foreach ($style as $rule => $value) { + if (!isset($existing[$rule]) + || $value['specificity'] > $existing[$rule]['specificity'] + ) { + $existing[$rule] = $value; + } + } + phpQuery::pq($element_child)->data('phpquery_css', $existing); + if (phpQuery::pq($element_child)->children()->length) { + $this->bubbleCSS(phpQuery::pq($element_child)); + } } - else { - // INSERT FROM - $insertTo = $this->elements; - $insertFrom = $this->documentWrapper->import($target); - } - break; - case 'object': - $insertFrom = $insertTo = array(); - // phpQuery - if ($target instanceof self) { - if ($to) { - $insertTo = $target->elements; - if ($this->documentFragment && $this->stackIsRoot()) - // get all body children - // $loop = $this->find('body > *')->elements; - // TODO test it, test it hard... - // $loop = $this->newInstance($this->root)->find('> *')->elements; - $loop = $this->root->childNodes; - else - $loop = $this->elements; - // import nodes if needed - $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop - : $target->documentWrapper->import($loop); - } - else { - $insertTo = $this->elements; - if ($target->documentFragment && $target->stackIsRoot()) - // get all body children - // $loop = $target->find('body > *')->elements; - $loop = $target->root->childNodes; - else - $loop = $target->elements; - // import nodes if needed - $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop - : $this->documentWrapper->import($loop); - } - // DOMNODE - } - elseif ($target instanceof DOMNODE) { - // import node if needed - // if ( $target->ownerDocument != $this->DOM ) - // $target = $this->DOM->importNode($target, true); - if ($to) { - $insertTo = array( - $target - ); - if ($this->documentFragment && $this->stackIsRoot()) - // get all body children - $loop = $this->root->childNodes; - // $loop = $this->find('body > *')->elements; - else - $loop = $this->elements; - foreach ($loop as $fromNode) - // import nodes if needed - $insertFrom[] = !$fromNode->ownerDocument->isSameNode($target->ownerDocument) ? $target->ownerDocument->importNode($fromNode, true) - : $fromNode; - } - else { - // import node if needed - if (!$target->ownerDocument->isSameNode($this->document)) - $target = $this->document->importNode($target, true); - $insertTo = $this->elements; - $insertFrom[] = $target; - } + } + + /** + * @todo + * + */ + public function show() + { + $display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state') + : 'block'; + $this->css('display', $display); + return $this; + } + + /** + * @todo + * + */ + public function hide() + { + $this->data('phpquery_display_state', $this->css('display')); + $this->css('display', 'none'); + return $this; + } + + /** + * Trigger a type of event on every matched element. + * + * @param $type + * @param array|\PhpQuery $data + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support more than event in $type (space-separated) + */ + public function trigger($type, $data = array()) + { + foreach ($this->elements as $node) + PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node); + return $this; + } + + /** + * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions. + * + * @param $type + * @param $data + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO + */ + public function triggerHandler($type, $data = array()) + { + // TODO; + } + + /** + * Binds a handler to one or more events (like click) for each matched element. + * Can also bind custom events. + * + * @param $type + * @param mixed $data Optional + * @param $callback + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO support '!' (exclusive) events + * @TODO support more than event in $type (space-separated) + */ + public function bind($type, $data, $callback = null) + { + // TODO check if $data is callable, not using is_callable + if (!isset($callback)) { + $callback = $data; + $data = null; + } + foreach ($this->elements as $node) + PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback); + return $this; + } + + /** + * Enter description here... + * + * @param string $type + * @param $callback + * @return unknown + * @TODO namespace events + * @TODO support more than event in $type (space-separated) + */ + public function unbind($type = null, $callback = null) + { + foreach ($this->elements as $node) + PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback); + return $this; + } + + /** + * Enter description here... + * + * @param null $callback + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function change($callback = null) + { + if ($callback) + return $this->bind('change', $callback); + return $this->trigger('change'); + } + + /** + * Enter description here... + * + * @param null $callback + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function submit($callback = null) + { + if ($callback) + return $this->bind('submit', $callback); + return $this->trigger('submit'); + } + + /** + * Enter description here... + * + * @param null $callback + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function click($callback = null) + { + if ($callback) + return $this->bind('click', $callback); + return $this->trigger('click'); + } + + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAllOld($wrapper) + { + $wrapper = pq($wrapper)->_clone(); + if (!$wrapper->length() || !$this->length()) + return $this; + $wrapper->insertBefore($this->elements[0]); + $deepest = $wrapper->elements[0]; + while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) + $deepest = $deepest->firstChild; + pq($deepest)->append($this); + return $this; + } + + /** + * Enter description here... + * + * TODO testme... + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAll($wrapper) + { + if (!$this->length()) + return $this; + return phpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map( + array( + $this, + '___wrapAllCallback' + ) + )->append($this); + } + + /** + * + * @param $node + * @return unknown_type + * @access private + */ + public function ___wrapAllCallback($node) + { + $deepest = $node; + while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) + $deepest = $deepest->firstChild; + return $deepest; + } + + /** + * Enter description here... + * NON JQUERY METHOD + * + * @param $codeBefore + * @param $codeAfter + * @internal param $ String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapAllPHP($codeBefore, $codeAfter) + { + return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end(); + } + + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrap($wrapper) + { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper); + return $this; + } + + /** + * Enter description here... + * + * @param $codeBefore + * @param $codeAfter + * @internal param $ String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapPHP($codeBefore, $codeAfter) + { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter); + return $this; + } + + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapInner($wrapper) + { + foreach ($this->stack() as $node) + phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper); + return $this; + } + + /** + * Enter description here... + * + * @param $codeBefore + * @param $codeAfter + * @internal param $ String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function wrapInnerPHP($codeBefore, $codeAfter) + { + foreach ($this->stack(1) as $node) + phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter); + return $this; + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @testme Support for text nodes + */ + public function contents() + { + $stack = array(); + foreach ($this->stack(1) as $el) { + // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56 + // if (! isset($el->childNodes)) + // continue; + foreach ($el->childNodes as $node) { + $stack[] = $node; + } + } + return $this->newInstance($stack); + } + + /** + * Enter description here... + * + * jQuery difference. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function contentsUnwrap() + { + foreach ($this->stack(1) as $node) { + if (!$node->parentNode) + continue; + $childNodes = array(); + // any modification in DOM tree breaks childNodes iteration, so cache them first + foreach ($node->childNodes as $chNode) + $childNodes[] = $chNode; + foreach ($childNodes as $chNode) + // $node->parentNode->appendChild($chNode); + $node->parentNode->insertBefore($chNode, $node); + $node->parentNode->removeChild($node); + } + return $this; + } + + /** + * Enter description here... + * + * jQuery difference. + */ + public function switchWith($markup) + { + $markup = pq($markup, $this->getDocumentID()); + $content = null; + foreach ($this->stack(1) as $node) { + pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content)); + } + return $this; + } + + /** + * Enter description here... + * + * @param $num + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function eq($num) + { + $oldStack = $this->elements; + $this->elementsBackup = $this->elements; + $this->elements = array(); + if (isset($oldStack[$num])) + $this->elements[] = $oldStack[$num]; + return $this->newInstance(); + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function size() + { + return count($this->elements); + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @deprecated Use length as attribute + */ + public function length() + { + return $this->size(); + } + + public function count() + { + return $this->size(); + } + + /** + * Enter description here... + * + * @param int $level + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo $level + */ + public function end($level = 1) + { + // $this->elements = array_pop( $this->history ); + // return $this; + // $this->previous->DOM = $this->DOM; + // $this->previous->XPath = $this->XPath; + return $this->previous ? $this->previous : $this; + } + + /** + * Enter description here... + * Normal use ->clone() . + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _clone() + { + $newStack = array(); + //pr(array('copy... ', $this->whois())); + //$this->dumpHistory('copy'); + $this->elementsBackup = $this->elements; + foreach ($this->elements as $node) { + $newStack[] = $node->cloneNode(true); + } + $this->elements = $newStack; + return $this->newInstance(); + } + + /** + * Enter description here... + * + * @param $code + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function replaceWithPHP($code) + { + return $this->replaceWith(phpQuery::php($code)); + } + + /** + * Enter description here... + * + * @param String|phpQuery $content + * @link http://docs.jquery.com/Manipulation/replaceWith#content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function replaceWith($content) + { + return $this->after($content)->remove(); + } + + /** + * Enter description here... + * + * @param String $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo this works ? + */ + public function replaceAll($selector) + { + foreach (phpQuery::pq($selector, $this->getDocumentID()) as $node) + phpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove(); + return $this; + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function remove($selector = null) + { + $loop = $selector ? $this->filter($selector)->elements : $this->elements; + foreach ($loop as $node) { + if (!$node->parentNode) + continue; + if (isset($node->tagName)) + $this->debug("Removing '{$node->tagName}'"); + $node->parentNode->removeChild($node); + // Mutation event + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'DOMNodeRemoved' + )); + PhpQueryEvents::trigger( + $this->getDocumentID(), + $event->type, + array( + $event + ), + $node + ); + } + return $this; + } + + protected function markupEvents($newMarkup, $oldMarkup, $node) + { + if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) { + $event = new DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + PhpQueryEvents::trigger( + $this->getDocumentID(), + $event->type, + array( + $event + ), + $node + ); + } + } + + /** + * jQuey difference + * + * @param $markup + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return unknown_type + * @TODO trigger change event for textarea + */ + public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + $args = func_get_args(); + if ($this->documentWrapper->isXML) + return call_user_func_array( + array( + $this, + 'xml' + ), + $args + ); + else + return call_user_func_array( + array( + $this, + 'html' + ), + $args + ); + } + + /** + * jQuey difference + * + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @internal param $markup + * @return unknown_type + */ + public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null) + { + $args = func_get_args(); + if ($this->documentWrapper->isXML) + return call_user_func_array( + array( + $this, + 'xmlOuter' + ), + $args + ); + else + return call_user_func_array( + array( + $this, + 'htmlOuter' + ), + $args + ); + } + + /** + * Enter description here... + * + * @param unknown_type $html + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @TODO force html result + */ + public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + if (isset($html)) { + // INSERT + $nodes = $this->documentWrapper->import($html); + $this->empty(); + foreach ($this->stack(1) as $alreadyAdded => $node) { + // for now, limit events for textarea + if (($this->isXHTML() || $this->isHTML()) + && $node->tagName == 'textarea' + ) + $oldHtml = pq($node, $this->getDocumentID())->markup(); + foreach ($nodes as $newNode) { + $node->appendChild( + $alreadyAdded ? $newNode->cloneNode(true) + : $newNode + ); + } + // for now, limit events for textarea + if (($this->isXHTML() || $this->isHTML()) + && $node->tagName == 'textarea' + ) + $this->markupEvents($html, $oldHtml, $node); + } + return $this; + } else { + // FETCH + $return = $this->documentWrapper->markup($this->elements, true); + $args = func_get_args(); + foreach (array_slice($args, 1) as $callback) { + $return = phpQuery::callbackRun( + $callback, + array( + $return + ) + ); + } + return $return; + } + } + + /** + * @TODO force xml result + */ + public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + $args = func_get_args(); + return call_user_func_array( + array( + $this, + 'html' + ), + $args + ); + } + + /** + * Enter description here... + * @TODO force html result + * + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return String + */ + public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null) + { + $markup = $this->documentWrapper->markup($this->elements); + // pass thou callbacks + $args = func_get_args(); + foreach ($args as $callback) { + $markup = phpQuery::callbackRun( + $callback, + array( + $markup + ) + ); + } + return $markup; + } + + /** + * @TODO force xml result + */ + public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null) + { + $args = func_get_args(); + return call_user_func_array( + array( + $this, + 'htmlOuter' + ), + $args + ); + } + + public function __toString() + { + return $this->markupOuter(); + } + + /** + * Just like html(), but returns markup with VALID (dangerous) PHP tags. + * + * @param null $code + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo support returning markup with PHP tags when called without param + */ + public function php($code = null) + { + return $this->markupPHP($code); + } + + /** + * Enter description here... + * + * @param $code + * @return unknown_type + */ + public function markupPHP($code = null) + { + return isset($code) ? $this->markup(phpQuery::php($code)) + : phpQuery::markupToPHP($this->markup()); + } + + /** + * Enter description here... + * + * @internal param $code + * @return unknown_type + */ + public function markupOuterPHP() + { + return phpQuery::markupToPHP($this->markupOuter()); + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function children($selector = null) + { + $stack = array(); + foreach ($this->stack(1) as $node) { + // foreach($node->getElementsByTagName('*') as $newNode) { + foreach ($node->childNodes as $newNode) { + if ($newNode->nodeType != 1) + continue; + if ($selector && !$this->is($selector, $newNode)) + continue; + if ($this->elementsContainsNode($newNode, $stack)) + continue; + $stack[] = $newNode; + } } - break; - } - phpQuery::debug("From " . count($insertFrom) . "; To " . count($insertTo) - . " nodes"); - foreach ($insertTo as $insertNumber => $toNode) { - // we need static relative elements in some cases - switch ($type) { - case 'prependTo': - case 'prepend': - $firstChild = $toNode->firstChild; - break; - case 'insertAfter': - case 'after': - $nextSibling = $toNode->nextSibling; - break; - } - foreach ($insertFrom as $fromNode) { - // clone if inserted already before - $insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode; + $this->elementsBackup = $this->elements; + $this->elements = $stack; + return $this->newInstance(); + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function ancestors($selector = null) + { + return $this->children($selector); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function append($content) + { + return $this->insert($content, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function appendPHP($content) + { + return $this->insert("", 'append'); + } + + /** + * Enter description here... + * + * @param $seletor + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function appendTo($seletor) + { + return $this->insert($seletor, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prepend($content) + { + return $this->insert($content, __FUNCTION__); + } + + /** + * Enter description here... + * + * @todo accept many arguments, which are joined, arrays maybe also + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prependPHP($content) + { + return $this->insert("", 'prepend'); + } + + /** + * Enter description here... + * + * @param $seletor + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prependTo($seletor) + { + return $this->insert($seletor, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function before($content) + { + return $this->insert($content, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function beforePHP($content) + { + return $this->insert("", 'before'); + } + + /** + * Enter description here... + * + * @param String|phpQuery + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function insertBefore($seletor) + { + return $this->insert($seletor, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function after($content) + { + return $this->insert($content, __FUNCTION__); + } + + /** + * Enter description here... + * + * @param $content + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function afterPHP($content) + { + return $this->insert("", 'after'); + } + + /** + * Enter description here... + * + * @param $seletor + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function insertAfter($seletor) + { + return $this->insert($seletor, __FUNCTION__); + } + + /** + * Internal insert method. Don't use it. + * + * @param unknown_type $target + * @param unknown_type $type + * @throws \Exception + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function insert($target, $type) + { + $this->debug("Inserting data with '{$type}'"); + $to = false; switch ($type) { - case 'appendTo': - case 'append': - // $toNode->insertBefore( - // $fromNode, - // $toNode->lastChild->nextSibling - // ); - $toNode->appendChild($insert); - $eventTarget = $insert; - break; - case 'prependTo': - case 'prepend': - $toNode->insertBefore($insert, $firstChild); - break; - case 'insertBefore': - case 'before': - if (!$toNode->parentNode) - throw new \Exception("No parentNode, can't do {$type}()"); - else - $toNode->parentNode->insertBefore($insert, $toNode); - break; - case 'insertAfter': - case 'after': - if (!$toNode->parentNode) - throw new \Exception("No parentNode, can't do {$type}()"); - else - $toNode->parentNode->insertBefore($insert, $nextSibling); - break; - } - // Mutation event - $event = new DOMEvent(array( - 'target' => $insert, - 'type' => 'DOMNodeInserted' - )); - PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( - $event - ), $insert); - } - } - return $this; - } - /** - * Enter description here... - * - * @return Int - */ - public function index($subject) { - $index = -1; - $subject = $subject instanceof PhpQueryObject ? $subject->elements[0] - : $subject; - foreach ($this->newInstance() as $k => $node) { - if ($node->isSameNode($subject)) - $index = $k; - } - return $index; - } - /** - * Enter description here... - * - * @param unknown_type $start - * @param unknown_type $end - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @testme - */ - public function slice($start, $end = null) { - // $last = count($this->elements)-1; - // $end = $end - // ? min($end, $last) - // : $last; - // if ($start < 0) - // $start = $last+$start; - // if ($start > $last) - // return array(); - if ($end > 0) - $end = $end - $start; - return $this->newInstance(array_slice($this->elements, $start, $end)); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function reverse() { - $this->elementsBackup = $this->elements; - $this->elements = array_reverse($this->elements); - return $this->newInstance(); - } - /** - * Return joined text content. - * @return String - */ - public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null) { - if (isset($text)) - return $this->html(htmlspecialchars($text)); - $args = func_get_args(); - $args = array_slice($args, 1); - $return = ''; - foreach ($this->elements as $node) { - $text = $node->textContent; - if (count($this->elements) > 1 && $text) - $text .= "\n"; - foreach ($args as $callback) { - $text = phpQuery::callbackRun($callback, array( - $text - )); - } - $return .= $text; - } - return $return; - } - - /** - * @return The text content of each matching element, like - * text() but returns an array with one entry per matched element. - * Read only. - */ - public function texts($attr = null) { - $results = array(); - foreach ($this->elements as $node) { - $results[] = $node->textContent; - } - return $results; - } - - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function plugin($class, $file = null) { - phpQuery::plugin($class, $file); - return $this; - } - /** - * Deprecated, use $pq->plugin() instead. - * - * @deprecated - * @param $class - * @param $file - * @return unknown_type - */ - public static function extend($class, $file = null) { - return $this->plugin($class, $file); - } - /** - * - * @access private - * @param $method - * @param $args - * @return unknown_type - */ - public function __call($method, $args) { - $aliasMethods = array( - 'clone', - 'empty' - ); - if (isset(phpQuery::$extendMethods[$method])) { - array_unshift($args, $this); - return phpQuery::callbackRun(phpQuery::$extendMethods[$method], $args); - } - else if (isset(phpQuery::$pluginsMethods[$method])) { - array_unshift($args, $this); - $class = phpQuery::$pluginsMethods[$method]; - $realClass = "\PhpQuery\Plugin\$class"; - $return = call_user_func_array(array( - $realClass, - $method - ), $args); - // XXX deprecate ? - return is_null($return) ? $this : $return; - } - else if (in_array($method, $aliasMethods)) { - return call_user_func_array(array( - $this, - '_' . $method - ), $args); - } - else - throw new \Exception("Method '{$method}' doesnt exist"); - } - /** - * Safe rename of next(). - * - * Use it ONLY when need to call next() on an iterated object (in same time). - * Normaly there is no need to do such thing ;) - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _next($selector = null) { - return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true)); - } - /** - * Use prev() and next(). - * - * @deprecated - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _prev($selector = null) { - return $this->prev($selector); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function prev($selector = null) { - return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true)); - } - /** - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo - */ - public function prevAll($selector = null) { - return $this->newInstance($this->getElementSiblings('previousSibling', $selector)); - } - /** - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo FIXME: returns source elements insted of next siblings - */ - public function nextAll($selector = null) { - return $this->newInstance($this->getElementSiblings('nextSibling', $selector)); - } - /** - * @access private - */ - protected function getElementSiblings($direction, $selector = null, $limitToOne = false) { - $stack = array(); - $count = 0; - foreach ($this->stack() as $node) { - $test = $node; - while (isset($test->{$direction}) && $test->{$direction}) { - $test = $test->{$direction}; - if (!$test instanceof \DOMElement) - continue; - $stack[] = $test; - if ($limitToOne) - break; - } - } - if ($selector) { - $stackOld = $this->elements; - $this->elements = $stack; - $stack = $this->filter($selector, true)->stack(); - $this->elements = $stackOld; - } - return $stack; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function siblings($selector = null) { - $stack = array(); - $siblings = array_merge($this->getElementSiblings('previousSibling', $selector), $this->getElementSiblings('nextSibling', $selector)); - foreach ($siblings as $node) { - if (!$this->elementsContainsNode($node, $stack)) - $stack[] = $node; - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function not($selector = null) { - if (is_string($selector)) - phpQuery::debug(array( - 'not', - $selector - )); - else - phpQuery::debug('not'); - $stack = array(); - if ($selector instanceof self || $selector instanceof DOMNODE) { - foreach ($this->stack() as $node) { - if ($selector instanceof self) { - $matchFound = false; - foreach ($selector->stack() as $notNode) { - if ($notNode->isSameNode($node)) - $matchFound = true; - } - if (!$matchFound) - $stack[] = $node; + case 'appendTo': + case 'prependTo': + case 'insertBefore': + case 'insertAfter': + $to = true; } - else if ($selector instanceof DOMNODE) { - if (!$selector->isSameNode($node)) - $stack[] = $node; + switch (gettype($target)) { + case 'string': + $insertFrom = $insertTo = array(); + if ($to) { + // INSERT TO + $insertFrom = $this->elements; + if (phpQuery::isMarkup($target)) { + // $target is new markup, import it + $insertTo = $this->documentWrapper->import($target); + // insert into selected element + } else { + // $tagret is a selector + $thisStack = $this->elements; + $this->toRoot(); + $insertTo = $this->find($target)->elements; + $this->elements = $thisStack; + } + } else { + // INSERT FROM + $insertTo = $this->elements; + $insertFrom = $this->documentWrapper->import($target); + } + break; + case 'object': + $insertFrom = $insertTo = array(); + // phpQuery + if ($target instanceof self) { + if ($to) { + $insertTo = $target->elements; + if ($this->documentFragment && $this->stackIsRoot()) + // get all body children + // $loop = $this->find('body > *')->elements; + // TODO test it, test it hard... + // $loop = $this->newInstance($this->root)->find('> *')->elements; + $loop = $this->root->childNodes; + else + $loop = $this->elements; + // import nodes if needed + $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop + : $target->documentWrapper->import($loop); + } else { + $insertTo = $this->elements; + if ($target->documentFragment && $target->stackIsRoot()) + // get all body children + // $loop = $target->find('body > *')->elements; + $loop = $target->root->childNodes; + else + $loop = $target->elements; + // import nodes if needed + $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop + : $this->documentWrapper->import($loop); + } + // DOMNODE + } elseif ($target instanceof \DOMNODE) { + // import node if needed + // if ( $target->ownerDocument != $this->DOM ) + // $target = $this->DOM->importNode($target, true); + if ($to) { + $insertTo = array( + $target + ); + if ($this->documentFragment && $this->stackIsRoot()) + // get all body children + $loop = $this->root->childNodes; + // $loop = $this->find('body > *')->elements; + else + $loop = $this->elements; + foreach ($loop as $fromNode) + // import nodes if needed + $insertFrom[] = !$fromNode->ownerDocument->isSameNode( + $target->ownerDocument + ) ? $target->ownerDocument->importNode($fromNode, true) + : $fromNode; + } else { + // import node if needed + if (!$target->ownerDocument->isSameNode($this->document)) + $target = $this->document->importNode($target, true); + $insertTo = $this->elements; + $insertFrom[] = $target; + } + } + break; } - else { - if (!$this->is($selector)) - $stack[] = $node; - } - } - } - else { - $orgStack = $this->stack(); - $matched = $this->filter($selector, true)->stack(); - // $matched = array(); - // // simulate OR in filter() instead of AND 5y - // foreach($this->parseSelector($selector) as $s) { - // $matched = array_merge($matched, - // $this->filter(array($s))->stack() - // ); - // } - foreach ($orgStack as $node) - if (!$this->elementsContainsNode($node, $matched)) - $stack[] = $node; - } - return $this->newInstance($stack); - } - /** - * Enter description here... - * - * @param string|PhpQueryObject - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function add($selector = null) { - if (!$selector) - return $this; - $stack = array(); - $this->elementsBackup = $this->elements; - $found = phpQuery::pq($selector, $this->getDocumentID()); - $this->merge($found->elements); - return $this->newInstance(); - } - /** - * @access private - */ - protected function merge() { - foreach (func_get_args() as $nodes) - foreach ($nodes as $newNode) - if (!$this->elementsContainsNode($newNode)) - $this->elements[] = $newNode; - } - /** - * @access private - * TODO refactor to stackContainsNode - */ - protected function elementsContainsNode($nodeToCheck, $elementsStack = null) { - $loop = !is_null($elementsStack) ? $elementsStack : $this->elements; - foreach ($loop as $node) { - if ($node->isSameNode($nodeToCheck)) - return true; - } - return false; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function parent($selector = null) { - $stack = array(); - foreach ($this->elements as $node) - if ($node->parentNode - && !$this->elementsContainsNode($node->parentNode, $stack)) - $stack[] = $node->parentNode; - $this->elementsBackup = $this->elements; - $this->elements = $stack; - if ($selector) - $this->filter($selector, true); - return $this->newInstance(); - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function parents($selector = null) { - $stack = array(); - if (!$this->elements) - $this->debug('parents() - stack empty'); - foreach ($this->elements as $node) { - $test = $node; - while ($test->parentNode) { - $test = $test->parentNode; - if ($this->isRoot($test)) - break; - if (!$this->elementsContainsNode($test, $stack)) { - $stack[] = $test; - continue; - } - } - } - $this->elementsBackup = $this->elements; - $this->elements = $stack; - if ($selector) - $this->filter($selector, true); - return $this->newInstance(); - } - /** - * Internal stack iterator. - * - * @access private - * @return {Array.} - */ - public function stack($nodeTypes = null) { - if (!isset($nodeTypes)) - return $this->elements; - if (!is_array($nodeTypes)) - $nodeTypes = array( - $nodeTypes - ); - $return = array(); - foreach ($this->elements as $node) { - if (in_array($node->nodeType, $nodeTypes)) - $return[] = $node; - } - return $return; - } - // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes - protected function attrEvents($attr, $oldAttr, $oldValue, $node) { - // skip events for XML documents - if (!$this->isXHTML() && !$this->isHTML()) - return; - $event = null; - // identify - $isInputValue = $node->tagName == 'input' - && (in_array($node->getAttribute('type'), array( - 'text', - 'password', - 'hidden' - )) || !$node->getAttribute('type')); - $isRadio = $node->tagName == 'input' - && $node->getAttribute('type') == 'radio'; - $isCheckbox = $node->tagName == 'input' - && $node->getAttribute('type') == 'checkbox'; - $isOption = $node->tagName == 'option'; - if ($isInputValue && $attr == 'value' - && $oldValue != $node->getAttribute($attr)) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - } - else if (($isRadio || $isCheckbox) && $attr == 'checked' - && ( - // check - (!$oldAttr && $node->hasAttribute($attr)) - // un-check - || (!$node->hasAttribute($attr) && $oldAttr))) { - $event = new DOMEvent(array( - 'target' => $node, - 'type' => 'change' - )); - } - else if ($isOption && $node->parentNode && $attr == 'selected' - && ( - // select - (!$oldAttr && $node->hasAttribute($attr)) - // un-select - || (!$node->hasAttribute($attr) && $oldAttr))) { - $event = new DOMEvent(array( - 'target' => $node->parentNode, - 'type' => 'change' - )); - } - if ($event) { - PhpQueryEvents::trigger($this->getDocumentID(), $event->type, array( - $event - ), $node); - } - } - public function attr($attr = null, $value = null) { - foreach ($this->stack(1) as $node) { - if (!is_null($value)) { - $loop = $attr == '*' ? $this->getNodeAttrs($node) - : array( - $attr - ); - foreach ($loop as $a) { - $oldValue = $node->getAttribute($a); - $oldAttr = $node->hasAttribute($a); - // TODO raises an error when charset other than UTF-8 - // while document's charset is also not UTF-8 - @$node->setAttribute($a, $value); - $this->attrEvents($a, $oldAttr, $oldValue, $node); - } - } - else if ($attr == '*') { - // jQuery difference + phpQuery::debug( + "From " . count($insertFrom) . "; To " . count($insertTo) + . " nodes" + ); + foreach ($insertTo as $insertNumber => $toNode) { + // we need static relative elements in some cases + switch ($type) { + case 'prependTo': + case 'prepend': + $firstChild = $toNode->firstChild; + break; + case 'insertAfter': + case 'after': + $nextSibling = $toNode->nextSibling; + break; + } + foreach ($insertFrom as $fromNode) { + // clone if inserted already before + $insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode; + switch ($type) { + case 'appendTo': + case 'append': + // $toNode->insertBefore( + // $fromNode, + // $toNode->lastChild->nextSibling + // ); + $toNode->appendChild($insert); + $eventTarget = $insert; + break; + case 'prependTo': + case 'prepend': + $toNode->insertBefore($insert, $firstChild); + break; + case 'insertBefore': + case 'before': + if (!$toNode->parentNode) + throw new \Exception("No parentNode, can't do {$type}()"); + else + $toNode->parentNode->insertBefore($insert, $toNode); + break; + case 'insertAfter': + case 'after': + if (!$toNode->parentNode) + throw new \Exception("No parentNode, can't do {$type}()"); + else + $toNode->parentNode->insertBefore($insert, $nextSibling); + break; + } + // Mutation event + $event = new Dom\DOMEvent(array( + 'target' => $insert, + 'type' => 'DOMNodeInserted' + )); + PhpQueryEvents::trigger( + $this->getDocumentID(), + $event->type, + array( + $event + ), + $insert + ); + } + } + return $this; + } + + /** + * Enter description here... + * + * @param $subject + * @return Int + */ + public function index($subject) + { + $index = -1; + $subject = $subject instanceof PhpQueryObject ? $subject->elements[0] + : $subject; + foreach ($this->newInstance() as $k => $node) { + if ($node->isSameNode($subject)) + $index = $k; + } + return $index; + } + + /** + * Enter description here... + * + * @param unknown_type $start + * @param unknown_type $end + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @testme + */ + public function slice($start, $end = null) + { + // $last = count($this->elements)-1; + // $end = $end + // ? min($end, $last) + // : $last; + // if ($start < 0) + // $start = $last+$start; + // if ($start > $last) + // return array(); + if ($end > 0) + $end = $end - $start; + return $this->newInstance(array_slice($this->elements, $start, $end)); + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function reverse() + { + $this->elementsBackup = $this->elements; + $this->elements = array_reverse($this->elements); + return $this->newInstance(); + } + + /** + * Return joined text content. + * @param null $text + * @param null $callback1 + * @param null $callback2 + * @param null $callback3 + * @return String + */ + public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null) + { + if (isset($text)) + return $this->html(htmlspecialchars($text)); + $args = func_get_args(); + $args = array_slice($args, 1); + $return = ''; + foreach ($this->elements as $node) { + $text = $node->textContent; + if (count($this->elements) > 1 && $text) + $text .= "\n"; + foreach ($args as $callback) { + $text = phpQuery::callbackRun( + $callback, + array( + $text + ) + ); + } + $return .= $text; + } + return $return; + } + + /** + * @param null $attr + * @return The text content of each matching element, like + * text() but returns an array with one entry per matched element. + * Read only. + */ + public function texts($attr = null) + { + $results = array(); + foreach ($this->elements as $node) { + $results[] = $node->textContent; + } + return $results; + } + + /** + * Enter description here... + * + * @param $class + * @param null $file + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function plugin($class, $file = null) + { + phpQuery::plugin($class, $file); + return $this; + } + + /** + * Deprecated, use $pq->plugin() instead. + * + * @deprecated + * @param $class + * @param $file + * @return unknown_type + */ + public static function extend($class, $file = null) + { + return self::plugin($class, $file); + } + + /** + * + * @access private + * @param $method + * @param $args + * @throws \Exception + * @return unknown_type + */ + public function __call($method, $args) + { + $aliasMethods = array( + 'clone', + 'empty' + ); + if (isset(phpQuery::$extendMethods[$method])) { + array_unshift($args, $this); + return phpQuery::callbackRun(phpQuery::$extendMethods[$method], $args); + } else if (isset(phpQuery::$pluginsMethods[$method])) { + array_unshift($args, $this); + $class = phpQuery::$pluginsMethods[$method]; + $realClass = "\\PhpQuery\\Plugin\\$class"; + $return = call_user_func_array( + array( + $realClass, + $method + ), + $args + ); + // XXX deprecate ? + return is_null($return) ? $this : $return; + } else if (in_array($method, $aliasMethods)) { + return call_user_func_array( + array( + $this, + '_' . $method + ), + $args + ); + } else + throw new \Exception("Method '{$method}' doesnt exist"); + } + + /** + * Safe rename of next(). + * + * Use it ONLY when need to call next() on an iterated object (in same time). + * Normaly there is no need to do such thing ;) + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _next($selector = null) + { + return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true)); + } + + /** + * Use prev() and next(). + * + * @deprecated + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _prev($selector = null) + { + return $this->prev($selector); + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function prev($selector = null) + { + return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true)); + } + + /** + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo + */ + public function prevAll($selector = null) + { + return $this->newInstance($this->getElementSiblings('previousSibling', $selector)); + } + + /** + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo FIXME: returns source elements insted of next siblings + */ + public function nextAll($selector = null) + { + return $this->newInstance($this->getElementSiblings('nextSibling', $selector)); + } + + /** + * @access private + */ + protected function getElementSiblings($direction, $selector = null, $limitToOne = false) + { + $stack = array(); + $count = 0; + foreach ($this->stack() as $node) { + $test = $node; + while (isset($test->{$direction}) && $test->{$direction}) { + $test = $test->{$direction}; + if (!$test instanceof \DOMElement) + continue; + $stack[] = $test; + if ($limitToOne) + break; + } + } + if ($selector) { + $stackOld = $this->elements; + $this->elements = $stack; + $stack = $this->filter($selector, true)->stack(); + $this->elements = $stackOld; + } + return $stack; + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function siblings($selector = null) + { + $stack = array(); + $siblings = array_merge( + $this->getElementSiblings('previousSibling', $selector), + $this->getElementSiblings('nextSibling', $selector) + ); + foreach ($siblings as $node) { + if (!$this->elementsContainsNode($node, $stack)) + $stack[] = $node; + } + return $this->newInstance($stack); + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function not($selector = null) + { + if (is_string($selector)) + phpQuery::debug( + array( + 'not', + $selector + ) + ); + else + phpQuery::debug('not'); + $stack = array(); + if ($selector instanceof self || $selector instanceof \DOMNODE) { + foreach ($this->stack() as $node) { + if ($selector instanceof self) { + $matchFound = false; + foreach ($selector->stack() as $notNode) { + if ($notNode->isSameNode($node)) + $matchFound = true; + } + if (!$matchFound) + $stack[] = $node; + } else if ($selector instanceof \DOMNODE) { + if (!$selector->isSameNode($node)) + $stack[] = $node; + } else { + if (!$this->is($selector)) + $stack[] = $node; + } + } + } else { + $orgStack = $this->stack(); + $matched = $this->filter($selector, true)->stack(); + // $matched = array(); + // // simulate OR in filter() instead of AND 5y + // foreach($this->parseSelector($selector) as $s) { + // $matched = array_merge($matched, + // $this->filter(array($s))->stack() + // ); + // } + foreach ($orgStack as $node) + if (!$this->elementsContainsNode($node, $matched)) + $stack[] = $node; + } + return $this->newInstance($stack); + } + + /** + * Enter description here... + * + * @param string|PhpQueryObject + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function add($selector = null) + { + if (!$selector) + return $this; + $stack = array(); + $this->elementsBackup = $this->elements; + $found = phpQuery::pq($selector, $this->getDocumentID()); + $this->merge($found->elements); + return $this->newInstance(); + } + + /** + * @access private + */ + protected function merge() + { + foreach (func_get_args() as $nodes) + foreach ($nodes as $newNode) + if (!$this->elementsContainsNode($newNode)) + $this->elements[] = $newNode; + } + + /** + * @access private + * TODO refactor to stackContainsNode + */ + protected function elementsContainsNode($nodeToCheck, $elementsStack = null) + { + $loop = !is_null($elementsStack) ? $elementsStack : $this->elements; + foreach ($loop as $node) { + if ($node->isSameNode($nodeToCheck)) + return true; + } + return false; + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function parent($selector = null) + { + $stack = array(); + foreach ($this->elements as $node) + if ($node->parentNode + && !$this->elementsContainsNode($node->parentNode, $stack) + ) + $stack[] = $node->parentNode; + $this->elementsBackup = $this->elements; + $this->elements = $stack; + if ($selector) + $this->filter($selector, true); + return $this->newInstance(); + } + + /** + * Enter description here... + * + * @param null $selector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function parents($selector = null) + { + $stack = array(); + if (!$this->elements) + $this->debug('parents() - stack empty'); + foreach ($this->elements as $node) { + $test = $node; + while ($test->parentNode) { + $test = $test->parentNode; + if ($this->isRoot($test)) + break; + if (!$this->elementsContainsNode($test, $stack)) { + $stack[] = $test; + continue; + } + } + } + $this->elementsBackup = $this->elements; + $this->elements = $stack; + if ($selector) + $this->filter($selector, true); + return $this->newInstance(); + } + + /** + * Internal stack iterator. + * + * @access private + * @param null $nodeTypes + * @return array {Array.} + */ + public function stack($nodeTypes = null) + { + if (!isset($nodeTypes)) + return $this->elements; + if (!is_array($nodeTypes)) + $nodeTypes = array( + $nodeTypes + ); $return = array(); - foreach ($node->attributes as $n => $v) - $return[$n] = $v->value; + foreach ($this->elements as $node) { + if (in_array($node->nodeType, $nodeTypes)) + $return[] = $node; + } return $return; - } - else - return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null; - } - return is_null($value) ? '' : $this; - } - - /** - * @return The same attribute of each matching element, like - * attr() but returns an array with one entry per matched element. - * Read only. - */ - public function attrs($attr = null) { - $results = array(); - foreach ($this->stack(1) as $node) { - $results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr) - : null; - } - return $results; - } - - /** - * @access private - */ - protected function getNodeAttrs($node) { - $return = array(); - foreach ($node->attributes as $n => $o) - $return[] = $n; - return $return; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo check CDATA ??? - */ - public function attrPHP($attr, $code) { - if (!is_null($code)) { - $value = '<' . '?php ' . $code . ' ?' . '>'; - // TODO tempolary solution - // http://code.google.com/p/phpquery/issues/detail?id=17 - // if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII') - // $value = mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES'); - } - foreach ($this->stack(1) as $node) { - if (!is_null($code)) { - // $attrNode = $this->DOM->createAttribute($attr); - $node->setAttribute($attr, $value); - // $attrNode->value = $value; - // $node->appendChild($attrNode); - } - else if ($attr == '*') { - // jQuery diff + } + + // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes + protected function attrEvents($attr, $oldAttr, $oldValue, $node) + { + // skip events for XML documents + if (!$this->isXHTML() && !$this->isHTML()) + return; + $event = null; + // identify + $isInputValue = $node->tagName == 'input' + && (in_array( + $node->getAttribute('type'), + array( + 'text', + 'password', + 'hidden' + ) + ) || !$node->getAttribute('type')); + $isRadio = $node->tagName == 'input' + && $node->getAttribute('type') == 'radio'; + $isCheckbox = $node->tagName == 'input' + && $node->getAttribute('type') == 'checkbox'; + $isOption = $node->tagName == 'option'; + if ($isInputValue && $attr == 'value' + && $oldValue != $node->getAttribute($attr) + ) { + $event = new Dom\DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + } else if (($isRadio || $isCheckbox) && $attr == 'checked' + && ( + // check + (!$oldAttr && $node->hasAttribute($attr)) + // un-check + || (!$node->hasAttribute($attr) && $oldAttr)) + ) { + $event = new Dom\DOMEvent(array( + 'target' => $node, + 'type' => 'change' + )); + } else if ($isOption && $node->parentNode && $attr == 'selected' + && ( + // select + (!$oldAttr && $node->hasAttribute($attr)) + // un-select + || (!$node->hasAttribute($attr) && $oldAttr)) + ) { + $event = new Dom\DOMEvent(array( + 'target' => $node->parentNode, + 'type' => 'change' + )); + } + if ($event) { + PhpQueryEvents::trigger( + $this->getDocumentID(), + $event->type, + array( + $event + ), + $node + ); + } + } + + public function attr($attr = null, $value = null) + { + foreach ($this->stack(1) as $node) { + if (!is_null($value)) { + $loop = $attr == '*' ? $this->getNodeAttrs($node) + : array( + $attr + ); + foreach ($loop as $a) { + $oldValue = $node->getAttribute($a); + $oldAttr = $node->hasAttribute($a); + // TODO raises an error when charset other than UTF-8 + // while document's charset is also not UTF-8 + @$node->setAttribute($a, $value); + $this->attrEvents($a, $oldAttr, $oldValue, $node); + } + } else if ($attr == '*') { + // jQuery difference + $return = array(); + foreach ($node->attributes as $n => $v) + $return[$n] = $v->value; + return $return; + } else + return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null; + } + return is_null($value) ? '' : $this; + } + + /** + * @param null $attr + * @return The same attribute of each matching element, like + * attr() but returns an array with one entry per matched element. + * Read only. + */ + public function attrs($attr = null) + { + $results = array(); + foreach ($this->stack(1) as $node) { + $results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr) + : null; + } + return $results; + } + + /** + * @access private + */ + protected function getNodeAttrs($node) + { $return = array(); - foreach ($node->attributes as $n => $v) - $return[$n] = $v->value; + foreach ($node->attributes as $n => $o) + $return[] = $n; return $return; - } - else - return $node->getAttribute($attr); - } - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function removeAttr($attr) { - foreach ($this->stack(1) as $node) { - $loop = $attr == '*' ? $this->getNodeAttrs($node) - : array( - $attr - ); - foreach ($loop as $a) { - $oldValue = $node->getAttribute($a); - $node->removeAttribute($a); - $this->attrEvents($a, $oldValue, null, $node); - } - } - return $this; - } - /** - * Return form element value. - * - * @return String Fields value. - */ - public function val($val = null) { - if (!isset($val)) { - if ($this->eq(0)->is('select')) { - $selected = $this->eq(0)->find('option[selected=selected]'); - if ($selected->is('[value]')) - return $selected->attr('value'); - else - return $selected->text(); - } - else if ($this->eq(0)->is('textarea')) - return $this->eq(0)->markup(); - else - return $this->eq(0)->attr('value'); - } - else { - $_val = null; - foreach ($this->stack(1) as $node) { - $node = pq($node, $this->getDocumentID()); - if (is_array($val) - && in_array($node->attr('type'), array( - 'checkbox', - 'radio' - ))) { - $isChecked = in_array($node->attr('value'), $val) - || in_array($node->attr('name'), $val); - if ($isChecked) - $node->attr('checked', 'checked'); - else - $node->removeAttr('checked'); - } - else if ($node->get(0)->tagName == 'select') { - if (!isset($_val)) { - $_val = array(); - if (!is_array($val)) - $_val = array( - (string) $val - ); + } + + /** + * Enter description here... + * + * @param $attr + * @param $code + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo check CDATA ??? + */ + public function attrPHP($attr, $code) + { + if (!is_null($code)) { + $value = '<' . '?php ' . $code . ' ?' . '>'; + // TODO tempolary solution + // http://code.google.com/p/phpquery/issues/detail?id=17 + // if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII') + // $value = mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES'); + } + foreach ($this->stack(1) as $node) { + if (!is_null($code)) { + // $attrNode = $this->DOM->createAttribute($attr); + $node->setAttribute($attr, $value); + // $attrNode->value = $value; + // $node->appendChild($attrNode); + } else if ($attr == '*') { + // jQuery diff + $return = array(); + foreach ($node->attributes as $n => $v) + $return[$n] = $v->value; + return $return; + } else + return $node->getAttribute($attr); + } + return $this; + } + + /** + * Enter description here... + * + * @param $attr + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function removeAttr($attr) + { + foreach ($this->stack(1) as $node) { + $loop = $attr == '*' ? $this->getNodeAttrs($node) + : array( + $attr + ); + foreach ($loop as $a) { + $oldValue = $node->getAttribute($a); + $node->removeAttribute($a); + $this->attrEvents($a, $oldValue, null, $node); + } + } + return $this; + } + + /** + * Return form element value. + * + * @param null $val + * @return String Fields value. + */ + public function val($val = null) + { + if (!isset($val)) { + if ($this->eq(0)->is('select')) { + $selected = $this->eq(0)->find('option[selected=selected]'); + if ($selected->is('[value]')) + return $selected->attr('value'); + else + return $selected->text(); + } else if ($this->eq(0)->is('textarea')) + return $this->eq(0)->markup(); else - foreach ($val as $v) - $_val[] = $v; - } - foreach ($node['option']->stack(1) as $option) { - $option = pq($option, $this->getDocumentID()); - $selected = false; - // XXX: workaround for string comparsion, see issue #96 - // http://code.google.com/p/phpquery/issues/detail?id=96 - $selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val) - : in_array($option->attr('value'), $_val); - // $optionValue = $option->attr('value'); - // $optionText = $option->text(); - // $optionTextLenght = mb_strlen($optionText); - // foreach($_val as $v) - // if ($optionValue == $v) - // $selected = true; - // else if ($optionText == $v && $optionTextLenght == mb_strlen($v)) - // $selected = true; - if ($selected) - $option->attr('selected', 'selected'); + return $this->eq(0)->attr('value'); + } else { + $_val = null; + foreach ($this->stack(1) as $node) { + $node = pq($node, $this->getDocumentID()); + if (is_array($val) + && in_array( + $node->attr('type'), + array( + 'checkbox', + 'radio' + ) + ) + ) { + $isChecked = in_array($node->attr('value'), $val) + || in_array($node->attr('name'), $val); + if ($isChecked) + $node->attr('checked', 'checked'); + else + $node->removeAttr('checked'); + } else if ($node->get(0)->tagName == 'select') { + if (!isset($_val)) { + $_val = array(); + if (!is_array($val)) + $_val = array( + (string) $val + ); + else + foreach ($val as $v) + $_val[] = $v; + } + foreach ($node['option']->stack(1) as $option) { + $option = pq($option, $this->getDocumentID()); + $selected = false; + // XXX: workaround for string comparsion, see issue #96 + // http://code.google.com/p/phpquery/issues/detail?id=96 + $selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val) + : in_array($option->attr('value'), $_val); + // $optionValue = $option->attr('value'); + // $optionText = $option->text(); + // $optionTextLenght = mb_strlen($optionText); + // foreach($_val as $v) + // if ($optionValue == $v) + // $selected = true; + // else if ($optionText == $v && $optionTextLenght == mb_strlen($v)) + // $selected = true; + if ($selected) + $option->attr('selected', 'selected'); + else + $option->removeAttr('selected'); + } + } else if ($node->get(0)->tagName == 'textarea') + $node->markup($val); + else + $node->attr('value', $val); + } + } + return $this; + } + + /** + * Enter description here... + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function andSelf() + { + if ($this->previous) + $this->elements = array_merge($this->elements, $this->previous->elements); + return $this; + } + + /** + * Enter description here... + * + * @param $className + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function addClass($className) + { + if (!$className) + return $this; + foreach ($this->stack(1) as $node) { + if (!$this->is(".$className", $node)) + $node->setAttribute( + 'class', + trim( + $node->getAttribute('class') . ' ' + . $className + ) + ); + } + return $this; + } + + /** + * Enter description here... + * + * @param $className + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function addClassPHP($className) + { + foreach ($this->stack(1) as $node) { + $classes = $node->getAttribute('class'); + $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?' + . '>' : '<' . '?php ' . $className . ' ?' . '>'; + $node->setAttribute('class', $newValue); + } + return $this; + } + + /** + * Enter description here... + * + * @param string $className + * @return bool + */ + public function hasClass($className) + { + foreach ($this->stack(1) as $node) { + if ($this->is(".$className", $node)) + return true; + } + return false; + } + + /** + * Enter description here... + * + * @param $className + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function removeClass($className) + { + foreach ($this->stack(1) as $node) { + $classes = explode(' ', $node->getAttribute('class')); + if (in_array($className, $classes)) { + $classes = array_diff( + $classes, + array( + $className + ) + ); + if ($classes) + $node->setAttribute('class', implode(' ', $classes)); + else + $node->removeAttribute('class'); + } + } + return $this; + } + + /** + * Enter description here... + * + * @param $className + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function toggleClass($className) + { + foreach ($this->stack(1) as $node) { + if ($this->is($node, '.' . $className)) + $this->removeClass($className); else - $option->removeAttr('selected'); - } + $this->addClass($className); } - else if ($node->get(0)->tagName == 'textarea') - $node->markup($val); - else - $node->attr('value', $val); - } - } - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function andSelf() { - if ($this->previous) - $this->elements = array_merge($this->elements, $this->previous->elements); - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function addClass($className) { - if (!$className) - return $this; - foreach ($this->stack(1) as $node) { - if (!$this->is(".$className", $node)) - $node->setAttribute('class', trim($node->getAttribute('class') . ' ' - . $className)); - } - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function addClassPHP($className) { - foreach ($this->stack(1) as $node) { - $classes = $node->getAttribute('class'); - $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?' - . '>' : '<' . '?php ' . $className . ' ?' . '>'; - $node->setAttribute('class', $newValue); - } - return $this; - } - /** - * Enter description here... - * - * @param string $className - * @return bool - */ - public function hasClass($className) { - foreach ($this->stack(1) as $node) { - if ($this->is(".$className", $node)) - return true; - } - return false; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function removeClass($className) { - foreach ($this->stack(1) as $node) { - $classes = explode(' ', $node->getAttribute('class')); - if (in_array($className, $classes)) { - $classes = array_diff($classes, array( - $className - )); - if ($classes) - $node->setAttribute('class', implode(' ', $classes)); - else - $node->removeAttribute('class'); - } - } - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function toggleClass($className) { - foreach ($this->stack(1) as $node) { - if ($this->is($node, '.' . $className)) - $this->removeClass($className); - else - $this->addClass($className); - } - return $this; - } - /** - * Proper name without underscore (just ->empty()) also works. - * - * Removes all child nodes from the set of matched elements. - * - * Example: - * pq("p")._empty() - * - * HTML: - *

    Hello, Person and person

    - * - * Result: - * [

    ] - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @access private - */ - public function _empty() { - foreach ($this->stack(1) as $node) { - // thx to 'dave at dgx dot cz' - $node->nodeValue = ''; - } - return $this; - } - /** - * Enter description here... - * - * @param array|string $callback Expects $node as first param, $index as second - * @param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope) - * @param array $arg1 Will ba passed as third and futher args to callback. - * @param array $arg2 Will ba passed as fourth and futher args to callback, and so on... - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function each($callback, $param1 = null, $param2 = null, $param3 = null) { - $paramStructure = null; - if (func_num_args() > 1) { - $paramStructure = func_get_args(); - $paramStructure = array_slice($paramStructure, 1); - } - foreach ($this->elements as $v) - phpQuery::callbackRun($callback, array( - $v - ), $paramStructure); - return $this; - } - /** - * Run callback on actual object. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function callback($callback, $param1 = null, $param2 = null, $param3 = null) { - $params = func_get_args(); - $params[0] = $this; - phpQuery::callbackRun($callback, $params); - return $this; - } - /** - * Enter description here... - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * @todo add $scope and $args as in each() ??? - */ - public function map($callback, $param1 = null, $param2 = null, $param3 = null) { - // $stack = array(); - //// foreach($this->newInstance() as $node) { - // foreach($this->newInstance() as $node) { - // $result = call_user_func($callback, $node); - // if ($result) - // $stack[] = $result; - // } - $params = func_get_args(); - array_unshift($params, $this->elements); - return $this->newInstance(call_user_func_array(array( - 'phpQuery', - 'map' - ), $params) - // phpQuery::map($this->elements, $callback) - ); - } - /** - * Enter description here... - * - * @param $key - * @param $value - */ - public function data($key, $value = null) { - if (!isset($value)) { - // TODO? implement specific jQuery behavior od returning parent values - // is child which we look up doesn't exist - return phpQuery::data($this->get(0), $key, $value, $this->getDocumentID()); - } - else { - foreach ($this as $node) - phpQuery::data($node, $key, $value, $this->getDocumentID()); - return $this; - } - } - /** - * Enter description here... - * - * @param $key - */ - public function removeData($key) { - foreach ($this as $node) - phpQuery::removeData($node, $key, $this->getDocumentID()); - return $this; - } - // INTERFACE IMPLEMENTATIONS - - // ITERATOR INTERFACE - /** - * @access private - */ - public function rewind() { - $this->debug('iterating foreach'); - // phpQuery::selectDocument($this->getDocumentID()); - $this->elementsBackup = $this->elements; - $this->elementsInterator = $this->elements; - $this->valid = isset($this->elements[0]) ? 1 : 0; - // $this->elements = $this->valid - // ? array($this->elements[0]) - // : array(); - $this->current = 0; - } - /** - * @access private - */ - public function current() { - return $this->elementsInterator[$this->current]; - } - /** - * @access private - */ - public function key() { - return $this->current; - } - /** - * Double-function method. - * - * First: main iterator interface method. - * Second: Returning next sibling, alias for _next(). - * - * Proper functionality is choosed automagicaly. - * - * @see PhpQueryObject::_next() - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - */ - public function next($cssSelector = null) { - // if ($cssSelector || $this->valid) - // return $this->_next($cssSelector); - $this->valid = isset($this->elementsInterator[$this->current + 1]) ? true - : false; - if (!$this->valid && $this->elementsInterator) { - $this->elementsInterator = null; - } - else if ($this->valid) { - $this->current++; - } - else { - return $this->_next($cssSelector); - } - } - /** - * @access private - */ - public function valid() { - return $this->valid; - } - // ITERATOR INTERFACE END - // ARRAYACCESS INTERFACE - /** - * @access private - */ - public function offsetExists($offset) { - return $this->find($offset)->size() > 0; - } - /** - * @access private - */ - public function offsetGet($offset) { - return $this->find($offset); - } - /** - * @access private - */ - public function offsetSet($offset, $value) { - // $this->find($offset)->replaceWith($value); - $this->find($offset)->html($value); - } - /** - * @access private - */ - public function offsetUnset($offset) { - // empty - throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); - } - // ARRAYACCESS INTERFACE END - /** - * Returns node's XPath. - * - * @param unknown_type $oneNode - * @return string - * @TODO use native getNodePath is avaible - * @access private - */ - protected function getNodeXpath($oneNode = null, $namespace = null) { - $return = array(); - $loop = $oneNode ? array( - $oneNode - ) : $this->elements; - // if ($namespace) - // $namespace .= ':'; - foreach ($loop as $node) { - if ($node instanceof \DOMDocument) { - $return[] = ''; - continue; - } - $xpath = array(); - while (!($node instanceof \DOMDocument)) { - $i = 1; - $sibling = $node; - while ($sibling->previousSibling) { - $sibling = $sibling->previousSibling; - $isElement = $sibling instanceof \DOMElement; - if ($isElement && $sibling->tagName == $node->tagName) - $i++; - } - $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]" - : "{$node->tagName}[{$i}]"; - $node = $node->parentNode; - } - $xpath = join('/', array_reverse($xpath)); - $return[] = '/' . $xpath; - } - return $oneNode ? $return[0] : $return; - } - // HELPERS - public function whois($oneNode = null) { - $return = array(); - $loop = $oneNode ? array( - $oneNode - ) : $this->elements; - foreach ($loop as $node) { - if (isset($node->tagName)) { - $tag = in_array($node->tagName, array( - 'php', - 'js' - )) ? strtoupper($node->tagName) : $node->tagName; - $return[] = $tag - . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '') - . ($node->getAttribute('class') ? '.' - . join('.', explode(' ', $node->getAttribute('class'))) : '') - . ($node->getAttribute('name') ? '[name="' - . $node->getAttribute('name') . '"]' : '') - . ($node->getAttribute('value') - && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="' - . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15) - . '"]' : '') - . ($node->getAttribute('value') - && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]' - : '') . ($node->getAttribute('selected') ? '[selected]' : '') - . ($node->getAttribute('checked') ? '[checked]' : ''); - } - else if ($node instanceof DOMTEXT) { - if (trim($node->textContent)) - $return[] = 'Text:' - . substr(str_replace("\n", ' ', $node->textContent), 0, 15); - } - else { - - } - } - return $oneNode && isset($return[0]) ? $return[0] : $return; - } - /** - * Dump htmlOuter and preserve chain. Usefull for debugging. - * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery - * - */ - public function dump() { - print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; - // print __FILE__.':'.__LINE__."\n"; - var_dump($this->htmlOuter()); - return $this; - } - public function dumpWhois() { - print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; - // print __FILE__.':'.__LINE__."\n"; - var_dump('whois', $this->whois()); - phpQuery::$debug = $debug; - return $this; - } - public function dumpLength() { - print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; - $debug = phpQuery::$debug; - phpQuery::$debug = false; - // print __FILE__.':'.__LINE__."\n"; - var_dump('length', $this->length()); - phpQuery::$debug = $debug; - return $this; - } - public function dumpTree($html = true, $title = true) { - $output = $title ? 'DUMP #' . (phpQuery::$dumpCount++) . " \n" : ''; - $debug = phpQuery::$debug; - phpQuery::$debug = false; - foreach ($this->stack() as $node) - $output .= $this->__dumpTree($node); - phpQuery::$debug = $debug; - print $html ? nl2br(str_replace(' ', ' ', $output)) : $output; - return $this; - } - private function __dumpTree($node, $intend = 0) { - $whois = $this->whois($node); - $return = ''; - if ($whois) - $return .= str_repeat(' - ', $intend) . $whois . "\n"; - if (isset($node->childNodes)) - foreach ($node->childNodes as $chNode) - $return .= $this->__dumpTree($chNode, $intend + 1); - return $return; - } - /** - * Dump htmlOuter and stop script execution. Usefull for debugging. - * - */ - public function dumpDie() { - print __FILE__ . ':' . __LINE__; - var_dump($this->htmlOuter()); - die(); - } + return $this; + } + + /** + * Proper name without underscore (just ->empty()) also works. + * + * Removes all child nodes from the set of matched elements. + * + * Example: + * pq("p")._empty() + * + * HTML: + *

    Hello, Person and person

    + * + * Result: + * [

    ] + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @access private + */ + public function _empty() + { + foreach ($this->stack(1) as $node) { + // thx to 'dave at dgx dot cz' + $node->nodeValue = ''; + } + return $this; + } + + /** + * Enter description here... + * + * @param array|string $callback Expects $node as first param, $index as second + * @param null $param1 + * @param null $param2 + * @param null $param3 + * @internal param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope) + * @internal param array $arg1 Will ba passed as third and futher args to callback. + * @internal param array $arg2 Will ba passed as fourth and futher args to callback, and so on... + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function each($callback, $param1 = null, $param2 = null, $param3 = null) + { + $paramStructure = null; + if (func_num_args() > 1) { + $paramStructure = func_get_args(); + $paramStructure = array_slice($paramStructure, 1); + } + foreach ($this->elements as $v) + phpQuery::callbackRun( + $callback, + array( + $v + ), + $paramStructure + ); + return $this; + } + + /** + * Run callback on actual object. + * + * @param $callback + * @param null $param1 + * @param null $param2 + * @param null $param3 + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function callback($callback, $param1 = null, $param2 = null, $param3 = null) + { + $params = func_get_args(); + $params[0] = $this; + phpQuery::callbackRun($callback, $params); + return $this; + } + + /** + * Enter description here... + * + * @param $callback + * @param null $param1 + * @param null $param2 + * @param null $param3 + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @todo add $scope and $args as in each() ??? + */ + public function map($callback, $param1 = null, $param2 = null, $param3 = null) + { + // $stack = array(); + //// foreach($this->newInstance() as $node) { + // foreach($this->newInstance() as $node) { + // $result = call_user_func($callback, $node); + // if ($result) + // $stack[] = $result; + // } + $params = func_get_args(); + array_unshift($params, $this->elements); + return $this->newInstance( + call_user_func_array( + array( + 'phpQuery', + 'map' + ), + $params + ) + // phpQuery::map($this->elements, $callback) + ); + } + + /** + * Enter description here... + * + * @param $key + * @param $value + * @return $this + */ + public function data($key, $value = null) + { + if (!isset($value)) { + // TODO? implement specific jQuery behavior od returning parent values + // is child which we look up doesn't exist + return phpQuery::data($this->get(0), $key, $value, $this->getDocumentID()); + } else { + foreach ($this as $node) + phpQuery::data($node, $key, $value, $this->getDocumentID()); + return $this; + } + } + + /** + * Enter description here... + * + * @param $key + * @return $this + */ + public function removeData($key) + { + foreach ($this as $node) + phpQuery::removeData($node, $key, $this->getDocumentID()); + return $this; + } + // INTERFACE IMPLEMENTATIONS + + // ITERATOR INTERFACE + /** + * @access private + */ + public function rewind() + { + $this->debug('iterating foreach'); + // phpQuery::selectDocument($this->getDocumentID()); + $this->elementsBackup = $this->elements; + $this->elementsInterator = $this->elements; + $this->valid = isset($this->elements[0]) ? 1 : 0; + // $this->elements = $this->valid + // ? array($this->elements[0]) + // : array(); + $this->current = 0; + } + + /** + * @access private + */ + public function current() + { + return $this->elementsInterator[$this->current]; + } + + /** + * @access private + */ + public function key() + { + return $this->current; + } + + /** + * Double-function method. + * + * First: main iterator interface method. + * Second: Returning next sibling, alias for _next(). + * + * Proper functionality is choosed automagicaly. + * + * @see PhpQueryObject::_next() + * @param null $cssSelector + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + */ + public function next($cssSelector = null) + { + // if ($cssSelector || $this->valid) + // return $this->_next($cssSelector); + $this->valid = isset($this->elementsInterator[$this->current + 1]) ? true + : false; + if (!$this->valid && $this->elementsInterator) { + $this->elementsInterator = null; + } else if ($this->valid) { + $this->current++; + } else { + return $this->_next($cssSelector); + } + } + + /** + * @access private + */ + public function valid() + { + return $this->valid; + } + // ITERATOR INTERFACE END + // ARRAYACCESS INTERFACE + /** + * @access private + */ + public function offsetExists($offset) + { + return $this->find($offset)->size() > 0; + } + + /** + * @access private + */ + public function offsetGet($offset) + { + return $this->find($offset); + } + + /** + * @access private + */ + public function offsetSet($offset, $value) + { + // $this->find($offset)->replaceWith($value); + $this->find($offset)->html($value); + } + + /** + * @access private + */ + public function offsetUnset($offset) + { + // empty + throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML."); + } + // ARRAYACCESS INTERFACE END + /** + * Returns node's XPath. + * + * @param unknown_type $oneNode + * @param null $namespace + * @return string + * @TODO use native getNodePath is avaible + * @access private + */ + protected function getNodeXpath($oneNode = null, $namespace = null) + { + $return = array(); + $loop = $oneNode ? array( + $oneNode + ) : $this->elements; + // if ($namespace) + // $namespace .= ':'; + foreach ($loop as $node) { + if ($node instanceof \DOMDocument) { + $return[] = ''; + continue; + } + $xpath = array(); + while (!($node instanceof \DOMDocument)) { + $i = 1; + $sibling = $node; + while ($sibling->previousSibling) { + $sibling = $sibling->previousSibling; + $isElement = $sibling instanceof \DOMElement; + if ($isElement && $sibling->tagName == $node->tagName) + $i++; + } + $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]" + : "{$node->tagName}[{$i}]"; + $node = $node->parentNode; + } + $xpath = join('/', array_reverse($xpath)); + $return[] = '/' . $xpath; + } + return $oneNode ? $return[0] : $return; + } + + // HELPERS + public function whois($oneNode = null) + { + $return = array(); + $loop = $oneNode ? array( + $oneNode + ) : $this->elements; + foreach ($loop as $node) { + if (isset($node->tagName)) { + $tag = in_array( + $node->tagName, + array( + 'php', + 'js' + ) + ) ? strtoupper($node->tagName) : $node->tagName; + $return[] = $tag + . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '') + . ($node->getAttribute('class') ? '.' + . join('.', explode(' ', $node->getAttribute('class'))) : '') + . ($node->getAttribute('name') ? '[name="' + . $node->getAttribute('name') . '"]' : '') + . ($node->getAttribute('value') + && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="' + . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15) + . '"]' : '') + . ($node->getAttribute('value') + && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]' + : '') . ($node->getAttribute('selected') ? '[selected]' : '') + . ($node->getAttribute('checked') ? '[checked]' : ''); + } else if ($node instanceof \DOMTEXT) { + if (trim($node->textContent)) + $return[] = 'Text:' + . substr(str_replace("\n", ' ', $node->textContent), 0, 15); + } else { + + } + } + return $oneNode && isset($return[0]) ? $return[0] : $return; + } + + /** + * Dump htmlOuter and preserve chain. Usefull for debugging. + * + * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * + */ + public function dump() + { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump($this->htmlOuter()); + return $this; + } + + public function dumpWhois() + { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump('whois', $this->whois()); + phpQuery::$debug = $debug; + return $this; + } + + public function dumpLength() + { + print 'DUMP #' . (phpQuery::$dumpCount++) . ' '; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + // print __FILE__.':'.__LINE__."\n"; + var_dump('length', $this->length()); + phpQuery::$debug = $debug; + return $this; + } + + public function dumpTree($html = true, $title = true) + { + $output = $title ? 'DUMP #' . (phpQuery::$dumpCount++) . " \n" : ''; + $debug = phpQuery::$debug; + phpQuery::$debug = false; + foreach ($this->stack() as $node) + $output .= $this->__dumpTree($node); + phpQuery::$debug = $debug; + print $html ? nl2br(str_replace(' ', ' ', $output)) : $output; + return $this; + } + + private function __dumpTree($node, $intend = 0) + { + $whois = $this->whois($node); + $return = ''; + if ($whois) + $return .= str_repeat(' - ', $intend) . $whois . "\n"; + if (isset($node->childNodes)) + foreach ($node->childNodes as $chNode) + $return .= $this->__dumpTree($chNode, $intend + 1); + return $return; + } + + /** + * Dump htmlOuter and stop script execution. Usefull for debugging. + * + */ + public function dumpDie() + { + print __FILE__ . ':' . __LINE__; + var_dump($this->htmlOuter()); + die(); + } } diff --git a/src/Plugin/Scripts.php b/src/Plugin/Scripts.php index b2ded0a..2aaeb07 100644 --- a/src/Plugin/Scripts.php +++ b/src/Plugin/Scripts.php @@ -1,11 +1,14 @@ \ No newline at end of file +} \ No newline at end of file diff --git a/src/Plugin/Scripts/__config.example.php b/src/Plugin/Scripts/__config.example.php index db80652..8265299 100644 --- a/src/Plugin/Scripts/__config.example.php +++ b/src/Plugin/Scripts/__config.example.php @@ -6,5 +6,4 @@ */ $config = array( 'google_login' => array('login@mail', 'password'), -); -?> \ No newline at end of file +); \ No newline at end of file diff --git a/src/Plugin/Scripts/example.php b/src/Plugin/Scripts/example.php index a8f45f4..ebf82ab 100644 --- a/src/Plugin/Scripts/example.php +++ b/src/Plugin/Scripts/example.php @@ -10,5 +10,4 @@ * * By default each script returns $self aka $this. */ -$return = $self->find($params[0]); -?> \ No newline at end of file +$return = $self->find($params[0]); \ No newline at end of file diff --git a/src/Plugin/Scripts/google_login.php b/src/Plugin/Scripts/google_login.php index 0327045..a5287d0 100644 --- a/src/Plugin/Scripts/google_login.php +++ b/src/Plugin/Scripts/google_login.php @@ -6,6 +6,8 @@ * @package phpQuery.Plugins.Scripts * @author Tobiasz Cudnik */ +use PhpQuery\PhpQuery as phpQuery; + phpQuery::ajaxAllowHost( 'code.google.com', 'google.com', 'www.google.com', @@ -43,5 +45,4 @@ function ndfasui8923($browser, $scope) { // ->val('".str_replace("'", "\\'", $config['google_login'][1])."') // ->parents('form') // ->submit();" -//)); -?> \ No newline at end of file +//)); \ No newline at end of file diff --git a/src/Plugin/WebBrowser.php b/src/Plugin/WebBrowser.php index e225161..1289714 100644 --- a/src/Plugin/WebBrowser.php +++ b/src/Plugin/WebBrowser.php @@ -1,21 +1,28 @@ _clone()->toRoot(); $location = $location @@ -58,13 +65,14 @@ public static function downloadTo($self, $dir = null, $filename = null) { } return $self; } - /** - * Method changing browser location. - * Fires callback registered with WebBrowser(), if any. - * @param $self - * @param $url - * @return unknown_type - */ + + /** + * Method changing browser location. + * Fires callback registered with WebBrowser(), if any. + * @param $self + * @param $url + * @return bool + */ public static function location($self, $url = null) { // TODO if ! $url return actual location ??? $xhr = isset($self->document->xhr) @@ -105,16 +113,17 @@ public static function download($self, $url = null) { return $return; } } -class \PhpQuery\Plugin\UtilWebBrowser { - /** - * - * @param $url - * @param $callback - * @param $param1 - * @param $param2 - * @param $param3 - * @return Zend_Http_Client - */ +class UtilWebBrowser { + /** + * + * @param $url + * @param $callback + * @param $param1 + * @param $param2 + * @param $param3 + * @throws \Exception + * @return \Zend_Http_Client + */ public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) { phpQuery::debug("[WebBrowser] GET: $url"); @@ -140,7 +149,6 @@ public static function browserGet($url, $callback, return $xhr; } else { throw new \Exception("[WebBrowser] GET request failed; url: $url"); - return false; } } /** @@ -151,7 +159,7 @@ public static function browserGet($url, $callback, * @param $param1 * @param $param2 * @param $param3 - * @return Zend_Http_Client + * @return \Zend_Http_Client */ public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) { @@ -222,7 +230,7 @@ protected static function ajaxSettingsPrepare($settings) { return $settings; } /** - * @param Zend_Http_Client $xhr + * @param \Zend_Http_Client $xhr */ public static function browserReceive($xhr) { phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true)); @@ -277,13 +285,12 @@ public static function browserDownload($xhr) { return $body; } - /** - * - * @param $e - * @param $callback - * @return unknown_type - */ - public static function hadleClick($e, $callback = null) { + + /** + * @param $e + * @param null $callback + */ + public static function hadleClick($e, $callback = null) { $node = phpQuery::pq($e->target); $type = null; if ($node->is('a[href]')) { @@ -295,7 +302,7 @@ public static function hadleClick($e, $callback = null) { 'url' => resolve_url($e->data[0], $node->attr('href')), 'referer' => $node->document->location, ), $xhr); - if ((! $callback || !($callback instanceof Callback)) && $e->data[1]) + if ((! $callback || !($callback instanceof \Callback)) && $e->data[1]) $callback = $e->data[1]; if ($xhr->getLastResponse()->isSuccessful() && $callback) phpQuery::callbackRun($callback, array( @@ -304,12 +311,14 @@ public static function hadleClick($e, $callback = null) { } else if ($node->is(':submit') && $node->parents('form')->size()) $node->parents('form')->trigger('submit', array($e)); } - /** - * Enter description here... - * - * @param unknown_type $e - * @TODO trigger submit for form after form's submit button has a click event - */ + + /** + * Enter description here... + * + * @TODO trigger submit for form after form's submit button has a click event + * @param $e + * @param null $callback + */ public static function handleSubmit($e, $callback = null) { $node = phpQuery::pq($e->target); if (!$node->is('form') || !$node->is('[action]')) @@ -350,8 +359,6 @@ public static function handleSubmit($e, $callback = null) { } /** * - * @param unknown_type $parsed - * @return unknown * @link http://www.php.net/manual/en/function.parse-url.php * @author stevenlewis at hotmail dot com */ @@ -373,9 +380,6 @@ function glue_url($parsed) /** * Enter description here... * - * @param unknown_type $base - * @param unknown_type $url - * @return unknown * @author adrian-php at sixfingeredman dot net */ function resolve_url($base, $url) { @@ -434,3 +438,16 @@ function resolve_url($base, $url) { // Step 7 return glue_url($base); } + +function unparse_url($parsed_url) { + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; + $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; + $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; + $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + return "$scheme$user$pass$host$port$path$query$fragment"; +} \ No newline at end of file diff --git a/src/bootstrap.php b/src/bootstrap.php index afd5d4f..b03998d 100644 --- a/src/bootstrap.php +++ b/src/bootstrap.php @@ -8,9 +8,10 @@ * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding($enc) { - return true; - } + function mb_internal_encoding($enc) + { + return true; + } } /** @@ -19,9 +20,10 @@ function mb_internal_encoding($enc) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_regex_encoding')) { - function mb_regex_encoding($enc) { - return true; - } + function mb_regex_encoding($enc) + { + return true; + } } /** @@ -30,9 +32,10 @@ function mb_regex_encoding($enc) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_strlen')) { - function mb_strlen($str) { - return strlen($str); - } + function mb_strlen($str) + { + return strlen($str); + } } /** @@ -41,9 +44,10 @@ function mb_strlen($str) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_strpos')) { - function mb_strpos($haystack, $needle, $offset = 0) { - return strpos($haystack, $needle, $offset); - } + function mb_strpos($haystack, $needle, $offset = 0) + { + return strpos($haystack, $needle, $offset); + } } /** * mb_stripos() @@ -51,9 +55,10 @@ function mb_strpos($haystack, $needle, $offset = 0) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_stripos')) { - function mb_stripos($haystack, $needle, $offset = 0) { - return stripos($haystack, $needle, $offset); - } + function mb_stripos($haystack, $needle, $offset = 0) + { + return stripos($haystack, $needle, $offset); + } } /** @@ -62,9 +67,10 @@ function mb_stripos($haystack, $needle, $offset = 0) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_substr')) { - function mb_substr($str, $start, $length = 0) { - return substr($str, $start, $length); - } + function mb_substr($str, $start, $length = 0) + { + return substr($str, $start, $length); + } } /** @@ -73,7 +79,8 @@ function mb_substr($str, $start, $length = 0) { * Included for mbstring pseudo-compatability. */ if (!function_exists('mb_substr_count')) { - function mb_substr_count($haystack, $needle) { - return substr_count($haystack, $needle); - } + function mb_substr_count($haystack, $needle) + { + return substr_count($haystack, $needle); + } } From 5ee02b5fc13b541f5c7c2b708d3e276668240aa2 Mon Sep 17 00:00:00 2001 From: "Oleg Mikhailov (miholeus)" Date: Thu, 29 May 2014 19:22:23 +0400 Subject: [PATCH 47/59] case sensitive dom* objects --- src/PhpQueryEvents.php | 2 +- src/PhpQueryObject.php | 2 +- src/Tests/_archive/document_types.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/PhpQueryEvents.php b/src/PhpQueryEvents.php index 6987648..5f5030c 100644 --- a/src/PhpQueryEvents.php +++ b/src/PhpQueryEvents.php @@ -1,7 +1,7 @@ Date: Thu, 29 May 2014 19:31:05 +0400 Subject: [PATCH 48/59] =?UTF-8?q?[fixed]=20=D0=9F=D0=B5=D1=80=D0=B5=D0=B8?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D1=8B=D0=B2=D0=B0=D0=B5=D0=BC=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BA?= =?UTF-8?q?=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD=D0=BE=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D0=BD=D0=B0=20*nix-like?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Dom/{DomDocumentWrapper.php => DOMDocumentWrapper.php} | 0 src/Dom/{DomEvent.php => DOMEvent.php} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/Dom/{DomDocumentWrapper.php => DOMDocumentWrapper.php} (100%) rename src/Dom/{DomEvent.php => DOMEvent.php} (100%) diff --git a/src/Dom/DomDocumentWrapper.php b/src/Dom/DOMDocumentWrapper.php similarity index 100% rename from src/Dom/DomDocumentWrapper.php rename to src/Dom/DOMDocumentWrapper.php diff --git a/src/Dom/DomEvent.php b/src/Dom/DOMEvent.php similarity index 100% rename from src/Dom/DomEvent.php rename to src/Dom/DOMEvent.php From c13257e74a45dc98cb3fe44c9f43abe9aa446956 Mon Sep 17 00:00:00 2001 From: "Oleg Mikhailov (miholeus)" Date: Mon, 2 Jun 2014 09:56:08 +0400 Subject: [PATCH 49/59] name resolve fixes --- src/PhpQuery.php | 12 ++++++------ src/Proxy/jQueryServer.php | 8 +++++--- src/Tests/BasicTest.php | 18 ++++++++++-------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/PhpQuery.php b/src/PhpQuery.php index 27d80e2..06f706f 100644 --- a/src/PhpQuery.php +++ b/src/PhpQuery.php @@ -932,7 +932,7 @@ public static function ajax($options = array(), $xhr = null) $client->setParameterPost($options['data']); } if (self::$active == 0 && $options['global']) - phpQueryEvents::trigger($documentID, 'ajaxStart'); + PhpQueryEvents::trigger($documentID, 'ajaxStart'); self::$active++; // beforeSend callback if (isset($options['beforeSend']) && $options['beforeSend']) @@ -944,7 +944,7 @@ public static function ajax($options = array(), $xhr = null) ); // ajaxSend event if ($options['global']) - phpQueryEvents::trigger( + PhpQueryEvents::trigger( $documentID, 'ajaxSend', array( @@ -982,7 +982,7 @@ public static function ajax($options = array(), $xhr = null) ) ); if ($options['global']) - phpQueryEvents::trigger( + PhpQueryEvents::trigger( $documentID, 'ajaxSuccess', array( @@ -1001,7 +1001,7 @@ public static function ajax($options = array(), $xhr = null) ) ); if ($options['global']) - phpQueryEvents::trigger( + PhpQueryEvents::trigger( $documentID, 'ajaxError', array( @@ -1021,7 +1021,7 @@ public static function ajax($options = array(), $xhr = null) ) ); if ($options['global']) - phpQueryEvents::trigger( + PhpQueryEvents::trigger( $documentID, 'ajaxComplete', array( @@ -1030,7 +1030,7 @@ public static function ajax($options = array(), $xhr = null) ) ); if ($options['global'] && !--self::$active) - phpQueryEvents::trigger($documentID, 'ajaxStop'); + PhpQueryEvents::trigger($documentID, 'ajaxStop'); return $client; // if (is_null($domId)) // $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; diff --git a/src/Proxy/jQueryServer.php b/src/Proxy/jQueryServer.php index 58624fa..260d6e4 100755 --- a/src/Proxy/jQueryServer.php +++ b/src/Proxy/jQueryServer.php @@ -1,5 +1,8 @@ ` options['dataType'] = ''; switch (strtolower($this->options['dataType'])) { case 'json': - if ($pq instanceof PHPQUERYOBJECT) { + if ($pq instanceof PhpQueryObject) { $results = array(); foreach ($pq as $node) $results[] = pq($node)->htmlOuter(); @@ -112,5 +115,4 @@ public function success($response) { // : $this->json->decode($data); // } } -new jQueryServer($_POST['data']); -?> \ No newline at end of file +new jQueryServer($_POST['data']); \ No newline at end of file diff --git a/src/Tests/BasicTest.php b/src/Tests/BasicTest.php index 82f931b..84f8f4e 100644 --- a/src/Tests/BasicTest.php +++ b/src/Tests/BasicTest.php @@ -1,6 +1,8 @@ Date: Thu, 10 Jul 2014 11:07:41 -0500 Subject: [PATCH 50/59] Linked to QueryPath. [skip ci] --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 42dc141..2d70ce2 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,11 @@ Source for test.html: Beyond these adjustments, this project will be minimally maintained. For more phpQuery usage information and fork history, I highly recommend you review the https://github.com/electrolinux/phpquery README. +## Very Similar Project + +See [QueryPath](https://github.com/technosophos/querypath) for a more active project that also works +to replicate the jQuery syntax for PHP. + ## My Preferred Alternative There are several alternatives to phpQuery out there. While several have a healthy adoption rate, I was From c9918f04d8dc5bea2c6b84563edc594e988f1acb Mon Sep 17 00:00:00 2001 From: "Oleg Mikhailov (miholeus)" Date: Tue, 15 Jul 2014 16:15:50 +0400 Subject: [PATCH 51/59] Camelcase class name --- docs/bootstrap.example.php | 11 +- docs/demo.php | 24 +-- docs/plugin.example.php | 39 ++-- src/Callback/Callback.php | 4 +- src/Dom/DOMDocumentWrapper.php | 74 +++---- src/Dom/DOMEvent.php | 2 +- src/PhpQuery.php | 209 +++++++++---------- src/PhpQueryEvents.php | 28 +-- src/PhpQueryObject.php | 250 +++++++++++------------ src/Plugin/Scripts.php | 14 +- src/Plugin/Scripts/google_login.php | 12 +- src/Plugin/WebBrowser.php | 60 +++--- src/Proxy/jQueryServer.php | 20 +- src/Tests/BasicTest.php | 14 +- src/Tests/_archive/document_types.php | 4 +- src/Tests/_archive/test_2.php | 30 +-- src/Tests/_archive/test_4.php | 16 +- src/Tests/_archive/test_5.php | 6 +- src/Tests/_archive/test_ajax.php | 26 +-- src/Tests/_archive/test_arrayaccess.php | 12 +- src/Tests/_archive/test_attr.php | 8 +- src/Tests/_archive/test_callback.php | 8 +- src/Tests/_archive/test_charset.php | 18 +- src/Tests/_archive/test_document.php | 16 +- src/Tests/_archive/test_events.php | 6 +- src/Tests/_archive/test_insert.php | 10 +- src/Tests/_archive/test_manipulation.php | 16 +- src/Tests/_archive/test_manual.php | 90 ++++---- src/Tests/_archive/test_multidoc.php | 14 +- src/Tests/_archive/test_php.php | 8 +- src/Tests/_archive/test_replace.php | 8 +- src/Tests/_archive/test_scripts.php | 24 +-- src/Tests/_archive/test_selectors.php | 208 +++++++++---------- src/Tests/_archive/test_webbrowser.php | 26 +-- src/Tests/_archive/test_wrap.php | 14 +- 35 files changed, 658 insertions(+), 671 deletions(-) diff --git a/docs/bootstrap.example.php b/docs/bootstrap.example.php index 4fafe1a..4cdb1f7 100644 --- a/docs/bootstrap.example.php +++ b/docs/bootstrap.example.php @@ -1,14 +1,13 @@ \ No newline at end of file +//PhpQuery::ajaxAllowHost(); +//PhpQuery::ajaxAllowURL(); +//PhpQuery::plugin(); \ No newline at end of file diff --git a/docs/demo.php b/docs/demo.php index 63dacea..f7f7853 100644 --- a/docs/demo.php +++ b/docs/demo.php @@ -1,14 +1,14 @@ '); +$doc = PhpQuery::newDocument('
    '); // FILL IT // array syntax works like ->find() here @@ -28,7 +28,7 @@ // SELECT DOCUMENT // pq(); is using selected document as default -phpQuery::selectDocument($doc); +PhpQuery::selectDocument($doc); // documents are selected when created or by above method // query all unordered lists in last selected document $ul = pq('ul')->insertAfter('div'); @@ -36,18 +36,18 @@ // ITERATE IT // all direct LIs from $ul foreach($ul['> li'] as $li) { - // iteration returns PLAIN dom nodes, NOT phpQuery objects + // iteration returns PLAIN dom nodes, NOT PhpQuery objects $tagName = $li->tagName; $childNodes = $li->childNodes; - // so you NEED to wrap it within phpQuery, using pq(); + // so you NEED to wrap it within PhpQuery, using pq(); pq($li)->addClass('my-second-new-class'); } // PRINT OUTPUT // 1st way -print phpQuery::getDocument($doc->getDocumentID()); +print PhpQuery::getDocument($doc->getDocumentID()); // 2nd way -print phpQuery::getDocument(pq('div')->getDocumentID()); +print PhpQuery::getDocument(pq('div')->getDocumentID()); // 3rd way print pq('div')->getDocument(); // 4th way diff --git a/docs/plugin.example.php b/docs/plugin.example.php index c2270f4..2751a98 100644 --- a/docs/plugin.example.php +++ b/docs/plugin.example.php @@ -1,26 +1,26 @@ plugin('example') * pq('ul')->plugin('example', 'example.php') * * Plugin classes are never intialized, just method calls are forwarded - * in static way from phpQuery. + * in static way from PhpQuery. * * Have fun writing plugins :) */ /** - * phpQuery plugin class extending phpQuery object. - * Methods from this class are callable on every phpQuery object. + * PhpQuery plugin class extending PhpQuery object. + * Methods from this class are callable on every PhpQuery object. * * Class name prefix '\PhpQuery\Plugin\' must be preserved. */ -abstract class \PhpQuery\Plugin\example { +abstract class PhpQuery_Plugin_example { /** * Limit binded methods. * @@ -29,14 +29,14 @@ abstract class \PhpQuery\Plugin\example { * * @var array|null */ - public static $phpQueryMethods = null; + public static $PhpQueryMethods = null; /** * Enter description here... * - * @param PhpQueryObject $self + * @param \PhpQueryObject $self */ public static function example($self, $arg1) { - // this method can be called on any phpQuery object, like this: + // this method can be called on any PhpQuery object, like this: // pq('div')->example('$arg1 Value') // do something @@ -45,19 +45,19 @@ public static function example($self, $arg1) { return $self->find('div'); } protected static function helperFunction() { - // this method WONT be avaible as phpQuery method, + // this method WONT be avaible as PhpQuery method, // because it isn't publicly callable } } /** - * phpQuery plugin class extending phpQuery static namespace. + * PhpQuery plugin class extending PhpQuery static namespace. * Methods from this class are callable as follows: - * phpQuery::$plugins->staticMethod() + * PhpQuery::$plugins->staticMethod() * - * Class name prefix 'phpQueryPlugin_' must be preserved. + * Class name prefix 'PhpQueryPlugin_' must be preserved. */ -abstract class phpQueryPlugin_example { +abstract class PhpQueryPlugin_example { /** * Limit binded methods. * @@ -66,10 +66,9 @@ abstract class phpQueryPlugin_example { * * @var array|null */ - public static $phpQueryMethods = null; + public static $PhpQueryMethods = null; public static function staticMethod() { - // this method can be called within phpQuery class namespace, like this: - // phpQuery::$plugins->staticMethod() + // this method can be called within PhpQuery class namespace, like this: + // PhpQuery::$plugins->staticMethod() } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/src/Callback/Callback.php b/src/Callback/Callback.php index d9a90ea..1320238 100644 --- a/src/Callback/Callback.php +++ b/src/Callback/Callback.php @@ -14,11 +14,11 @@ function getName(); * 'param1 is now statically set', * new CallbackParam, new CallbackParam * ); - * phpQuery::callbackRun($fooCurried, + * PhpQuery::callbackRun($fooCurried, * array('param2 value', 'param3 value' * ); * - * Callback class is supported in all phpQuery methods which accepts callbacks. + * Callback class is supported in all PhpQuery methods which accepts callbacks. * * @link http://code.google.com/p/phpquery/wiki/Callbacks#Param_Structures * @author Tobiasz Cudnik diff --git a/src/Dom/DOMDocumentWrapper.php b/src/Dom/DOMDocumentWrapper.php index f056ce9..a8cbf01 100644 --- a/src/Dom/DOMDocumentWrapper.php +++ b/src/Dom/DOMDocumentWrapper.php @@ -1,7 +1,7 @@ - * @package phpQuery + * @package PhpQuery */ class DOMDocumentWrapper { @@ -60,7 +60,7 @@ public function __construct($markup = null, $contentType = null, $newDocumentID public function load($markup, $contentType = null, $newDocumentID = null) { - // phpQuery::$documents[$id] = $this; + // PhpQuery::$documents[$id] = $this; $this->contentType = strtolower($contentType); if ($markup instanceof \DOMDocument) { $this->document = $markup; @@ -78,7 +78,7 @@ public function load($markup, $contentType = null, $newDocumentID = null) $this->afterMarkupLoad(); return true; // remember last loaded document - // return phpQuery::selectDocument($id); + // return PhpQuery::selectDocument($id); } return false; } @@ -99,34 +99,34 @@ protected function loadMarkup($markup) list($contentType, $charset) = $this->contentTypeToArray($this->contentType); switch ($contentType) { case 'text/html': - phpQuery::debug("Loading HTML, content type '{$this->contentType}'"); + PhpQuery::debug("Loading HTML, content type '{$this->contentType}'"); $loaded = $this->loadMarkupHTML($markup, $charset); break; case 'text/xml': case 'application/xhtml+xml': - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + PhpQuery::debug("Loading XML, content type '{$this->contentType}'"); $loaded = $this->loadMarkupXML($markup, $charset); break; default: // for feeds or anything that sometimes doesn't use text/xml if (strpos('xml', $this->contentType) !== false) { - phpQuery::debug("Loading XML, content type '{$this->contentType}'"); + PhpQuery::debug("Loading XML, content type '{$this->contentType}'"); $loaded = $this->loadMarkupXML($markup, $charset); } else { - phpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); + PhpQuery::debug("Could not determine document type from content type '{$this->contentType}'"); } } } else { // content type autodetection if ($this->isXML($markup)) { - phpQuery::debug("Loading XML, isXML() == true"); + PhpQuery::debug("Loading XML, isXML() == true"); $loaded = $this->loadMarkupXML($markup); if (!$loaded && $this->isXHTML) { - phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); + PhpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true'); $loaded = $this->loadMarkupHTML($markup); } } else { - phpQuery::debug("Loading HTML, isXML() == false"); + PhpQuery::debug("Loading HTML, isXML() == false"); $loaded = $this->loadMarkupHTML($markup); } } @@ -152,8 +152,8 @@ protected function documentCreate($charset, $version = '1.0') protected function loadMarkupHTML($markup, $requestedCharset = null) { - if (phpQuery::$debug) { - phpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250)); + if (PhpQuery::$debug) { + PhpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250)); } $this->loadMarkupReset(); $this->isHTML = true; @@ -172,7 +172,7 @@ protected function loadMarkupHTML($markup, $requestedCharset = null) } } if (!$charset) { - $charset = phpQuery::$defaultCharset; + $charset = PhpQuery::$defaultCharset; } // HTTP 1.1 says that the default charset is ISO-8859-1 // @see http://www.w3.org/International/O-HTTP-charset @@ -184,11 +184,11 @@ protected function loadMarkupHTML($markup, $requestedCharset = null) // Worse, some pages can have mixed encodings... we'll try not to worry about that $requestedCharset = strtoupper($requestedCharset); $documentCharset = strtoupper($documentCharset); - phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); + PhpQuery::debug("DOC: $documentCharset REQ: $requestedCharset"); if ($requestedCharset && $documentCharset && $requestedCharset !== $documentCharset ) { - phpQuery::debug("CHARSET CONVERT"); + PhpQuery::debug("CHARSET CONVERT"); // Document Encoding Conversion // http://code.google.com/p/phpquery/issues/detail?id=86 if (function_exists('mb_detect_encoding')) { @@ -202,33 +202,33 @@ protected function loadMarkupHTML($markup, $requestedCharset = null) $docEncoding = $documentCharset; } // ok trust the document - phpQuery::debug("DETECTED '$docEncoding'"); + PhpQuery::debug("DETECTED '$docEncoding'"); // Detected does not match what document says... if ($docEncoding !== $documentCharset) { // Tricky.. } if ($docEncoding !== $requestedCharset) { - phpQuery::debug("CONVERT $docEncoding => $requestedCharset"); + PhpQuery::debug("CONVERT $docEncoding => $requestedCharset"); $markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding); $markup = $this->charsetAppendToHTML($markup, $requestedCharset); $charset = $requestedCharset; } } else { - phpQuery::debug("TODO: charset conversion without mbstring..."); + PhpQuery::debug("TODO: charset conversion without mbstring..."); } } $return = false; if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); + PhpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'"); $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); } else { if ($addDocumentCharset) { - phpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); + PhpQuery::debug("Full markup load (HTML), appending charset: '$charset'"); $markup = $this->charsetAppendToHTML($markup, $charset); } - phpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); + PhpQuery::debug("Full markup load (HTML), documentCreate('$charset')"); $this->documentCreate($charset); - $return = phpQuery::$debug === 2 ? $this->document->loadHTML($markup) + $return = PhpQuery::$debug === 2 ? $this->document->loadHTML($markup) : @$this->document->loadHTML($markup); if ($return) { $this->root = $this->document; @@ -242,8 +242,8 @@ protected function loadMarkupHTML($markup, $requestedCharset = null) protected function loadMarkupXML($markup, $requestedCharset = null) { - if (phpQuery::$debug) { - phpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250)); + if (PhpQuery::$debug) { + PhpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250)); } $this->loadMarkupReset(); $this->isXML = true; @@ -268,7 +268,7 @@ protected function loadMarkupXML($markup, $requestedCharset = null) // this is XHTML, try to get charset from content-type meta header $documentCharset = $this->charsetFromHTML($markup); if ($documentCharset) { - phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); + PhpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'"); $this->charsetAppendToXML($markup, $documentCharset); $charset = $documentCharset; } @@ -283,7 +283,7 @@ protected function loadMarkupXML($markup, $requestedCharset = null) } } if (!$charset) { - $charset = phpQuery::$defaultCharset; + $charset = PhpQuery::$defaultCharset; } if ($requestedCharset && $documentCharset && $requestedCharset != $documentCharset @@ -293,13 +293,13 @@ protected function loadMarkupXML($markup, $requestedCharset = null) } $return = false; if ($this->isDocumentFragment) { - phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); + PhpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'"); $return = $this->documentFragmentLoadMarkup($this, $charset, $markup); } else { // FIXME ??? if ($isContentTypeXHTML && !$isMarkupXHTML) { if (!$documentCharset) { - phpQuery::debug("Full markup load (XML), appending charset '$charset'"); + PhpQuery::debug("Full markup load (XML), appending charset '$charset'"); $markup = $this->charsetAppendToXML($markup, $charset); } } @@ -312,11 +312,11 @@ protected function loadMarkupXML($markup, $requestedCharset = null) $this->documentCreate($charset); if (phpversion() < 5.1) { $this->document->resolveExternals = true; - $return = phpQuery::$debug === 2 ? $this->document->loadXML($markup) + $return = PhpQuery::$debug === 2 ? $this->document->loadXML($markup) : @$this->document->loadXML($markup); } else { /** @link http://pl2.php.net/manual/en/libxml.constants.php */ - $libxmlStatic = phpQuery::$debug === 2 ? LIBXML_DTDLOAD + $libxmlStatic = PhpQuery::$debug === 2 ? LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING | LIBXML_NOERROR; @@ -619,7 +619,7 @@ private function documentFragmentLoadMarkup($fragment, $charset, $markup = null) $fragment->root = $fragment->document->firstChild; } } else { - $markup2 = phpQuery::$defaultDoctype + $markup2 = PhpQuery::$defaultDoctype . ''; $noBody = strpos($markup, 'isDocumentFragment; $fragment->isDocumentFragment = false; $markup = $fragment->markup(); @@ -661,8 +661,8 @@ protected function documentFragmentToMarkup($fragment) $markup = substr($markup, 0, strrpos($markup, '')); } $fragment->isDocumentFragment = $tmp; - if (phpQuery::$debug) { - phpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150)); + if (PhpQuery::$debug) { + PhpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150)); } return $markup; } @@ -692,7 +692,7 @@ public function markup($nodes = null, $innerMarkup = false) if ($node->isSameNode($this->root)) { // var_dump($node); $nodes = array_slice($nodes, 0, $i) - + phpQuery::DOMNodeListToArray($node->childNodes) + + PhpQuery::DOMNodeListToArray($node->childNodes) + array_slice($nodes, $i + 1); } } @@ -770,7 +770,7 @@ protected static function markupFixXHTML($markup) public static function debug($text) { - phpQuery::debug($text); + PhpQuery::debug($text); } /** diff --git a/src/Dom/DOMEvent.php b/src/Dom/DOMEvent.php index 8704522..47593a0 100644 --- a/src/Dom/DOMEvent.php +++ b/src/Dom/DOMEvent.php @@ -7,7 +7,7 @@ * Based on * @link http://developer.mozilla.org/En/DOM:event * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery * @todo implement ArrayAccess ? */ class DOMEvent diff --git a/src/PhpQuery.php b/src/PhpQuery.php index 06f706f..b9ba06d 100644 --- a/src/PhpQuery.php +++ b/src/PhpQuery.php @@ -1,6 +1,6 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License - * @package phpQuery + * @package PhpQuery */ namespace PhpQuery; @@ -17,15 +17,15 @@ require_once __DIR__ . '/bootstrap.php'; /** - * Shortcut to phpQuery::pq($arg1, $context) + * Shortcut to PhpQuery::pq($arg1, $context) * Chainable. * - * @see phpQuery::pq() + * @see PhpQuery::pq() * @param $arg1 * @param null $context * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery */ function pq($arg1, $context = null) { @@ -33,12 +33,12 @@ function pq($arg1, $context = null) } /** - * Static namespace for phpQuery functions. + * Static namespace for PhpQuery functions. * * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery */ -abstract class phpQuery +abstract class PhpQuery { /** * XXX: Workaround for mbstring problems @@ -53,7 +53,7 @@ abstract class phpQuery /** * Applies only to HTML. * - * @var unknown_type + * @var string */ public static $defaultDoctype = ''; @@ -67,7 +67,7 @@ abstract class phpQuery /** * List of loaded plugins. * - * @var unknown_type + * @var array */ public static $pluginsLoaded = array(); public static $pluginsMethods = array(); @@ -149,7 +149,7 @@ public static function use_function($ns = '\\', $func = 'pq') * pq('
    ', $pq->getDocumentID()) * - Import into same document as \DOMNode belongs to: * pq('
    ', \DOMNode) - * - Import into document from phpQuery object: + * - Import into document from PhpQuery object: * pq('
    ', $pq) * * 2. Run query: @@ -159,21 +159,21 @@ public static function use_function($ns = '\\', $func = 'pq') * pq('div.myClass', $pq->getDocumentID()) * - Run query on same document as \DOMNode belongs to and use node(s)as root for query: * pq('div.myClass', \DOMNode) - * - Run query on document from phpQuery object + * - Run query on document from PhpQuery object * and use object's stack as root node(s) for query: * pq('div.myClass', $pq) * * @param string|\DOMNode|\DOMNodeList|array $arg1 HTML markup, CSS Selector, \DOMNode or array of \DOMNodes - * @param string|PhpQueryObject|\DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or \DOMNode (determines also query root) + * @param string|PhpQueryObject|\DOMNode $context DOM ID from $pq->getDocumentID(), PhpQuery object (determines also query root) or \DOMNode (determines also query root) * * @throws \Exception * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false - * phpQuery object or false in case of error. + * PhpQuery object or false in case of error. */ public static function pq($arg1, $context = null) { if ($arg1 instanceof \DOMNode && !isset($context)) { - foreach (phpQuery::$documents as $documentWrapper) { + foreach (PhpQuery::$documents as $documentWrapper) { $compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument; if ($documentWrapper->document->isSameNode($compare)) { $context = $documentWrapper->id; @@ -183,7 +183,7 @@ public static function pq($arg1, $context = null) if (!$context) { $domId = self::$defaultDocumentID; if (!$domId) { - throw new \Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first."); + throw new \Exception("Can't use last created DOM, because there isn't any. Use PhpQuery::newDocument() first."); } // } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) } else { @@ -220,67 +220,67 @@ public static function pq($arg1, $context = null) } $class = get_class($arg1); // support inheritance by passing old object to overloaded constructor - $phpQuery = $class != 'phpQuery' ? new $class($arg1, $domId) + $PhpQuery = $class != 'PhpQuery' ? new $class($arg1, $domId) : new PhpQueryObject($domId); - $phpQuery->elements = array(); + $PhpQuery->elements = array(); foreach ($arg1->elements as $node) { - $phpQuery->elements[] = $phpQuery->document->importNode($node, true); + $PhpQuery->elements[] = $PhpQuery->document->importNode($node, true); } - return $phpQuery; + return $PhpQuery; } else { if ($arg1 instanceof \DOMNode || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode) ) { /* - * Wrap DOM nodes with phpQuery object, import into document when needed: + * Wrap DOM nodes with PhpQuery object, import into document when needed: * pq(array($domNode1, $domNode2)) */ - $phpQuery = new PhpQueryObject($domId); + $PhpQuery = new PhpQueryObject($domId); if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) { $arg1 = array( $arg1 ); } - $phpQuery->elements = array(); + $PhpQuery->elements = array(); foreach ($arg1 as $node) { $sameDocument = $node->ownerDocument instanceof \DOMDocument - && !$node->ownerDocument->isSameNode($phpQuery->document); - $phpQuery->elements[] = $sameDocument ? $phpQuery->document->importNode($node, true) + && !$node->ownerDocument->isSameNode($PhpQuery->document); + $PhpQuery->elements[] = $sameDocument ? $PhpQuery->document->importNode($node, true) : $node; } - return $phpQuery; + return $PhpQuery; } else { if (self::isMarkup($arg1)) { /** * Import HTML: * pq('
    ') */ - $phpQuery = new PhpQueryObject($domId); - return $phpQuery->newInstance($phpQuery->documentWrapper->import($arg1)); + $PhpQuery = new PhpQueryObject($domId); + return $PhpQuery->newInstance($PhpQuery->documentWrapper->import($arg1)); } else { /** * Run CSS query: * pq('div.myClass') */ - $phpQuery = new PhpQueryObject($domId); + $PhpQuery = new PhpQueryObject($domId); // if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject'))) if ($context && $context instanceof PhpQueryObject) { - $phpQuery->elements = $context->elements; + $PhpQuery->elements = $context->elements; } else { if ($context && $context instanceof \DOMNodeList) { - $phpQuery->elements = array(); + $PhpQuery->elements = array(); foreach ($context as $node) { - $phpQuery->elements[] = $node; + $PhpQuery->elements[] = $node; } } else { if ($context && $context instanceof \DOMNode) { - $phpQuery->elements = array( + $PhpQuery->elements = array( $context ); } } } - return $phpQuery->find($arg1); + return $PhpQuery->find($arg1); } } } @@ -305,16 +305,16 @@ public static function selectDocument($id) * $id can be retrived via getDocumentID() or getDocumentIDRef(). * Chainable. * - * @see phpQuery::selectDocument() + * @see PhpQuery::selectDocument() * @param null $id * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public static function getDocument($id = null) { if ($id) - phpQuery::selectDocument($id); + PhpQuery::selectDocument($id); else - $id = phpQuery::$defaultDocumentID; + $id = PhpQuery::$defaultDocumentID; return new PhpQueryObject($id); } @@ -330,7 +330,7 @@ public static function newDocument($markup = null, $contentType = null) { if (!$markup) $markup = ''; - $documentID = phpQuery::createDocumentWrapper($markup, $contentType); + $documentID = PhpQuery::createDocumentWrapper($markup, $contentType); return new PhpQueryObject($documentID); } @@ -387,7 +387,7 @@ public static function newDocumentXHTML($markup = null, $charset = null) public static function newDocumentPHP($markup = null, $contentType = "text/html") { // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function) - $markup = phpQuery::phpToMarkup($markup, self::$defaultCharset); + $markup = PhpQuery::phpToMarkup($markup, self::$defaultCharset); return self::newDocument($markup, $contentType); } @@ -409,7 +409,7 @@ public static function phpToMarkup($php, $charset = 'utf-8') // .$m[5].$m[2];' // ), array( - 'phpQuery', + 'PhpQuery', '_phpToMarkupCallback' ), $php @@ -439,7 +439,7 @@ public static function _markupToPHPCallback($m) } /** - * Converts document markup containing PHP code generated by phpQuery::php() + * Converts document markup containing PHP code generated by PhpQuery::php() * into valid (executable) PHP code syntax. * * @param string|PhpQueryObject $content @@ -456,7 +456,7 @@ public static function markupToPHP($content) // 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";' // ), array( - 'phpQuery', + 'PhpQuery', '_markupToPHPCallback' ), $content @@ -582,17 +582,17 @@ public static function loadDocument($document) protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) { if (function_exists('domxml_open_mem')) - throw new \Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled."); + throw new \Exception("Old PHP4 DOM XML extension detected. PhpQuery won't work until this extension is enabled."); // $id = $documentID // ? $documentID // : md5(microtime()); $document = null; if ($html instanceof \DOMDocument) { if (self::getDocumentID($html)) { - // document already exists in phpQuery::$documents, make a copy + // document already exists in PhpQuery::$documents, make a copy $document = clone $html; } else { - // new document, add it to phpQuery::$documents + // new document, add it to PhpQuery::$documents $wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID); } } else { @@ -600,9 +600,9 @@ protected static function createDocumentWrapper($html, $contentType = null, $doc } // $wrapper->id = $id; // bind document - phpQuery::$documents[$wrapper->id] = $wrapper; + PhpQuery::$documents[$wrapper->id] = $wrapper; // remember last loaded document - phpQuery::selectDocument($wrapper->id); + PhpQuery::selectDocument($wrapper->id); return $wrapper->id; } @@ -622,7 +622,7 @@ public static function extend($target, $source) $targetRef = & self::$extendMethods; $targetRef2 = & self::$pluginsMethods; break; - case 'phpQuery': + case 'PhpQuery': $targetRef = & self::$extendStaticMethods; $targetRef2 = & self::$pluginsStaticMethods; break; @@ -653,17 +653,17 @@ public static function extend($target, $source) } /** - * Extend phpQuery with $class from $file. + * Extend PhpQuery with $class from $file. * - * @param string $class Extending class name. Real class name can be prepended phpQuery_. + * @param string $class Extending class name. Real class name can be prepended PhpQuery_. * @param string $file Filename to include. Defaults to "{$class}.php". * @throws \Exception * @return bool */ public static function plugin($class, $file = null) { - // TODO $class checked agains phpQuery_$class - // if (strpos($class, 'phpQuery') === 0) + // TODO $class checked agains PhpQuery_$class + // if (strpos($class, 'PhpQuery') === 0) // $class = substr($class, 8); if (in_array($class, self::$pluginsLoaded)) return true; @@ -678,8 +678,8 @@ public static function plugin($class, $file = null) if (class_exists('\PhpQuery\Plugin\Util' . $class)) { $realClass = '\PhpQuery\Plugin\Util' . $class; $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + $loop = isset($vars['PhpQueryMethods']) + && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods'] : get_class_methods($realClass); foreach ($loop as $method) { if ($method == '__initialize') @@ -711,8 +711,8 @@ public static function plugin($class, $file = null) if (class_exists('\\PhpQuery\\Plugin\\' . $class)) { $realClass = '\\PhpQuery\\Plugin\\' . $class; $vars = get_class_vars($realClass); - $loop = isset($vars['phpQueryMethods']) - && !is_null($vars['phpQueryMethods']) ? $vars['phpQueryMethods'] + $loop = isset($vars['PhpQueryMethods']) + && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods'] : get_class_methods($realClass); foreach ($loop as $method) { if (!is_callable( @@ -738,24 +738,24 @@ public static function plugin($class, $file = null) * Unloades all or specified document from memory. * * @param null $id - * @internal param mixed $documentID @see phpQuery::getDocumentID() for supported types. + * @internal param mixed $documentID @see PhpQuery::getDocumentID() for supported types. */ public static function unloadDocuments($id = null) { if (isset($id)) { if ($id = self::getDocumentID($id)) - unset(phpQuery::$documents[$id]); + unset(PhpQuery::$documents[$id]); } else { - foreach (phpQuery::$documents as $k => $v) { - unset(phpQuery::$documents[$k]); + foreach (PhpQuery::$documents as $k => $v) { + unset(PhpQuery::$documents[$k]); } } } /** - * Parses phpQuery object or HTML result against PHP tags and makes them active. + * Parses PhpQuery object or HTML result against PHP tags and makes them active. * - * @param phpQuery|string $content + * @param PhpQuery|string $content * @deprecated * @return string */ @@ -801,7 +801,7 @@ public static function debug($text) * @throws \Exception * @internal param \PhpQuery\See $array $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions * Additional options are: - * 'document' - document for global events, @see phpQuery::getDocumentID() + * 'document' - document for global events, @see PhpQuery::getDocumentID() * 'referer' - implemented * 'requested_with' - TODO; not implemented (X-Requested-With) * @return \Zend_Http_Client @@ -845,7 +845,7 @@ public static function ajax($options = array(), $xhr = null) $host = parse_url($options['url'], PHP_URL_HOST); if (!in_array($host, self::$ajaxAllowedHosts)) { throw new \Exception("Request not permitted, host '$host' not present in " - . "phpQuery::\$ajaxAllowedHosts"); + . "PhpQuery::\$ajaxAllowedHosts"); } // JSONP $jsre = "/=\\?(&|$)/"; @@ -936,7 +936,7 @@ public static function ajax($options = array(), $xhr = null) self::$active++; // beforeSend callback if (isset($options['beforeSend']) && $options['beforeSend']) - phpQuery::callbackRun( + PhpQuery::callbackRun( $options['beforeSend'], array( $client @@ -952,7 +952,7 @@ public static function ajax($options = array(), $xhr = null) $options ) ); - if (phpQuery::$debug) { + if (PhpQuery::$debug) { self::debug("{$options['type']}: {$options['url']}\n"); self::debug("Options:
    " . var_export($options, true) . "
    \n"); // if ($client->getCookieJar()) @@ -960,7 +960,7 @@ public static function ajax($options = array(), $xhr = null) } // request $response = $client->request(); - if (phpQuery::$debug) { + if (PhpQuery::$debug) { self::debug( 'Status: ' . $response->getStatus() . ' / ' . $response->getMessage() @@ -973,7 +973,7 @@ public static function ajax($options = array(), $xhr = null) self::$lastModified = $response->getHeader('Last-Modified'); $data = self::httpData($response->getBody(), $options['dataType'], $options); if (isset($options['success']) && $options['success']) - phpQuery::callbackRun( + PhpQuery::callbackRun( $options['success'], array( $data, @@ -992,7 +992,7 @@ public static function ajax($options = array(), $xhr = null) ); } else { if (isset($options['error']) && $options['error']) - phpQuery::callbackRun( + PhpQuery::callbackRun( $options['error'], array( $client, @@ -1013,7 +1013,7 @@ public static function ajax($options = array(), $xhr = null) ); } if (isset($options['complete']) && $options['complete']) - phpQuery::callbackRun( + PhpQuery::callbackRun( $options['complete'], array( $client, @@ -1034,7 +1034,7 @@ public static function ajax($options = array(), $xhr = null) return $client; // if (is_null($domId)) // $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false; - // return new phpQueryAjaxResponse($response, $domId); + // return new PhpQueryAjaxResponse($response, $domId); } protected static function httpData($data, $type, $options) @@ -1061,7 +1061,7 @@ protected static function httpData($data, $type, $options) /** * Enter description here... * - * @param array|phpQuery $data + * @param array|PhpQuery $data * * @return string */ @@ -1077,7 +1077,7 @@ public static function get($url, $data = null, $callback = null, $type = null) $data = null; } // TODO some array_values on this shit - return phpQuery::ajax( + return PhpQuery::ajax( array( 'type' => 'GET', 'url' => $url, @@ -1094,7 +1094,7 @@ public static function post($url, $data = null, $callback = null, $type = null) $callback = $data; $data = null; } - return phpQuery::ajax( + return PhpQuery::ajax( array( 'type' => 'POST', 'url' => $url, @@ -1112,7 +1112,7 @@ public static function getJSON($url, $data = null, $callback = null) $data = null; } // TODO some array_values on this shit - return phpQuery::ajax( + return PhpQuery::ajax( array( 'type' => 'GET', 'url' => $url, @@ -1132,8 +1132,8 @@ public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) { $loop = is_array($host1) ? $host1 : func_get_args(); foreach ($loop as $host) { - if ($host && !in_array($host, phpQuery::$ajaxAllowedHosts)) { - phpQuery::$ajaxAllowedHosts[] = $host; + if ($host && !in_array($host, PhpQuery::$ajaxAllowedHosts)) { + PhpQuery::$ajaxAllowedHosts[] = $host; } } } @@ -1142,7 +1142,7 @@ public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) { $loop = is_array($url1) ? $url1 : func_get_args(); foreach ($loop as $url) - phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); + PhpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST)); } /** @@ -1188,18 +1188,18 @@ public static function parseJSON($json) public static function getDocumentID($source) { if ($source instanceof \DOMDocument) { - foreach (phpQuery::$documents as $id => $document) { + foreach (PhpQuery::$documents as $id => $document) { if ($source->isSameNode($document->document)) return $id; } } else if ($source instanceof \DOMNode) { - foreach (phpQuery::$documents as $id => $document) { + foreach (PhpQuery::$documents as $id => $document) { if ($source->ownerDocument->isSameNode($document->document)) return $id; } } else if ($source instanceof PhpQueryObject) return $source->getDocumentID(); - else if (is_string($source) && isset(phpQuery::$documents[$source])) + else if (is_string($source) && isset(PhpQuery::$documents[$source])) return $source; } @@ -1266,7 +1266,7 @@ public static function each($object, $callback, $param1 = null, $param2 = null, } if (is_object($object) && !($object instanceof \Iterator)) { foreach (get_object_vars($object) as $name => $value) - phpQuery::callbackRun( + PhpQuery::callbackRun( $callback, array( $name, @@ -1276,7 +1276,7 @@ public static function each($object, $callback, $param1 = null, $param2 = null, ); } else { foreach ($object as $name => $value) - phpQuery::callbackRun( + PhpQuery::callbackRun( $callback, array( $name, @@ -1300,7 +1300,7 @@ public static function map($array, $callback, $param1 = null, $param2 = null, $p $paramStructure = array_slice($paramStructure, 2); } foreach ($array as $v) { - $vv = phpQuery::callbackRun( + $vv = PhpQuery::callbackRun( $callback, array( $v @@ -1355,7 +1355,7 @@ public static function callbackRun($callback, $params = array(), $paramStructure } /** - * Merge 2 phpQuery objects. + * Merge 2 PhpQuery objects. * @param array $one * @param array $two * @return array @@ -1528,7 +1528,7 @@ public static function __callStatic($method, $params) { return call_user_func_array( array( - phpQuery::$plugins, + PhpQuery::$plugins, $method ), $params @@ -1538,19 +1538,19 @@ public static function __callStatic($method, $params) protected static function dataSetupNode($node, $documentID) { // search are return if alredy exists - foreach (phpQuery::$documents[$documentID]->dataNodes as $dataNode) { + foreach (PhpQuery::$documents[$documentID]->dataNodes as $dataNode) { if ($node->isSameNode($dataNode)) return $dataNode; } // if doesn't, add it - phpQuery::$documents[$documentID]->dataNodes[] = $node; + PhpQuery::$documents[$documentID]->dataNodes[] = $node; return $node; } protected static function dataRemoveNode($node, $documentID) { // search are return if alredy exists - foreach (phpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { + foreach (PhpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) { if ($node->isSameNode($dataNode)) { unset(self::$documents[$documentID]->dataNodes[$k]); unset(self::$documents[$documentID]->data[$dataNode->dataID]); @@ -1563,10 +1563,10 @@ public static function data($node, $name, $data, $documentID = null) if (!$documentID) // TODO check if this works $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; + $document = PhpQuery::$documents[$documentID]; $node = self::dataSetupNode($node, $documentID); if (!isset($node->dataID)) - $node->dataID = ++phpQuery::$documents[$documentID]->uuid; + $node->dataID = ++PhpQuery::$documents[$documentID]->uuid; $id = $node->dataID; if (!isset($document->data[$id])) $document->data[$id] = array(); @@ -1584,7 +1584,7 @@ public static function removeData($node, $name, $documentID) if (!$documentID) // TODO check if this works $documentID = self::getDocumentID($node); - $document = phpQuery::$documents[$documentID]; + $document = PhpQuery::$documents[$documentID]; $node = self::dataSetupNode($node, $documentID); $id = $node->dataID; if ($name) { @@ -1605,17 +1605,17 @@ public static function removeData($node, $name, $documentID) * Plugins static namespace class. * * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery * @todo move plugin methods here (as statics) */ -class phpQueryPlugins +class PhpQueryPlugins { public function __call($method, $args) { - if (isset(phpQuery::$extendStaticMethods[$method])) { - $return = call_user_func_array(phpQuery::$extendStaticMethods[$method], $args); - } else if (isset(phpQuery::$pluginsStaticMethods[$method])) { - $class = phpQuery::$pluginsStaticMethods[$method]; + if (isset(PhpQuery::$extendStaticMethods[$method])) { + $return = call_user_func_array(PhpQuery::$extendStaticMethods[$method], $args); + } else if (isset(PhpQuery::$pluginsStaticMethods[$method])) { + $class = PhpQuery::$pluginsStaticMethods[$method]; $realClass = "\PhpQuery\Plugin\Util$class"; $return = call_user_func_array( array( @@ -1630,15 +1630,4 @@ public function __call($method, $args) } } -// // add plugins dir and Zend framework to include path -// set_include_path( -// get_include_path() -// .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/' -// .PATH_SEPARATOR.dirname(__FILE__).'/phpQuery/plugins/' -// ); -// why ? no __call nor __get for statics in php... -// XXX __callStatic will be available in PHP 5.3 -phpQuery::$plugins = new phpQueryPlugins(); -// include bootstrap file (personal library config) -if (file_exists(dirname(__FILE__) . '/phpQuery/bootstrap.php')) - require_once dirname(__FILE__) . '/phpQuery/bootstrap.php'; \ No newline at end of file +PhpQuery::$plugins = new PhpQueryPlugins(); \ No newline at end of file diff --git a/src/PhpQueryEvents.php b/src/PhpQueryEvents.php index 5f5030c..29f79ef 100644 --- a/src/PhpQueryEvents.php +++ b/src/PhpQueryEvents.php @@ -7,7 +7,7 @@ * Event handling class. * * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery * @static */ abstract class PhpQueryEvents @@ -27,7 +27,7 @@ abstract class PhpQueryEvents public static function trigger($document, $type, $data = array(), $node = null) { // trigger: function(type, data, elem, donative, extra) { - $documentID = phpQuery::getDocumentID($document); + $documentID = PhpQuery::getDocumentID($document); $namespace = null; if (strpos($type, '.') !== false) { list($name, $namespace) = explode('.', $type); @@ -36,7 +36,7 @@ public static function trigger($document, $type, $data = array(), $node = null) } if (!$node) { if (self::issetGlobal($documentID, $type)) { - $pq = phpQuery::getDocument($documentID); + $pq = PhpQuery::getDocument($documentID); // TODO check add($pq->document) $pq->find('*')->add($pq->document)->trigger($type, $data); } @@ -56,7 +56,7 @@ public static function trigger($document, $type, $data = array(), $node = null) $i = 0; while ($node) { // TODO whois - phpQuery::debug( + PhpQuery::debug( "Triggering " . ($i ? "bubbled " : '') . "event '{$type}' on " . "node \n" ); @@ -78,7 +78,7 @@ public static function trigger($document, $type, $data = array(), $node = null) continue; } foreach ($handlers as $handler) { - phpQuery::debug("Calling event handler\n"); + PhpQuery::debug("Calling event handler\n"); $event->data = $handler['data'] ? $handler['data'] : null; $params = array_merge( array( @@ -86,7 +86,7 @@ public static function trigger($document, $type, $data = array(), $node = null) ), $data ); - $return = phpQuery::callbackRun($handler['callback'], $params); + $return = PhpQuery::callbackRun($handler['callback'], $params); if ($return === false) { $event->bubbles = false; } @@ -119,8 +119,8 @@ public static function trigger($document, $type, $data = array(), $node = null) */ public static function add($document, $node, $type, $data, $callback = null) { - phpQuery::debug("Binding '$type' event"); - $documentID = phpQuery::getDocumentID($document); + PhpQuery::debug("Binding '$type' event"); + $documentID = PhpQuery::getDocumentID($document); // if (is_null($callback) && is_callable($data)) { // $callback = $data; // $data = null; @@ -151,7 +151,7 @@ public static function add($document, $node, $type, $data, $callback = null) */ public static function remove($document, $node, $type = null, $callback = null) { - $documentID = phpQuery::getDocumentID($document); + $documentID = PhpQuery::getDocumentID($document); $eventNode = self::getNode($documentID, $node); if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) { if ($callback) { @@ -168,7 +168,7 @@ public static function remove($document, $node, $type = null, $callback = null) protected static function getNode($documentID, $node) { - foreach (phpQuery::$documents[$documentID]->eventsNodes as $eventNode) { + foreach (PhpQuery::$documents[$documentID]->eventsNodes as $eventNode) { if ($node->isSameNode($eventNode)) { return $eventNode; } @@ -177,16 +177,16 @@ protected static function getNode($documentID, $node) protected static function setNode($documentID, $node) { - phpQuery::$documents[$documentID]->eventsNodes[] = $node; - return phpQuery::$documents[$documentID]->eventsNodes[count(phpQuery::$documents[$documentID]->eventsNodes) + PhpQuery::$documents[$documentID]->eventsNodes[] = $node; + return PhpQuery::$documents[$documentID]->eventsNodes[count(PhpQuery::$documents[$documentID]->eventsNodes) - 1]; } protected static function issetGlobal($documentID, $type) { - return isset(phpQuery::$documents[$documentID]) ? in_array( + return isset(PhpQuery::$documents[$documentID]) ? in_array( $type, - phpQuery::$documents[$documentID]->eventsGlobal + PhpQuery::$documents[$documentID]->eventsGlobal ) : false; } diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php index 43b5199..3a97eb9 100644 --- a/src/PhpQueryObject.php +++ b/src/PhpQueryObject.php @@ -4,10 +4,10 @@ use Sabberworm\CSS\Parser as CssParser; /** - * Class representing phpQuery objects. + * Class representing PhpQuery objects. * * @author Tobiasz Cudnik - * @package phpQuery + * @package PhpQuery * @method PhpQueryObject clone() clone() * @method PhpQueryObject empty() empty() * @property Int $length @@ -108,12 +108,12 @@ public function __construct($documentID) $id = $documentID instanceof self ? $documentID->getDocumentID() : $documentID; // var_dump($id); - if (!isset(phpQuery::$documents[$id])) { - // var_dump(phpQuery::$documents); - throw new \Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first."); + if (!isset(PhpQuery::$documents[$id])) { + // var_dump(PhpQuery::$documents); + throw new \Exception("Document with ID '{$id}' isn't loaded. Use PhpQuery::newDocument(\$html) or PhpQuery::newDocumentFile(\$file) first."); } $this->documentID = $id; - $this->documentWrapper = & phpQuery::$documents[$id]; + $this->documentWrapper = & PhpQuery::$documents[$id]; $this->document = & $this->documentWrapper->document; $this->xpath = & $this->documentWrapper->xpath; $this->charset = & $this->documentWrapper->charset; @@ -159,7 +159,7 @@ public function toReference(&$var) public function documentFragment($state = null) { if ($state) { - phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; + PhpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state; return $this; } return $this->documentFragment; @@ -206,15 +206,15 @@ public function toRoot() * Saves object's DocumentID to $var by reference. * * $myDocumentId; - * phpQuery::newDocument('
    ') + * PhpQuery::newDocument('
    ') * ->getDocumentIDRef($myDocumentId) * ->find('div')->... * * * @param $documentID * @internal param string $domId - * @see phpQuery::newDocument - * @see phpQuery::newDocumentFile + * @see PhpQuery::newDocument + * @see PhpQuery::newDocumentFile * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery */ public function getDocumentIDRef(&$documentID) @@ -230,7 +230,7 @@ public function getDocumentIDRef(&$documentID) */ public function getDocument() { - return phpQuery::getDocument($this->getDocumentID()); + return PhpQuery::getDocument($this->getDocumentID()); } /** @@ -245,7 +245,7 @@ public function getDOMDocument() /** * Get object's Document ID. * - * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery + * @return string */ public function getDocumentID() { @@ -261,7 +261,7 @@ public function getDocumentID() */ public function unloadDocument() { - phpQuery::unloadDocuments($this->getDocumentID()); + PhpQuery::unloadDocuments($this->getDocumentID()); } public function isHTML() @@ -287,7 +287,7 @@ public function isXML() */ public function serialize() { - return phpQuery::param($this->serializeArray()); + return PhpQuery::param($this->serializeArray()); } /** @@ -304,7 +304,7 @@ public function serializeArray($submit = null) $return = array(); // $source->dumpDie(); foreach ($source as $input) { - $input = phpQuery::pq($input); + $input = PhpQuery::pq($input); if ($input->is('[disabled]')) { continue; } @@ -339,13 +339,13 @@ public function serializeArray($submit = null) */ protected function debug($in) { - if (!phpQuery::$debug) { + if (!PhpQuery::$debug) { return; } print('
    ');
             print_r($in);
             // file debug
    -        //		file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
    +        //		file_put_contents(dirname(__FILE__).'/PhpQuery.log', print_r($in, true)."\n", FILE_APPEND);
             // quite handy debug trace
             //		if ( is_array($in))
             //			print_r(array_slice(debug_backtrace(), 3));
    @@ -377,7 +377,7 @@ protected function isRegexp($pattern)
          */
         protected function isChar($char)
         {
    -        return extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_eregi('\w', $char)
    +        return extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_eregi('\w', $char)
                 : preg_match('@\w@', $char);
         }
     
    @@ -587,14 +587,14 @@ public function get($index = null, $callback1 = null, $callback2 = null, $callba
             foreach ($args as $callback) {
                 if (is_array($return))
                     foreach ($return as $k => $v)
    -                    $return[$k] = phpQuery::callbackRun(
    +                    $return[$k] = PhpQuery::callbackRun(
                             $callback,
                             array(
                                 $v
                             )
                         );
                 else
    -                $return = phpQuery::callbackRun(
    +                $return = PhpQuery::callbackRun(
                         $callback,
                         array(
                             $return
    @@ -631,7 +631,7 @@ public function getString($index = null, $callback1 = null, $callback2 = null, $
             $args = func_get_args();
             $args = array_slice($args, 1);
             foreach ($args as $callback) {
    -            $return = phpQuery::callbackRun(
    +            $return = PhpQuery::callbackRun(
                     $callback,
                     array(
                         $return
    @@ -670,14 +670,14 @@ public function getStrings($index = null, $callback1 = null, $callback2 = null,
             foreach ($args as $callback) {
                 if (is_array($return))
                     foreach ($return as $k => $v)
    -                    $return[$k] = phpQuery::callbackRun(
    +                    $return[$k] = PhpQuery::callbackRun(
                             $callback,
                             array(
                                 $v
                             )
                         );
                 else
    -                $return = phpQuery::callbackRun(
    +                $return = PhpQuery::callbackRun(
                         $callback,
                         array(
                             $return
    @@ -697,7 +697,7 @@ public function newInstance($newStack = null)
         {
             $class = get_class($this);
             // support inheritance by passing old object to overloaded constructor
    -        $new           = $class != 'phpQuery' ? new $class($this, $this->getDocumentID())
    +        $new           = $class != 'PhpQuery' ? new $class($this, $this->getDocumentID())
                 : new PhpQueryObject($this->getDocumentID());
             $new->previous = $this;
             if (is_null($newStack)) {
    @@ -705,7 +705,7 @@ public function newInstance($newStack = null)
                 if ($this->elementsBackup)
                     $this->elements = $this->elementsBackup;
             } else if (is_string($newStack)) {
    -            $new->elements = phpQuery::pq($newStack, $this->getDocumentID())->stack();
    +            $new->elements = PhpQuery::pq($newStack, $this->getDocumentID())->stack();
             } else {
                 $new->elements = $newStack;
             }
    @@ -793,13 +793,13 @@ protected function runQuery($XQuery, $selector = null, $compare = null)
                 foreach ($nodes as $node) {
                     $matched = false;
                     if ($compare) {
    -                    phpQuery::$debug ? $this->debug(
    +                    PhpQuery::$debug ? $this->debug(
                             "Found: " . $this->whois($node)
                             . ", comparing with {$compare}()"
                         ) : null;
    -                    $phpQueryDebug   = phpQuery::$debug;
    -                    phpQuery::$debug = false;
    -                    // TODO ??? use phpQuery::callbackRun()
    +                    $PhpQueryDebug   = PhpQuery::$debug;
    +                    PhpQuery::$debug = false;
    +                    // TODO ??? use PhpQuery::callbackRun()
                         if (call_user_func_array(
                             array(
                                 $this,
    @@ -812,17 +812,17 @@ protected function runQuery($XQuery, $selector = null, $compare = null)
                         )
                         )
                             $matched = true;
    -                    phpQuery::$debug = $phpQueryDebug;
    +                    PhpQuery::$debug = $PhpQueryDebug;
                     } else {
                         $matched = true;
                     }
                     if ($matched) {
    -                    if (phpQuery::$debug)
    +                    if (PhpQuery::$debug)
                             $debug[] = $this->whois($node);
                         $stack[] = $node;
                     }
                 }
    -            if (phpQuery::$debug) {
    +            if (PhpQuery::$debug) {
                     $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
                 }
                 if ($detachAfter)
    @@ -845,7 +845,7 @@ public function find($selectors, $context = null, $noHistory = false)
                 // backup last stack /for end()/
                 $this->elementsBackup = $this->elements;
             // allow to define context
    -        // TODO combine code below with phpQuery::pq() context guessing code
    +        // TODO combine code below with PhpQuery::pq() context guessing code
             //   as generic function
             if (isset($context)) {
                 if (!is_array($context) && $context instanceof \DOMElement) {
    @@ -881,7 +881,7 @@ public function find($selectors, $context = null, $noHistory = false)
                 $delimiterBefore = false;
                 foreach ($selector as $s) {
                     // TAG
    -                $isTag = extension_loaded('mbstring') && phpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s)
    +                $isTag = extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s)
                         || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*';
                     if ($isTag) {
                         if ($this->isXML()) {
    @@ -991,7 +991,7 @@ public function find($selectors, $context = null, $noHistory = false)
                         $delimiterBefore = 2;
                         // ERRORS
                     } else {
    -                    phpQuery::debug("Unrecognized token '$s'");
    +                    PhpQuery::debug("Unrecognized token '$s'");
                     }
                     $delimiterBefore = $delimiterBefore === 2;
                 }
    @@ -1099,7 +1099,7 @@ protected function pseudoClasses($class)
                     break;
                 case 'submit':
                 case 'reset':
    -                $this->elements = phpQuery::merge(
    +                $this->elements = PhpQuery::merge(
                         $this->map(
                             array(
                                 $this,
    @@ -1273,7 +1273,7 @@ protected function pseudoClasses($class)
     								return ($index-$b)%$a == 0
     									? $node
     									: null;
    -								phpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs");
    +								PhpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs");
     								return $a*floor($index/$a)+$b-1 == $prevs
     										? $node
     										: null;
    @@ -1339,7 +1339,7 @@ protected function __pseudoClassParam($paramsString)
          */
         public function is($selector, $nodes = null)
         {
    -        phpQuery::debug(
    +        PhpQuery::debug(
                 array(
                     "Is:",
                     $selector
    @@ -1384,7 +1384,7 @@ public function filterCallback($callback, $_skipHistory = false)
             }
             $newStack = array();
             foreach ($this->elements as $index => $node) {
    -            $result = phpQuery::callbackRun(
    +            $result = PhpQuery::callbackRun(
                     $callback,
                     array(
                         $index,
    @@ -1473,7 +1473,7 @@ public function filter($selectors, $_skipHistory = false)
                                             $break = true;
                                     } else if ($this->isRegexp($attr)) {
                                         $val = extension_loaded('mbstring')
    -                                    && phpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
    +                                    && PhpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
                                             : preg_quote(trim($val, '"\''), '@');
                                         // switch last character
                                         switch (substr($attr, -1)) {
    @@ -1492,7 +1492,7 @@ public function filter($selectors, $_skipHistory = false)
                                         // cut last character
                                         $attr    = substr($attr, 0, -1);
                                         $isMatch = extension_loaded('mbstring')
    -                                    && phpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
    +                                    && PhpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
                                             : preg_match("@{$pattern}@", $node->getAttribute($attr));
                                         if (!$isMatch)
                                             $break = true;
    @@ -1572,7 +1572,7 @@ protected static function unQuote($value)
          * @param      $url
          * @param null $data
          * @param null $callback
    -     * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
    +     * @return PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          * @todo Support $selector
          */
         public function load($url, $data = null, $callback = null)
    @@ -1583,7 +1583,7 @@ public function load($url, $data = null, $callback = null)
             }
             if (mb_strpos($url, ' ') !== false) {
                 $matches = null;
    -            if (extension_loaded('mbstring') && phpQuery::$mbstringSupport)
    +            if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport)
                     mb_ereg('^([^ ]+) (.*)$', $url, $matches);
                 else
                     preg_match('@^([^ ]+) (.*)$@', $url, $matches);
    @@ -1602,7 +1602,7 @@ public function load($url, $data = null, $callback = null)
                     '__loadSuccess'
                 )
             );
    -        phpQuery::ajax($ajax);
    +        PhpQuery::ajax($ajax);
             return $this;
         }
     
    @@ -1613,17 +1613,17 @@ public function load($url, $data = null, $callback = null)
         public function __loadSuccess($html)
         {
             if ($this->_loadSelector) {
    -            $html = phpQuery::newDocument($html)->find($this->_loadSelector);
    +            $html = PhpQuery::newDocument($html)->find($this->_loadSelector);
                 unset($this->_loadSelector);
             }
             foreach ($this->stack(1) as $node) {
    -            phpQuery::pq($node, $this->getDocumentID())->markup($html);
    +            PhpQuery::pq($node, $this->getDocumentID())->markup($html);
             }
         }
     
         /**
          * Allows users to enter strings of CSS selectors. Useful
    -     * when the CSS is loaded via style or @imports that phpQuery can't load
    +     * when the CSS is loaded via style or @imports that PhpQuery can't load
          * because it doesn't know the URL context of the request.
          */
         public function addCSS($string)
    @@ -1647,11 +1647,11 @@ public function addCSS($string)
         public function css($property_name, $value = false)
         {
             if (!isset($this->cssIsParsed[$this->getDocumentID()])
    -        || $this->cssIsParsed[$this->getDocumentID()] = false
    +        || $this->cssIsParsed[$this->getDocumentID()] === false
             ) {
                 $this->parseCSS();
             }
    -        $data = phpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID());
    +        $data = PhpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID());
             if (!$value) {
                 if (isset($data[$property_name])) {
                     return $data[$property_name]['value'];
    @@ -1664,8 +1664,8 @@ public function css($property_name, $value = false)
                 'specificity' => $specificity,
                 'value'       => $value
             );
    -        phpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID());
    -        $this->bubbleCSS(phpQuery::pq($this->get(0), $this->getDocumentID()));
    +        PhpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID());
    +        $this->bubbleCSS(PhpQuery::pq($this->get(0), $this->getDocumentID()));
     
             if ($specificity >= 1000) {
                 $styles = array();
    @@ -1677,7 +1677,7 @@ public function css($property_name, $value = false)
                 ksort($styles);
                 if (empty($styles)) {
                     $this->removeAttr('style');
    -            } elseif (phpQuery::$enableCssShorthand) {
    +            } elseif (PhpQuery::$enableCssShorthand) {
                     $parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}');
                     $doc    = $parser->parse();
                     $doc->createShorthands();
    @@ -1697,8 +1697,8 @@ public function parseCSS()
                     . '/Resources/default.css'
                 );
             }
    -        foreach (phpQuery::pq('style', $this->getDocumentID()) as $style) {
    -            $this->cssString[$this->getDocumentID()] .= phpQuery::pq($style)->text();
    +        foreach (PhpQuery::pq('style', $this->getDocumentID()) as $style) {
    +            $this->cssString[$this->getDocumentID()] .= PhpQuery::pq($style)->text();
             }
     
             $CssParser   = new CssParser($this->cssString[$this->getDocumentID()]);
    @@ -1706,9 +1706,9 @@ public function parseCSS()
             foreach ($CssDocument->getAllRuleSets() as $ruleset) {
                 foreach ($ruleset->getSelector() as $selector) {
                     $specificity = $selector->getSpecificity();
    -                foreach (phpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) {
    +                foreach (PhpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) {
                         $existing = pq($el)->data('phpquery_css');
    -                    if (phpQuery::$enableCssShorthand) {
    +                    if (PhpQuery::$enableCssShorthand) {
                             $ruleset->expandShorthands();
                         }
                         foreach ($ruleset->getRules() as $value) {
    @@ -1724,12 +1724,12 @@ public function parseCSS()
                                 );
                             }
                         }
    -                    phpQuery::pq($el)->data('phpquery_css', $existing);
    -                    $this->bubbleCSS(phpQuery::pq($el));
    +                    PhpQuery::pq($el)->data('phpquery_css', $existing);
    +                    $this->bubbleCSS(PhpQuery::pq($el));
                     }
                 }
             }
    -        foreach (phpQuery::pq('*', $this->getDocumentID()) as $el) {
    +        foreach (PhpQuery::pq('*', $this->getDocumentID()) as $el) {
                 $existing = pq($el)->data('phpquery_css');
                 $style    = pq($el)->attr('style');
                 $style    = strlen($style) ? explode(';', $style) : array();
    @@ -1743,7 +1743,7 @@ public function parseCSS()
                     $CssDocument = $CssParser->parse();
                     $ruleset     = $CssDocument->getAllRulesets();
                     $ruleset     = reset($ruleset);
    -                if (phpQuery::$enableCssShorthand) {
    +                if (PhpQuery::$enableCssShorthand) {
                         $ruleset->expandShorthands();
                     }
                     foreach ($ruleset->getRules() as $value) {
    @@ -1759,8 +1759,8 @@ public function parseCSS()
                             );
                         }
                     }
    -                phpQuery::pq($el)->data('phpquery_css', $existing);
    -                $this->bubbleCSS(phpQuery::pq($el));
    +                PhpQuery::pq($el)->data('phpquery_css', $existing);
    +                $this->bubbleCSS(PhpQuery::pq($el));
                 }
             }
         }
    @@ -1769,7 +1769,7 @@ protected function bubbleCSS($element)
         {
             $style = $element->data('phpquery_css');
             foreach ($element->children() as $element_child) {
    -            $existing = phpQuery::pq($element_child)->data('phpquery_css');
    +            $existing = PhpQuery::pq($element_child)->data('phpquery_css');
                 foreach ($style as $rule => $value) {
                     if (!isset($existing[$rule])
                         || $value['specificity'] > $existing[$rule]['specificity']
    @@ -1777,9 +1777,9 @@ protected function bubbleCSS($element)
                         $existing[$rule] = $value;
                     }
                 }
    -            phpQuery::pq($element_child)->data('phpquery_css', $existing);
    -            if (phpQuery::pq($element_child)->children()->length) {
    -                $this->bubbleCSS(phpQuery::pq($element_child));
    +            PhpQuery::pq($element_child)->data('phpquery_css', $existing);
    +            if (PhpQuery::pq($element_child)->children()->length) {
    +                $this->bubbleCSS(PhpQuery::pq($element_child));
                 }
             }
         }
    @@ -1916,7 +1916,7 @@ public function click($callback = null)
         /**
          * Enter description here...
          *
    -     * @param String|phpQuery
    +     * @param String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapAllOld($wrapper)
    @@ -1936,14 +1936,14 @@ public function wrapAllOld($wrapper)
          * Enter description here...
          *
          * TODO testme...
    -     * @param String|phpQuery
    +     * @param String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapAll($wrapper)
         {
             if (!$this->length())
                 return $this;
    -        return phpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
    +        return PhpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
                 array(
                     $this,
                     '___wrapAllCallback'
    @@ -1971,7 +1971,7 @@ public function ___wrapAllCallback($node)
          *
          * @param $codeBefore
          * @param $codeAfter
    -     * @internal param $ String|phpQuery
    +     * @internal param $ String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapAllPHP($codeBefore, $codeAfter)
    @@ -1982,13 +1982,13 @@ public function wrapAllPHP($codeBefore, $codeAfter)
         /**
          * Enter description here...
          *
    -     * @param String|phpQuery
    +     * @param String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrap($wrapper)
         {
             foreach ($this->stack() as $node)
    -            phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
    +            PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
             return $this;
         }
     
    @@ -1997,26 +1997,26 @@ public function wrap($wrapper)
          *
          * @param $codeBefore
          * @param $codeAfter
    -     * @internal param $ String|phpQuery
    +     * @internal param $ String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapPHP($codeBefore, $codeAfter)
         {
             foreach ($this->stack() as $node)
    -            phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
    +            PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
             return $this;
         }
     
         /**
          * Enter description here...
          *
    -     * @param String|phpQuery
    +     * @param String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapInner($wrapper)
         {
             foreach ($this->stack() as $node)
    -            phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
    +            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
             return $this;
         }
     
    @@ -2025,13 +2025,13 @@ public function wrapInner($wrapper)
          *
          * @param $codeBefore
          * @param $codeAfter
    -     * @internal param $ String|phpQuery
    +     * @internal param $ String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function wrapInnerPHP($codeBefore, $codeAfter)
         {
             foreach ($this->stack(1) as $node)
    -            phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
    +            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
             return $this;
         }
     
    @@ -2180,13 +2180,13 @@ public function _clone()
          */
         public function replaceWithPHP($code)
         {
    -        return $this->replaceWith(phpQuery::php($code));
    +        return $this->replaceWith(PhpQuery::php($code));
         }
     
         /**
          * Enter description here...
          *
    -     * @param String|phpQuery $content
    +     * @param String|PhpQuery $content
          * @link http://docs.jquery.com/Manipulation/replaceWith#content
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
    @@ -2204,8 +2204,8 @@ public function replaceWith($content)
          */
         public function replaceAll($selector)
         {
    -        foreach (phpQuery::pq($selector, $this->getDocumentID()) as $node)
    -            phpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
    +        foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node)
    +            PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
             return $this;
         }
     
    @@ -2296,7 +2296,7 @@ public function markup($markup = null, $callback1 = null, $callback2 = null, $ca
          * @param null $callback2
          * @param null $callback3
          * @internal param $markup
    -     * @return unknown_type
    +     * @return string
          */
         public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
         {
    @@ -2326,7 +2326,7 @@ public function markupOuter($callback1 = null, $callback2 = null, $callback3 = n
          * @param null         $callback1
          * @param null         $callback2
          * @param null         $callback3
    -     * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
    +     * @return string|PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          * @TODO force html result
          */
         public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null)
    @@ -2359,7 +2359,7 @@ public function html($html = null, $callback1 = null, $callback2 = null, $callba
                 $return = $this->documentWrapper->markup($this->elements, true);
                 $args   = func_get_args();
                 foreach (array_slice($args, 1) as $callback) {
    -                $return = phpQuery::callbackRun(
    +                $return = PhpQuery::callbackRun(
                         $callback,
                         array(
                             $return
    @@ -2400,7 +2400,7 @@ public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = nul
             // pass thou callbacks
             $args = func_get_args();
             foreach ($args as $callback) {
    -            $markup = phpQuery::callbackRun(
    +            $markup = PhpQuery::callbackRun(
                     $callback,
                     array(
                         $markup
    @@ -2450,19 +2450,19 @@ public function php($code = null)
          */
         public function markupPHP($code = null)
         {
    -        return isset($code) ? $this->markup(phpQuery::php($code))
    -            : phpQuery::markupToPHP($this->markup());
    +        return isset($code) ? $this->markup(PhpQuery::php($code))
    +            : PhpQuery::markupToPHP($this->markup());
         }
     
         /**
          * Enter description here...
          *
          * @internal param $code
    -     * @return unknown_type
    +     * @return string PHP code
          */
         public function markupOuterPHP()
         {
    -        return phpQuery::markupToPHP($this->markupOuter());
    +        return PhpQuery::markupToPHP($this->markupOuter());
         }
     
         /**
    @@ -2594,7 +2594,7 @@ public function beforePHP($content)
         /**
          * Enter description here...
          *
    -     * @param String|phpQuery
    +     * @param String|PhpQuery
          * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
          */
         public function insertBefore($seletor)
    @@ -2661,7 +2661,7 @@ public function insert($target, $type)
                     if ($to) {
                         // INSERT TO
                         $insertFrom = $this->elements;
    -                    if (phpQuery::isMarkup($target)) {
    +                    if (PhpQuery::isMarkup($target)) {
                             // $target is new markup, import it
                             $insertTo = $this->documentWrapper->import($target);
                             // insert into selected element
    @@ -2680,7 +2680,7 @@ public function insert($target, $type)
                     break;
                 case 'object':
                     $insertFrom = $insertTo = array();
    -                // phpQuery
    +                // PhpQuery
                     if ($target instanceof self) {
                         if ($to) {
                             $insertTo = $target->elements;
    @@ -2738,7 +2738,7 @@ public function insert($target, $type)
                     }
                     break;
             }
    -        phpQuery::debug(
    +        PhpQuery::debug(
                 "From " . count($insertFrom) . "; To " . count($insertTo)
                 . " nodes"
             );
    @@ -2878,7 +2878,7 @@ public function text($text = null, $callback1 = null, $callback2 = null, $callba
                 if (count($this->elements) > 1 && $text)
                     $text .= "\n";
                 foreach ($args as $callback) {
    -                $text = phpQuery::callbackRun(
    +                $text = PhpQuery::callbackRun(
                         $callback,
                         array(
                             $text
    @@ -2914,7 +2914,7 @@ public function texts($attr = null)
          */
         public function plugin($class, $file = null)
         {
    -        phpQuery::plugin($class, $file);
    +        PhpQuery::plugin($class, $file);
             return $this;
         }
     
    @@ -2945,12 +2945,12 @@ public function __call($method, $args)
                 'clone',
                 'empty'
             );
    -        if (isset(phpQuery::$extendMethods[$method])) {
    +        if (isset(PhpQuery::$extendMethods[$method])) {
                 array_unshift($args, $this);
    -            return phpQuery::callbackRun(phpQuery::$extendMethods[$method], $args);
    -        } else if (isset(phpQuery::$pluginsMethods[$method])) {
    +            return PhpQuery::callbackRun(PhpQuery::$extendMethods[$method], $args);
    +        } else if (isset(PhpQuery::$pluginsMethods[$method])) {
                 array_unshift($args, $this);
    -            $class     = phpQuery::$pluginsMethods[$method];
    +            $class     = PhpQuery::$pluginsMethods[$method];
                 $realClass = "\\PhpQuery\\Plugin\\$class";
                 $return    = call_user_func_array(
                     array(
    @@ -3088,14 +3088,14 @@ public function siblings($selector = null)
         public function not($selector = null)
         {
             if (is_string($selector))
    -            phpQuery::debug(
    +            PhpQuery::debug(
                     array(
                         'not',
                         $selector
                     )
                 );
             else
    -            phpQuery::debug('not');
    +            PhpQuery::debug('not');
             $stack = array();
             if ($selector instanceof self || $selector instanceof \DOMNODE) {
                 foreach ($this->stack() as $node) {
    @@ -3144,7 +3144,7 @@ public function add($selector = null)
                 return $this;
             $stack                = array();
             $this->elementsBackup = $this->elements;
    -        $found                = phpQuery::pq($selector, $this->getDocumentID());
    +        $found                = PhpQuery::pq($selector, $this->getDocumentID());
             $this->merge($found->elements);
             return $this->newInstance();
         }
    @@ -3658,7 +3658,7 @@ public function each($callback, $param1 = null, $param2 = null, $param3 = null)
                 $paramStructure = array_slice($paramStructure, 1);
             }
             foreach ($this->elements as $v)
    -            phpQuery::callbackRun(
    +            PhpQuery::callbackRun(
                     $callback,
                     array(
                         $v
    @@ -3681,7 +3681,7 @@ public function callback($callback, $param1 = null, $param2 = null, $param3 = nu
         {
             $params    = func_get_args();
             $params[0] = $this;
    -        phpQuery::callbackRun($callback, $params);
    +        PhpQuery::callbackRun($callback, $params);
             return $this;
         }
     
    @@ -3709,12 +3709,12 @@ public function map($callback, $param1 = null, $param2 = null, $param3 = null)
             return $this->newInstance(
                 call_user_func_array(
                     array(
    -                    'phpQuery',
    +                    'PhpQuery',
                         'map'
                     ),
                     $params
                 )
    -        //			phpQuery::map($this->elements, $callback)
    +        //			PhpQuery::map($this->elements, $callback)
             );
         }
     
    @@ -3730,10 +3730,10 @@ public function data($key, $value = null)
             if (!isset($value)) {
                 // TODO? implement specific jQuery behavior od returning parent values
                 // is child which we look up doesn't exist
    -            return phpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
    +            return PhpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
             } else {
                 foreach ($this as $node)
    -                phpQuery::data($node, $key, $value, $this->getDocumentID());
    +                PhpQuery::data($node, $key, $value, $this->getDocumentID());
                 return $this;
             }
         }
    @@ -3747,7 +3747,7 @@ public function data($key, $value = null)
         public function removeData($key)
         {
             foreach ($this as $node)
    -            phpQuery::removeData($node, $key, $this->getDocumentID());
    +            PhpQuery::removeData($node, $key, $this->getDocumentID());
             return $this;
         }
         // INTERFACE IMPLEMENTATIONS
    @@ -3759,7 +3759,7 @@ public function removeData($key)
         public function rewind()
         {
             $this->debug('iterating foreach');
    -        //		phpQuery::selectDocument($this->getDocumentID());
    +        //		PhpQuery::selectDocument($this->getDocumentID());
             $this->elementsBackup    = $this->elements;
             $this->elementsInterator = $this->elements;
             $this->valid             = isset($this->elements[0]) ? 1 : 0;
    @@ -3946,8 +3946,8 @@ public function whois($oneNode = null)
          */
         public function dump()
         {
    -        print 'DUMP #' . (phpQuery::$dumpCount++) . ' ';
    -        phpQuery::$debug = false;
    +        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
    +        PhpQuery::$debug = false;
             //		print __FILE__.':'.__LINE__."\n";
             var_dump($this->htmlOuter());
             return $this;
    @@ -3955,34 +3955,34 @@ public function dump()
     
         public function dumpWhois()
         {
    -        print 'DUMP #' . (phpQuery::$dumpCount++) . ' ';
    -        $debug           = phpQuery::$debug;
    -        phpQuery::$debug = false;
    +        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
    +        $debug           = PhpQuery::$debug;
    +        PhpQuery::$debug = false;
             //		print __FILE__.':'.__LINE__."\n";
             var_dump('whois', $this->whois());
    -        phpQuery::$debug = $debug;
    +        PhpQuery::$debug = $debug;
             return $this;
         }
     
         public function dumpLength()
         {
    -        print 'DUMP #' . (phpQuery::$dumpCount++) . ' ';
    -        $debug           = phpQuery::$debug;
    -        phpQuery::$debug = false;
    +        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
    +        $debug           = PhpQuery::$debug;
    +        PhpQuery::$debug = false;
             //		print __FILE__.':'.__LINE__."\n";
             var_dump('length', $this->length());
    -        phpQuery::$debug = $debug;
    +        PhpQuery::$debug = $debug;
             return $this;
         }
     
         public function dumpTree($html = true, $title = true)
         {
    -        $output          = $title ? 'DUMP #' . (phpQuery::$dumpCount++) . " \n" : '';
    -        $debug           = phpQuery::$debug;
    -        phpQuery::$debug = false;
    +        $output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
    +        $debug           = PhpQuery::$debug;
    +        PhpQuery::$debug = false;
             foreach ($this->stack() as $node)
                 $output .= $this->__dumpTree($node);
    -        phpQuery::$debug = $debug;
    +        PhpQuery::$debug = $debug;
             print $html ? nl2br(str_replace(' ', ' ', $output)) : $output;
             return $this;
         }
    diff --git a/src/Plugin/Scripts.php b/src/Plugin/Scripts.php
    index 2aaeb07..43b8aee 100644
    --- a/src/Plugin/Scripts.php
    +++ b/src/Plugin/Scripts.php
    @@ -1,10 +1,10 @@
     
      */
    -use PhpQuery\PhpQuery as phpQuery;
    +use PhpQuery\PhpQuery;
     
    -phpQuery::ajaxAllowHost(
    +PhpQuery::ajaxAllowHost(
     	'code.google.com',
     	'google.com', 'www.google.com',
     	'mail.google.com',
    @@ -31,12 +31,12 @@ function ndfasui8923($browser, $scope) {
     		'config', 'self', 'return', 'params'
     	));
     }
    -phpQuery::plugin('WebBrowser');
    -$self->document->xhr = phpQuery::$plugins->browserGet(
    +PhpQuery::plugin('WebBrowser');
    +$self->document->xhr = PhpQuery::$plugins->browserGet(
     	'https://www.google.com/accounts/Login',
     	$ndfasui8923
     );
    -//$self->document->xhr = phpQuery::$plugins->browserGet('https://www.google.com/accounts/Login', create_function('$browser', "
    +//$self->document->xhr = PhpQuery::$plugins->browserGet('https://www.google.com/accounts/Login', create_function('$browser', "
     //	\$browser
     //		->WebBrowser()
     //		->find('#Email')
    diff --git a/src/Plugin/WebBrowser.php b/src/Plugin/WebBrowser.php
    index 1289714..756c222 100644
    --- a/src/Plugin/WebBrowser.php
    +++ b/src/Plugin/WebBrowser.php
    @@ -1,7 +1,7 @@
     document->xhr)
     			? $self->document->xhr
     			: null;
    -		$xhr = phpQuery::ajax(array(
    +		$xhr = PhpQuery::ajax(array(
     			'url' => $url,
     		), $xhr);
     		$return = false;
     		if ($xhr->getLastResponse()->isSuccessful()) {
     			$return = \PhpQuery\Plugin\UtilWebBrowser::browserReceive($xhr);
     			if (isset($self->document->WebBrowserCallback))
    -				phpQuery::callbackRun(
    +				PhpQuery::callbackRun(
     					$self->document->WebBrowserCallback,
     					array($return)
     				);
    @@ -98,14 +98,14 @@ public static function download($self, $url = null) {
                 $xhr = isset($self->document->xhr)
     			? $self->document->xhr
     			: null;
    -		$xhr = phpQuery::ajax(array(
    +		$xhr = PhpQuery::ajax(array(
     			'url' => $url,
     		), $xhr);
     		$return = false;
     		if ($xhr->getLastResponse()->isSuccessful()) {
     			$return = \PhpQuery\Plugin\UtilWebBrowser::browserDownload($xhr);
     			if (isset($self->document->WebBrowserCallback))
    -				phpQuery::callbackRun(
    +				PhpQuery::callbackRun(
     					$self->document->WebBrowserCallback,
     					array($return)
     				);
    @@ -126,9 +126,9 @@ class UtilWebBrowser {
          */
     	public static function browserGet($url, $callback,
     		$param1 = null, $param2 = null, $param3 = null) {
    -		phpQuery::debug("[WebBrowser] GET: $url");
    +		PhpQuery::debug("[WebBrowser] GET: $url");
     		self::authorizeHost($url);
    -		$xhr = phpQuery::ajax(array(
    +		$xhr = PhpQuery::ajax(array(
     			'type' => 'GET',
     			'url' => $url,
     			'dataType' => 'html',
    @@ -139,11 +139,11 @@ public static function browserGet($url, $callback,
     			$paramStructure = array_slice($paramStructure, 2);
     		}
     		if ($xhr->getLastResponse()->isSuccessful()) {
    -			phpQuery::callbackRun($callback,
    +			PhpQuery::callbackRun($callback,
     				array(self::browserReceive($xhr)->WebBrowser()),
     				$paramStructure
     			);
    -//			phpQuery::callbackRun($callback, array(
    +//			PhpQuery::callbackRun($callback, array(
     //				self::browserReceive($xhr)//->WebBrowser($callback)
     //			));
     			return $xhr;
    @@ -164,7 +164,7 @@ public static function browserGet($url, $callback,
     	public static function browserPost($url, $data, $callback,
     		$param1 = null, $param2 = null, $param3 = null) {
     		self::authorizeHost($url);
    -		$xhr = phpQuery::ajax(array(
    +		$xhr = PhpQuery::ajax(array(
     			'type' => 'POST',
     			'url' => $url,
     			'dataType' => 'html',
    @@ -176,11 +176,11 @@ public static function browserPost($url, $data, $callback,
     			$paramStructure = array_slice($paramStructure, 3);
     		}
     		if ($xhr->getLastResponse()->isSuccessful()) {
    -			phpQuery::callbackRun($callback,
    +			PhpQuery::callbackRun($callback,
     				array(self::browserReceive($xhr)->WebBrowser()),
     				$paramStructure
     			);
    -//			phpQuery::callbackRun($callback, array(
    +//			PhpQuery::callbackRun($callback, array(
     //				self::browserReceive($xhr)//->WebBrowser($callback)
     //			));
     			return $xhr;
    @@ -199,7 +199,7 @@ public static function browserPost($url, $data, $callback,
     	public static function browser($ajaxSettings, $callback,
     		$param1 = null, $param2 = null, $param3 = null) {
     		self::authorizeHost($ajaxSettings['url']);
    -		$xhr = phpQuery::ajax(
    +		$xhr = PhpQuery::ajax(
     			self::ajaxSettingsPrepare($ajaxSettings)
     		);
     		$paramStructure = null;
    @@ -208,11 +208,11 @@ public static function browser($ajaxSettings, $callback,
     			$paramStructure = array_slice($paramStructure, 2);
     		}
     		if ($xhr->getLastResponse()->isSuccessful()) {
    -			phpQuery::callbackRun($callback,
    +			PhpQuery::callbackRun($callback,
     				array(self::browserReceive($xhr)->WebBrowser()),
     				$paramStructure
     			);
    -//			phpQuery::callbackRun($callback, array(
    +//			PhpQuery::callbackRun($callback, array(
     //				self::browserReceive($xhr)//->WebBrowser($callback)
     //			));
     			return $xhr;
    @@ -222,7 +222,7 @@ public static function browser($ajaxSettings, $callback,
     	protected static function authorizeHost($url) {
     		$host = parse_url($url, PHP_URL_HOST);
     		if ($host)
    -			phpQuery::ajaxAllowHost($host);
    +			PhpQuery::ajaxAllowHost($host);
     	}
     	protected static function ajaxSettingsPrepare($settings) {
     		unset($settings['success']);
    @@ -233,7 +233,7 @@ protected static function ajaxSettingsPrepare($settings) {
     	 * @param \Zend_Http_Client $xhr
     	 */
     	public static function browserReceive($xhr) {
    -		phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
    +		PhpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
     		// TODO handle meta redirects
     		$body = $xhr->getLastResponse()->getBody();
     
    @@ -243,7 +243,7 @@ public static function browserReceive($xhr) {
     				.str_replace('', '', $body)
     				.'';
     		}
    -		$pq = phpQuery::newDocument($body);
    +		$pq = PhpQuery::newDocument($body);
     		$pq->document->xhr = $xhr;
     		$pq->document->location = $xhr->getUri(true);
     		$refresh = $pq->find('meta[http-equiv=refresh]')
    @@ -251,16 +251,16 @@ public static function browserReceive($xhr) {
     		if ($refresh->size()) {
     //			print htmlspecialchars(var_export($xhr->getCookieJar()->getAllCookies(), true));
     //			print htmlspecialchars(var_export($xhr->getLastResponse()->getHeader('Set-Cookie'), true));
    -			phpQuery::debug("Meta redirect... '{$refresh->attr('content')}'\n");
    +			PhpQuery::debug("Meta redirect... '{$refresh->attr('content')}'\n");
     			// there is a refresh, so get the new url
     			$content = $refresh->attr('content');
     			$urlRefresh = substr($content, strpos($content, '=')+1);
     			$urlRefresh = trim($urlRefresh, '\'"');
     			// XXX not secure ?!
    -			phpQuery::ajaxAllowURL($urlRefresh);
    +			PhpQuery::ajaxAllowURL($urlRefresh);
     //			$urlRefresh = urldecode($urlRefresh);
     			// make ajax call, passing last $xhr object to preserve important stuff
    -			$xhr = phpQuery::ajax(array(
    +			$xhr = PhpQuery::ajax(array(
     				'type' => 'GET',
     				'url' => $urlRefresh,
     				'dataType' => 'html',
    @@ -279,7 +279,7 @@ public static function browserReceive($xhr) {
     	 * @param Zend_Http_Client $xhr
     	 */
     	public static function browserDownload($xhr) {
    -		phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
    +		PhpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
     		// TODO handle meta redirects
     		$body = $xhr->getLastResponse()->getBody();
     
    @@ -291,21 +291,21 @@ public static function browserDownload($xhr) {
          * @param null $callback
          */
         public static function hadleClick($e, $callback = null) {
    -		$node = phpQuery::pq($e->target);
    +		$node = PhpQuery::pq($e->target);
     		$type = null;
     		if ($node->is('a[href]')) {
     			// TODO document.location
     			$xhr = isset($node->document->xhr)
     				? $node->document->xhr
     				: null;
    -			$xhr = phpQuery::ajax(array(
    +			$xhr = PhpQuery::ajax(array(
     				'url' => resolve_url($e->data[0], $node->attr('href')),
     				'referer' => $node->document->location,
     			), $xhr);
     			if ((! $callback || !($callback instanceof \Callback)) && $e->data[1])
     				$callback = $e->data[1];
     			if ($xhr->getLastResponse()->isSuccessful() && $callback)
    -				phpQuery::callbackRun($callback, array(
    +				PhpQuery::callbackRun($callback, array(
     					self::browserReceive($xhr)
     				));
     		} else if ($node->is(':submit') && $node->parents('form')->size())
    @@ -320,7 +320,7 @@ public static function hadleClick($e, $callback = null) {
          * @param null $callback
          */
     	public static function handleSubmit($e, $callback = null) {
    -		$node = phpQuery::pq($e->target);
    +		$node = PhpQuery::pq($e->target);
     		if (!$node->is('form') || !$node->is('[action]'))
     			return;
     		// TODO document.location
    @@ -348,11 +348,11 @@ public static function handleSubmit($e, $callback = null) {
     		);
     		if ($node->attr('enctype'))
     			$options['contentType'] = $node->attr('enctype');
    -		$xhr = phpQuery::ajax($options, $xhr);
    +		$xhr = PhpQuery::ajax($options, $xhr);
     		if ((! $callback || !($callback instanceof Callback)) && $e->data[1])
     			$callback = $e->data[1];
     		if ($xhr->getLastResponse()->isSuccessful() && $callback)
    -			phpQuery::callbackRun($callback, array(
    +			PhpQuery::callbackRun($callback, array(
     				self::browserReceive($xhr)
     			));
     	}
    diff --git a/src/Proxy/jQueryServer.php b/src/Proxy/jQueryServer.php
    index 260d6e4..3fc63a6 100755
    --- a/src/Proxy/jQueryServer.php
    +++ b/src/Proxy/jQueryServer.php
    @@ -1,12 +1,12 @@
     `
     
    @@ -30,7 +30,7 @@ class jQueryServer {
       public $allowedHosts = null;
       function __construct($data) {
         $pq = null;
    -    include_once(dirname(__FILE__) . '/../phpQuery/phpQuery.php');
    +    include_once(dirname(__FILE__) . '/../PhpQuery/PhpQuery.php');
         if (file_exists(dirname(__FILE__) . '/jQueryServer.config.php')) {
           include_once(dirname(__FILE__) . '/jQueryServer.config.php');
           if ($jQueryServerConfig)
    @@ -48,13 +48,13 @@ function __construct($data) {
             return;
           }
         }
    -    //		phpQueryClass::$debug = true;
    +    //		PhpQueryClass::$debug = true;
         //		if (! function_exists('json_decode')) {
         //			include_once(dirname(__FILE__).'/JSON.php');
         //			$this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
         //		}
         //		$data = $this->jsonDecode($data);
    -    $data = phpQuery::parseJSON($data);
    +    $data = PhpQuery::parseJSON($data);
         // load document (required for first $data element)
         if (is_array($data[0]) && isset($data[0]['url'])) {
           $this->options = $data[0];
    @@ -64,18 +64,18 @@ function __construct($data) {
             $this,
             'success'
           );
    -      phpQuery::ajax($ajax);
    +      PhpQuery::ajax($ajax);
         }
         else {
           throw new \Exception("URL needed to download content");
         }
       }
       public function success($response) {
    -    $pq = phpQuery::newDocument($response);
    +    $pq = PhpQuery::newDocument($response);
         foreach ($this->calls as $k => $r) {
           // check if method exists
           if (!method_exists(get_class($pq), $r['method'])) {
    -        throw new \Exception("Method '{$r['method']}' not implemented in phpQuery, sorry...");
    +        throw new \Exception("Method '{$r['method']}' not implemented in PhpQuery, sorry...");
             // execute method
           }
           else {
    @@ -93,10 +93,10 @@ public function success($response) {
               $results = array();
               foreach ($pq as $node)
                 $results[] = pq($node)->htmlOuter();
    -          print phpQuery::toJSON($results);
    +          print PhpQuery::toJSON($results);
             }
             else {
    -          print phpQuery::toJSON($pq);
    +          print PhpQuery::toJSON($pq);
             }
             break;
           default:
    diff --git a/src/Tests/BasicTest.php b/src/Tests/BasicTest.php
    index 84f8f4e..8587ae7 100644
    --- a/src/Tests/BasicTest.php
    +++ b/src/Tests/BasicTest.php
    @@ -1,6 +1,6 @@
     ')->find('.field1')->php('longlongtest');
    +    $pq = PhpQuery::newDocument('
  • ')->find('.field1')->php('longlongtest'); $validResult = '
  • longlongtestlonglongtest
  • '; similar_text($pq->htmlOuter(), $validResult, $similarity); @@ -154,7 +154,7 @@ function testSimpleDataInsertion($pq) {

    paragraph after UL

    EOF; - $expected_pq = phpQuery::newDocumentHTML($testResult); + $expected_pq = PhpQuery::newDocumentHTML($testResult); $rows = array( array( 'title' => 'News 1 title', @@ -192,12 +192,12 @@ function testSimpleDataInsertion($pq) { * @return void */ public function testCssParser() { - phpQuery::$enableCssShorthand = FALSE; + PhpQuery::$enableCssShorthand = FALSE; $expected_html = '
    Hello World!
    '; - $expected_pq = phpQuery::newDocumentHTML($expected_html); + $expected_pq = PhpQuery::newDocumentHTML($expected_html); - $test_pq = phpQuery::newDocumentHTML('
    '); + $test_pq = PhpQuery::newDocumentHTML('
    '); $test = pq('div'); $test->append('Hello World!'); $test->hide(); diff --git a/src/Tests/_archive/document_types.php b/src/Tests/_archive/document_types.php index 0123ad0..d28c2e4 100644 --- a/src/Tests/_archive/document_types.php +++ b/src/Tests/_archive/document_types.php @@ -11,7 +11,7 @@ * - document fragments tests (with all 4 charset scenarios) * */ -class phpQuery { +class PhpQuery { static $defaultDocumentID; static $debug = 0; static $documents = array(); @@ -22,7 +22,7 @@ static function debug($text) { } } require_once(__DIR__ . '/../../Dom/DOMDocumentWrapper.php'); -phpQuery::$debug = 2; +PhpQuery::$debug = 2; /* ENCODINGS */ //print ''; diff --git a/src/Tests/_archive/test_2.php b/src/Tests/_archive/test_2.php index 4b82993..d1a6ecd 100644 --- a/src/Tests/_archive/test_2.php +++ b/src/Tests/_archive/test_2.php @@ -1,20 +1,20 @@ find('p') - ->filter('.body:gt(1)'); -if ( $result->whois() == $testResult ) - print "Test '{$testName}' PASSED :)"; -else +); +$result = PhpQuery::newDocumentFile('test.html'); +$result = $result->find('p') + ->filter('.body:gt(1)'); +if ( $result->whois() == $testResult ) + print "Test '{$testName}' PASSED :)"; +else print "Test '{$testName}' FAILED !!! "; -print_r($result->whois()); +print_r($result->whois()); print "\n"; @@ -22,7 +22,7 @@ $testResult = array( 'p.body', ); -$testDOM = phpQuery::newDocumentFile('test.html'); +$testDOM = PhpQuery::newDocumentFile('test.html'); $single = $testDOM->find('p')->filter('.body') ->add( $testDOM->find('p')->filter('.title') @@ -43,10 +43,10 @@ $testName = 'Attributes in HTML element'; $validResult = 'testValue'; -$result = phpQuery::newDocumentFile('test.html')->find('html') +$result = PhpQuery::newDocumentFile('test.html')->find('html') ->empty() ->attr('test', $validResult); -$result = phpQuery::newDocument($result->htmlOuter())->find('html') +$result = PhpQuery::newDocument($result->htmlOuter())->find('html') ->attr('test'); //similar_text($result->htmlOuter(), $validResult, $similarity); if ( $result == $validResult ) diff --git a/src/Tests/_archive/test_4.php b/src/Tests/_archive/test_4.php index f54515c..f78f4e9 100755 --- a/src/Tests/_archive/test_4.php +++ b/src/Tests/_archive/test_4.php @@ -1,12 +1,12 @@ find('li') ->slice(1, 2); if ( $result->whois() == $testResult ) @@ -26,7 +26,7 @@ 'li#i_have_nested_list', 'li.nested', ); -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('li') ->slice(1, -1); if ( $result->whois() == $testResult ) @@ -40,7 +40,7 @@ print "\n"; // Multi-insert -$result = phpQuery::newDocument('
  • ') +$result = PhpQuery::newDocument('
  • ') ->find('.field1') ->php('longlongtest'); $validResult = '
  • longlongtestlonglongtest
  • '; @@ -57,7 +57,7 @@ // INDEX $testResult = 1; -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('p') ->index(pq('p.title:first')); if ( $result == $testResult ) @@ -71,7 +71,7 @@ $testName = 'Clone'; $testResult = 3; $document; -$p = phpQuery::newDocumentFile('test.html') +$p = PhpQuery::newDocumentFile('test.html') ->toReference($document) ->find('p:first'); foreach(array(0,1,2) as $i) { @@ -91,7 +91,7 @@ $testName = 'Next'; $testResult = 3; $document; -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('li:first') ->next() ->next() diff --git a/src/Tests/_archive/test_5.php b/src/Tests/_archive/test_5.php index 13a7c44..aaf96ec 100755 --- a/src/Tests/_archive/test_5.php +++ b/src/Tests/_archive/test_5.php @@ -1,6 +1,6 @@ find('li') ->each($test); $testName = is_array($test) diff --git a/src/Tests/_archive/test_ajax.php b/src/Tests/_archive/test_ajax.php index 5058e58..1c08d5a 100755 --- a/src/Tests/_archive/test_ajax.php +++ b/src/Tests/_archive/test_ajax.php @@ -5,19 +5,19 @@ .'zend-framework/' ); -require_once('../phpQuery/phpQuery.php'); -phpQuery::$debug = true; -phpQuery::$ajaxAllowedHosts[] = 'wikipedia.org'; -phpQuery::$ajaxAllowedHosts[] = 'google.com'; -phpQuery::$ajaxAllowedHosts[] = 'code.google.com'; -phpQuery::$ajaxAllowedHosts[] = 'www.google.com'; +require_once('../PhpQuery/PhpQuery.php'); +PhpQuery::$debug = true; +PhpQuery::$ajaxAllowedHosts[] = 'wikipedia.org'; +PhpQuery::$ajaxAllowedHosts[] = 'google.com'; +PhpQuery::$ajaxAllowedHosts[] = 'code.google.com'; +PhpQuery::$ajaxAllowedHosts[] = 'www.google.com'; -//$pq = phpQuery::ajax(array( +//$pq = PhpQuery::ajax(array( // 'url' => 'http://wikipedia.org/', // 'success' => 'v87shs79d8fhs9d' //)); //function v87shs79d8fhs9d($html) { -// $title = phpQuery::newDocument($html)->find('title'); +// $title = PhpQuery::newDocument($html)->find('title'); // $testName = 'Simple AJAX'; // if ( strpos(strtolower($title->html()), 'wikipedia') !== false ) // print "Test '$testName' PASSED :)"; @@ -32,7 +32,7 @@ $testName = 'Load'; -$test = phpQuery::newDocumentFile('test.html') +$test = PhpQuery::newDocumentFile('test.html') ->find('div:first') ->load('http://wikipedia.org/ div[lang]'); if (pq('div[lang]')->size()) @@ -46,7 +46,7 @@ // http://code.google.com/p/phpquery/issues/detail?id=130 -$pq = phpQuery::ajax(array( +$pq = PhpQuery::ajax(array( 'url' => 'http://'.$_SERVER['SERVER_NAME'].preg_replace('@/[^/]+$@', '/test_ajax_data_1', $_SERVER['REQUEST_URI']), 'success' => 'a789fhasdui3124', 'error' => 'jhdbg786213u8dsfg7y' @@ -68,10 +68,10 @@ function jhdbg786213u8dsfg7y() { //$testName = 'gdata plugin'; -//phpQuery::extend('gdata'); -//$xhr = phpQuery::$plugins->gdata('tobiasz.cudnik@gmail.com', 'XXX'); +//PhpQuery::extend('gdata'); +//$xhr = PhpQuery::$plugins->gdata('tobiasz.cudnik@gmail.com', 'XXX'); //$url = 'http://code.google.com/p/phpquery/w/edit/Callbacks'; -//phpQuery::ajax(array('url' => $url, 'success' => 'ksjsdgh892jh23'), $xhr); +//PhpQuery::ajax(array('url' => $url, 'success' => 'ksjsdgh892jh23'), $xhr); //function ksjsdgh892jh23($html) { // print $html; // print pq($html)->find('script')->remove()->end(); diff --git a/src/Tests/_archive/test_arrayaccess.php b/src/Tests/_archive/test_arrayaccess.php index fb31098..b56dd31 100755 --- a/src/Tests/_archive/test_arrayaccess.php +++ b/src/Tests/_archive/test_arrayaccess.php @@ -5,9 +5,9 @@ .':/home/bob/Sources/PHP/zend-framework/' ); -require_once('../phpQuery/phpQuery.php'); -phpQuery::$debug = true; -$testHtml = phpQuery::newDocumentFile('test.html'); +require_once('../PhpQuery/PhpQuery.php'); +PhpQuery::$debug = true; +$testHtml = PhpQuery::newDocumentFile('test.html'); $testHtml['li:first']->append('test'); $testName = 'Array Access get'; if (trim($testHtml['.just-added']->html()) == 'test') @@ -20,9 +20,9 @@ } print "\n"; -require_once('../phpQuery/phpQuery.php'); -phpQuery::$debug = true; -$testHtml = phpQuery::newDocumentFile('test.html'); +require_once('../PhpQuery/PhpQuery.php'); +PhpQuery::$debug = true; +$testHtml = PhpQuery::newDocumentFile('test.html'); $testHtml['li:first'] = 'new inner html'; $testName = 'Array Access set'; if (trim($testHtml['li:first']->html()) == 'new inner html') diff --git a/src/Tests/_archive/test_attr.php b/src/Tests/_archive/test_attr.php index 4e808c0..8ca6106 100644 --- a/src/Tests/_archive/test_attr.php +++ b/src/Tests/_archive/test_attr.php @@ -1,10 +1,10 @@ find('p[rel]:first') ->attr('rel', $expected); if ($result->attr('rel') == $expected) @@ -16,7 +16,7 @@ $testName = 'Attribute change in iteration'; $expected = 'new attr value'; -$doc = phpQuery::newDocumentFile('test.html'); +$doc = PhpQuery::newDocumentFile('test.html'); foreach($doc['p[rel]:first'] as $p) pq($p)->attr('rel', $expected); if ($doc['p[rel]:first']->attr('rel') == $expected) diff --git a/src/Tests/_archive/test_callback.php b/src/Tests/_archive/test_callback.php index d38df8a..31527f2 100644 --- a/src/Tests/_archive/test_callback.php +++ b/src/Tests/_archive/test_callback.php @@ -2,8 +2,8 @@ //if (PHP_VERSION < 5.3) // throw new \Exception("This test case is only for PHP 5.3 and above."); require('/home/bob/Sources/php/simpletest/simpletest/trunk/autorun.php'); -require_once('../phpQuery/phpQuery.php'); -phpQuery::$debug = true; +require_once('../PhpQuery/PhpQuery.php'); +PhpQuery::$debug = true; class CallbackTest extends UnitTestCase { public function callback2() { @@ -17,8 +17,8 @@ public function testExtend() { 'newMethod1' => array($this, 'callback1'), 'newMethod2' => array($this, 'callback2'), ); - phpQuery::extend('PhpQueryObject', $newMethods); - $doc = phpQuery::newDocumentXML("
    "); + PhpQuery::extend('PhpQueryObject', $newMethods); + $doc = PhpQuery::newDocumentXML("
    "); $this->assertTrue($doc->newMethod1() == $doc, '$doc->newMethod1 == $doc'); $this->assertTrue($doc->newMethod2() == "callback2", diff --git a/src/Tests/_archive/test_charset.php b/src/Tests/_archive/test_charset.php index a0b4768..ee65d12 100644 --- a/src/Tests/_archive/test_charset.php +++ b/src/Tests/_archive/test_charset.php @@ -1,10 +1,10 @@ find('li:first') ->find('p:first') ->html('żźć'); @@ -15,7 +15,7 @@ print "\n"; $testName = 'Text node HTML entite append'; -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('li:first') ->find('p:first') ->_empty() @@ -29,7 +29,7 @@ print "\n"; $testName = 'DOMElement node HTML entite append'; -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('li:first') ->find('p:first') ->empty() @@ -43,7 +43,7 @@ print "\n"; $testName = 'Append and move'; -$result = phpQuery::newDocumentFile('test.html'); +$result = PhpQuery::newDocumentFile('test.html'); $li = $result->find('li:first'); $result->find('div')->_empty(); $li->html('test1-é-test1') @@ -62,7 +62,7 @@ print "\n"; $testName = 'Attr charset'; -$result = phpQuery::newDocumentFile('test.html') +$result = PhpQuery::newDocumentFile('test.html') ->find('li:first') ->attr('test', 'foo é żźć bar'); if (trim($result->attr('test')) == 'foo é żźć bar') @@ -75,10 +75,10 @@ //$testName = 'Loading document without meta charset'; -//$result = phpQuery::newDocumentFile('test.html') +//$result = PhpQuery::newDocumentFile('test.html') // ->_empty(); ////var_dump((string)$result->htmlOuter()); -//$result = phpQuery::newDocument($result->htmlOuter()); +//$result = PhpQuery::newDocument($result->htmlOuter()); //$validResult = << // diff --git a/src/Tests/_archive/test_document.php b/src/Tests/_archive/test_document.php index 24c2cc5..f46f33e 100644 --- a/src/Tests/_archive/test_document.php +++ b/src/Tests/_archive/test_document.php @@ -1,20 +1,20 @@ find('li:first')->html('foo

    bar

    foo foo')->html(); die(); -$testResult = 10; -if ($doc->script('example', 'p')->length == $testResult) - print "Test '$testName' PASSED :)"; -else { +$testResult = 10; +if ($doc->script('example', 'p')->length == $testResult) + print "Test '$testName' PASSED :)"; +else { print "Test '$testName' FAILED !!! "; print "
    ";
    -	var_dump($doc->whois());
    +	var_dump($doc->whois());
     	print "
    \n"; } print "\n"; \ No newline at end of file diff --git a/src/Tests/_archive/test_events.php b/src/Tests/_archive/test_events.php index f4ebcd9..adc225f 100755 --- a/src/Tests/_archive/test_events.php +++ b/src/Tests/_archive/test_events.php @@ -1,6 +1,6 @@ @@ -13,7 +13,7 @@ EOF; -$doc = phpQuery::newDocumentHTML($form); +$doc = PhpQuery::newDocumentHTML($form); $inputs = $doc['form > *']; // creates array from input names // $results = $inputs->get(null, diff --git a/src/Tests/_archive/test_insert.php b/src/Tests/_archive/test_insert.php index ff2e7e2..efd33cf 100644 --- a/src/Tests/_archive/test_insert.php +++ b/src/Tests/_archive/test_insert.php @@ -1,12 +1,12 @@ find('step'); print $doc->find('p'); $markup = "test
    test

    test p

    "; diff --git a/src/Tests/_archive/test_manipulation.php b/src/Tests/_archive/test_manipulation.php index 8ef5173..d116ae7 100644 --- a/src/Tests/_archive/test_manipulation.php +++ b/src/Tests/_archive/test_manipulation.php @@ -1,6 +1,6 @@ 'News 3 body', ), ); -phpQuery::newDocumentFile('test.html'); +PhpQuery::newDocumentFile('test.html'); $articles = pq('.articles ul'); $rowSrc = $articles->find('li') ->remove() @@ -69,7 +69,7 @@ $testName = 'Parent && children'; -$result = phpQuery::newDocumentFile('test.html'); +$result = PhpQuery::newDocumentFile('test.html'); $parent = $result->find('ul:first'); $children = $parent->find('li:first'); $e = null; @@ -85,7 +85,7 @@ $testName = 'HTML insertion'; -$doc = phpQuery::newDocument('

    '); +$doc = PhpQuery::newDocument('

    '); $string = "La Thermo-sonde de cuisson vous permet de cuire à la perfection au four comme au bain-marie. Température: entre 0°C et 210°C."; $doc->find('p')->html($string); if (pq('p')->length == 1) @@ -98,7 +98,7 @@ $testName = 'HTML insertion 2'; -$doc = phpQuery::newDocument('

    '); +$doc = PhpQuery::newDocument('

    '); $string = "
    La Thermo-sonde de cuisson vous permet de cuire à la perfection au four comme au bain-marie. Température: entre 0°C et 210°C.
    "; $doc->find('p')->html($string); if (pq('div')->length == 2) { @@ -111,7 +111,7 @@ $testName = 'HTML insertion 3'; -$doc = phpQuery::newDocument('

    '); +$doc = PhpQuery::newDocument('

    '); $string = 'Hors paragraphe.

    Éditorial de l\'institution Saint-Pierre.

    @@ -130,7 +130,7 @@ $testName = 'Text insertion'; -$doc = phpQuery::newDocument('

    '); +$doc = PhpQuery::newDocument('

    '); $string = "La Thermo-sonde de cuisson vous permet de cuire à la perfection au four comme au bain-marie"; $doc->find('p')->html($string); if (trim(pq('p:first')->html()) == $string) diff --git a/src/Tests/_archive/test_manual.php b/src/Tests/_archive/test_manual.php index fe81cc7..dd6d300 100644 --- a/src/Tests/_archive/test_manual.php +++ b/src/Tests/_archive/test_manual.php @@ -1,24 +1,24 @@

    p

    '); +//$doc = PhpQuery::newDocumentXML('

    p

    '); //print $doc['article']->children(':empty')->get(0)->tagName; -//$doc = phpQuery::newDocumentFile('test.html'); +//$doc = PhpQuery::newDocumentFile('test.html'); //setlocale(LC_ALL, 'pl_PL.UTF-8'); //$string = strftime('%B %Y', time()); //$doc['p:first']->append($string)->dump(); /* * -$doc1 = phpQuery::newDocumentFileXHTML('doc1.html'); -$doc2 = phpQuery::newDocumentFileXHTML('doc2.html'); -$doc3 = phpQuery::newDocumentFileXHTML('doc3.html'); -$doc4 = phpQuery::newDocumentFileXHTML('doc4.html'); +$doc1 = PhpQuery::newDocumentFileXHTML('doc1.html'); +$doc2 = PhpQuery::newDocumentFileXHTML('doc2.html'); +$doc3 = PhpQuery::newDocumentFileXHTML('doc3.html'); +$doc4 = PhpQuery::newDocumentFileXHTML('doc4.html'); $doc2['body'] ->append($doc3['body >*']) ->append($doc4['body >*']); @@ -26,13 +26,13 @@ ->append($doc2['body >*']); print $doc1->plugin('Scripts')->script('safe_print'); */ -//$doc = phpQuery::newDocument('

    p1 b1 b2

    p2

    '); +//$doc = PhpQuery::newDocument('

    p1 b1 b2

    p2

    '); //print $doc['p']->contents()->not('[nodeType=1]'); -//print phpQuery::newDocumentFileXML('tmp.xml'); +//print PhpQuery::newDocumentFileXML('tmp.xml'); -//$doc = phpQuery::newDocumentXML('textnodetest'); +//$doc = PhpQuery::newDocumentXML('textnodetest'); //pq('

    ', $doc)->insertBefore(pq('node'))->append(pq('node')); //$doc->contents()->wrap('

    '); //$doc['node']->wrapAll('

    '); @@ -41,29 +41,29 @@ //print $doc; // http://code.google.com/p/phpquery/issues/detail?id=66 -//$doc = phpQuery::newDocumentXML('

    123123

    '); +//$doc = PhpQuery::newDocumentXML('

    123123

    '); //$doc->dump(); //$doc->children()->wrapAll('
    ')->dump(); // http://code.google.com/p/phpquery/issues/detail?id=69 -//$doc = phpQuery::newDocumentXML('

    123123

    '); +//$doc = PhpQuery::newDocumentXML('

    123123

    '); //$doc['[class^="test"]']->dump(); // http://code.google.com/p/phpquery/issues/detail?id=71 -// $doc = phpQuery::newDocument(''); +// $doc = PhpQuery::newDocument(''); // print $doc['input']->val('new')->val(); // http://code.google.com/p/phpquery/issues/detail?id=71 -// $doc = phpQuery::newDocument(''); +// $doc = PhpQuery::newDocument(''); // $doc['select']->val('20')->dump(); // http://code.google.com/p/phpquery/issues/detail?id=73 -// $doc = phpQuery::newDocument(''); +// $doc = PhpQuery::newDocument(''); // var_dump($doc['input']->val(0)->val()); // $a = null; // new CallbackReference($a); -// phpQuery::callbackRun(new CallbackReference($a), array('new $a value')); +// PhpQuery::callbackRun(new CallbackReference($a), array('new $a value')); // var_dump($a); // check next() inside (also, but separatly) @@ -74,23 +74,23 @@ // http://code.google.com/p/phpquery/issues/detail?id=74 // http://code.google.com/p/phpquery/issues/detail?id=31 -//$doc = phpQuery::newDocument('
    '); +//$doc = PhpQuery::newDocument('
    '); //$doc['div']->filter('.class1, .class2')->dump()->dumpWhois(); // http://code.google.com/p/phpquery/issues/detail?id=76 // mb_internal_encoding("UTF-8"); // mb_regex_encoding("UTF-8"); -// $xml = phpQuery::newDocumentXML('<документа/>'); +// $xml = PhpQuery::newDocumentXML('<документа/>'); // // $xml['документа']->append('<список>'); // $xml['документа список'] = '<эл>1<эл>2<эл>3'; // print "$xml"; // zeromski 0.9.5 vs 0.9.1 -// phpQuery::newDocumentXML('')->dump(); +// PhpQuery::newDocumentXML('')->dump(); // http://code.google.com/p/phpquery/issues/detail?id=77 -// phpQuery::newDocumentFile('http://google.com/') +// PhpQuery::newDocumentFile('http://google.com/') // ->find('body > *')->dumpWhois(); /*$XHTML = << EOF; -phpQuery::newDocumentXHTML($XHTML) +PhpQuery::newDocumentXHTML($XHTML) ->find('body:first > *')->dumpWhois();*/ // http://code.google.com/p/phpquery/issues/detail?id=83 -//$doc = phpQuery::newDocument('
    '); //print $doc['[name=toto]']->val('1'); -//$doc = phpQuery::newDocumentFile('http://www.google.pl/search?hl=en&q=test&btnG=Google+Search'); +//$doc = PhpQuery::newDocumentFile('http://www.google.pl/search?hl=en&q=test&btnG=Google+Search'); //print $doc; // http://code.google.com/p/phpquery/issues/detail?id=88 -//$doc = phpQuery::newDocumentXML(''); +//$doc = PhpQuery::newDocumentXML(''); //$doc['foo']->find('bar')->andSelf()->addClass('test'); //$doc->dump(); // http://code.google.com/p/phpquery/issues/detail?id=90 -//print phpQuery::newDocument('') +//print PhpQuery::newDocument('') // ->find('body') // ->load('http://localhost/phpinfo.php'); // http://code.google.com/p/phpquery/issues/detail?id=91 -// phpQuery::newDocumentXML(''); +// PhpQuery::newDocumentXML(''); // print pq('foo')->filter('[bar$=c]'); // FIXME http://code.google.com/p/phpquery/issues/detail?id=93 @@ -181,11 +181,11 @@ // //blah //'; -//$pq = phpQuery::newDocument($doc); +//$pq = PhpQuery::newDocument($doc); //echo $pq; # http://code.google.com/p/phpquery/issues/detail?id=94#makechanges -//$doc = phpQuery::newDocument(); +//$doc = PhpQuery::newDocument(); //$test = pq( //' //
  • @@ -199,11 +199,11 @@ //); // http://code.google.com/p/phpquery/issues/detail?id=96 -//$doc = phpQuery::newDocument(''); -//$doc = phpQuery::newDocument(''); @@ -218,12 +218,12 @@ //(16:30:20) jomofcw: the value of $section['libelle'] is exactly "3°" in database... # http://code.google.com/p/phpquery/issues/detail?id=98 -//$doc = phpQuery::newDocument(''); //print $doc['select']->val(0)->end()->script('print_source'); // http://groups.google.com/group/phpquery/browse_thread/thread/1c78f7e41fc5808c?hl=en -//$doc = phpQuery::newDocumentXML(" +//$doc = PhpQuery::newDocumentXML(" // // // '?'), 'jsonSuccess'); +//PhpQuery::ajaxAllowHost('api.flickr.com'); +//PhpQuery::getJSON($url, array('jsoncallback' => '?'), 'jsonSuccess'); //var_dump(json_decode($json)); -//require_once('../phpQuery/Zend/Json/Decoder.php'); +//require_once('../PhpQuery/Zend/Json/Decoder.php'); //var_dump(Zend_Json_Decoder::decode($json)); -#var_dump(''.phpQuery::newDocumentFile("http://www.chefkoch.de/magazin/artikel/943,0/AEG-Electrolux/Frischer-Saft-aus-dem-Dampfgarer.html")); -// var_dump(phpQuery::newDocument( +#var_dump(''.PhpQuery::newDocumentFile("http://www.chefkoch.de/magazin/artikel/943,0/AEG-Electrolux/Frischer-Saft-aus-dem-Dampfgarer.html")); +// var_dump(PhpQuery::newDocument( // str_replace(' // ', '', // file_get_contents("http://www.chefkoch.de/magazin/artikel/943,0/AEG-Electrolux/Frischer-Saft-aus-dem-Dampfgarer.html" // )))); // http://code.google.com/p/phpquery/issues/detail?id=102 -// $doc = phpQuery::newDocumentFileHTML('http://www.google.de'); -// //$doc = phpQuery::newDocument(''); +// $doc = PhpQuery::newDocumentFileHTML('http://www.google.de'); +// //$doc = PhpQuery::newDocument(''); // $images = $doc['img']->dump(); // // $foo = 'aaa'; @@ -272,20 +272,20 @@ // var_dump(preg_match('@^[\w|\||-]+$@', $foo) || $foo == '*'); // http://code.google.com/p/phpquery/issues/detail?id=67 -//$doc = phpQuery::newDocumentXML(""); +//$doc = PhpQuery::newDocumentXML(""); //$doc['node1']->data('foo', 'bar'); //var_dump($doc['node1']->data('foo')); //$doc['node1']->removeData('foo'); //var_dump($doc['node1']->data('foo')); //$doc['node1']->data('foo.bar', 'bar'); //var_dump($doc['node1']->data('foo.bar')); -//var_dump(phpQuery::$documents[$doc->getDocumentID()]->data); +//var_dump(PhpQuery::$documents[$doc->getDocumentID()]->data); // xhtml fragments -//$doc = phpQuery::newDocumentXHTML("


    "); +//$doc = PhpQuery::newDocumentXHTML("


    "); //print $doc; -$doc = phpQuery::newDocument('
    '); +$doc = PhpQuery::newDocument('
    '); //$content_string = str_repeat('a', 99988); $content_string = str_repeat(str_repeat('a', 350)."\n", 350); //var_dump(strlen($content_string)); diff --git a/src/Tests/_archive/test_multidoc.php b/src/Tests/_archive/test_multidoc.php index dc30e42..ed5f9df 100644 --- a/src/Tests/_archive/test_multidoc.php +++ b/src/Tests/_archive/test_multidoc.php @@ -1,13 +1,13 @@ find('p') as $node) $doc2->find('body')->append(pq($node)); @@ -23,8 +23,8 @@ $testResult = array( 'p.body', ); -$doc1 = phpQuery::newDocumentFile('test.html'); -$doc2 = phpQuery::newDocumentFile('test.html'); +$doc1 = PhpQuery::newDocumentFile('test.html'); +$doc2 = PhpQuery::newDocumentFile('test.html'); foreach ($doc1->find('p') as $node) $doc2->find('body')->append($node); $testResult = $doc2->find('p'); diff --git a/src/Tests/_archive/test_php.php b/src/Tests/_archive/test_php.php index 728cb9f..c862410 100644 --- a/src/Tests/_archive/test_php.php +++ b/src/Tests/_archive/test_php.php @@ -1,13 +1,13 @@ "> EOF; -$result = phpQuery::newDocumentPHP(null, 'text/html;charset=utf-8') +$result = PhpQuery::newDocumentPHP(null, 'text/html;charset=utf-8') ->appendPHP('print $r') ->append('') ->find('a') @@ -20,7 +20,7 @@ print "\n"; $testName = 'PHP file open'; -$result = phpQuery::newDocumentFilePHP('document-types/document-utf8.php'); +$result = PhpQuery::newDocumentFilePHP('document-types/document-utf8.php'); var_dump($result->php()); /* ->appendPHP('print $r') diff --git a/src/Tests/_archive/test_replace.php b/src/Tests/_archive/test_replace.php index bd96eaa..23b6597 100644 --- a/src/Tests/_archive/test_replace.php +++ b/src/Tests/_archive/test_replace.php @@ -1,9 +1,9 @@ find('p:eq(1)') ->replaceWith("

    this is example title @@ -20,7 +20,7 @@ $testName = 'ReplaceAll'; $testResult = 3; -phpQuery::newDocumentFile('test.html'); +PhpQuery::newDocumentFile('test.html'); pq('

    ') ->replaceAll('li:first p'); $result = pq('.replacer'); diff --git a/src/Tests/_archive/test_scripts.php b/src/Tests/_archive/test_scripts.php index 490e309..2ba1970 100644 --- a/src/Tests/_archive/test_scripts.php +++ b/src/Tests/_archive/test_scripts.php @@ -1,19 +1,19 @@ script('example', 'p')->length == $testResult) - print "Test '$testName' PASSED :)"; -else { +$doc = PhpQuery::newDocumentFile('test.html'); +$testResult = 10; +if ($doc->script('example', 'p')->length == $testResult) + print "Test '$testName' PASSED :)"; +else { print "Test '$testName' FAILED !!! "; print "
    ";
    -	var_dump($doc->whois());
    +	var_dump($doc->whois());
     	print "
    \n"; } print "\n"; @@ -22,8 +22,8 @@ $testName = 'Scripts/gmail_login'; $testResult = 1; $url = 'http://code.google.com/p/phpquery/w/edit/MultiDocumentSupport'; -//phpQuery::ajaxAllowURL($url); -$editor = phpQuery::newDocument('
    ') +//PhpQuery::ajaxAllowURL($url); +$editor = PhpQuery::newDocument('
    ') ->script('google_login') ->location($url); if ($editor->find('textarea#content')->length == $testResult) @@ -34,5 +34,5 @@ var_dump($doc->whois()); print "\n"; } -print "\n"; +print "\n"; ?> \ No newline at end of file diff --git a/src/Tests/_archive/test_selectors.php b/src/Tests/_archive/test_selectors.php index 2332d1a..ef0ef89 100644 --- a/src/Tests/_archive/test_selectors.php +++ b/src/Tests/_archive/test_selectors.php @@ -1,91 +1,91 @@ $test ) { - $tests[ $k ][2] = pq( $test[0] )->whois(); -} -foreach( $tests as $test ) { - if ( $test[1] == $test[2] ) - print "Test '{$test[0]}' PASSED :)"; - else { - print "Test '{$test[0]}' FAILED !!!"; - print_r($test[2]); - } - print "

    "; +// ), +); + +PhpQuery::newDocumentFile('test.html'); +foreach( $tests as $k => $test ) { + $tests[ $k ][2] = pq( $test[0] )->whois(); +} +foreach( $tests as $test ) { + if ( $test[1] == $test[2] ) + print "Test '{$test[0]}' PASSED :)"; + else { + print "Test '{$test[0]}' FAILED !!!"; + print_r($test[2]); + } + print "

    "; } // $testName = 'Complicated selector 1'; -phpQuery::newDocumentFile('test.html'); +PhpQuery::newDocumentFile('test.html'); pq('') ->appendTo('body'); $result = pq('select[name="test[]"]:has(option[value=3])'); @@ -298,5 +298,5 @@ else print "Test '{$testName}' FAILED !!! "; $result->dump(); -print "\n"; +print "\n"; ?> \ No newline at end of file diff --git a/src/Tests/_archive/test_webbrowser.php b/src/Tests/_archive/test_webbrowser.php index e15054e..d9f93de 100755 --- a/src/Tests/_archive/test_webbrowser.php +++ b/src/Tests/_archive/test_webbrowser.php @@ -1,17 +1,17 @@ browserGet('http://google.com/', 'success1'); + PhpQuery::$plugins->browserGet('http://google.com/', 'success1'); /** * * @param $pq PhpQueryObject @@ -22,7 +22,7 @@ function success1($pq) { $pq ->WebBrowser('success2') ->find('input[name=q]') - ->val('phpQuery') + ->val('PhpQuery') ->parents('form') ->submit() ; @@ -41,8 +41,8 @@ function success2($pq) { // Gmail login (not working...) if (0) { - phpQuery::plugin("Scripts"); - phpQuery::newDocument('
    ') + PhpQuery::plugin("Scripts"); + PhpQuery::newDocument('
    ') ->script('google_login') ->location('http://mail.google.com/') ->toReference($pq); @@ -55,7 +55,7 @@ function success2($pq) { if (0) { $browser = null; $browserCallback = new CallbackReference($browser); - phpQuery::browserGet('http://mail.google.com/', $browserCallback); + PhpQuery::browserGet('http://mail.google.com/', $browserCallback); if ($browser) { $browser ->WebBrowser($browserCallback) diff --git a/src/Tests/_archive/test_wrap.php b/src/Tests/_archive/test_wrap.php index b845580..bd67ba5 100644 --- a/src/Tests/_archive/test_wrap.php +++ b/src/Tests/_archive/test_wrap.php @@ -1,9 +1,9 @@ find('p') ->slice(1, 3); $p->wrap('
    '); @@ -23,7 +23,7 @@ $testName = 'WrapAll'; $testResult = 1; -phpQuery::newDocumentFile('test.html') +PhpQuery::newDocumentFile('test.html') ->find('p') ->slice(1, 3) ->wrapAll('
    '); @@ -39,7 +39,7 @@ $testName = 'WrapInner'; $testResult = 3; -phpQuery::newDocumentFile('test.html') +PhpQuery::newDocumentFile('test.html') ->find('li:first') ->wrapInner('
    '); $result = pq('.wrapper p'); @@ -54,7 +54,7 @@ // TODO ! $testName = 'WrapAllTest'; /* -$doc = phpQuery::newDocumentHTML('
    '); +$doc = PhpQuery::newDocumentHTML('
    '); $doc['#myDiv']->append('hors paragraphe

    Test

    hors paragraphe') ->contents() ->not('[nodeType=1]') @@ -62,7 +62,7 @@ var_dump((string)$doc); */ //$testResult = 3; -//phpQuery::newDocumentFile('test.html') +//PhpQuery::newDocumentFile('test.html') // ->find('li:first') // ->wrapInner('
    '); //$result = pq('.wrapper p'); From addaee2acfb7b6565bc19aa2cf3749be4c8bccda Mon Sep 17 00:00:00 2001 From: "Oleg Mikhailov (miholeus)" Date: Tue, 9 Sep 2014 12:31:13 +0400 Subject: [PATCH 52/59] map fix function --- src/PhpQueryObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php index 3a97eb9..6658750 100644 --- a/src/PhpQueryObject.php +++ b/src/PhpQueryObject.php @@ -3709,7 +3709,7 @@ public function map($callback, $param1 = null, $param2 = null, $param3 = null) return $this->newInstance( call_user_func_array( array( - 'PhpQuery', + '\\PhpQuery\\PhpQuery', 'map' ), $params From ef3884329a51002a58e720c320c416d6b0ba64ea Mon Sep 17 00:00:00 2001 From: "Oleg Mikhailov (miholeus)" Date: Thu, 18 Sep 2014 01:13:05 +0400 Subject: [PATCH 53/59] fixed domevent error --- src/PhpQueryObject.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpQueryObject.php b/src/PhpQueryObject.php index 6658750..f5e3f9f 100644 --- a/src/PhpQueryObject.php +++ b/src/PhpQueryObject.php @@ -2224,7 +2224,7 @@ public function remove($selector = null) $this->debug("Removing '{$node->tagName}'"); $node->parentNode->removeChild($node); // Mutation event - $event = new DOMEvent(array( + $event = new Dom\DOMEvent(array( 'target' => $node, 'type' => 'DOMNodeRemoved' )); @@ -2243,7 +2243,7 @@ public function remove($selector = null) protected function markupEvents($newMarkup, $oldMarkup, $node) { if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) { - $event = new DOMEvent(array( + $event = new Dom\DOMEvent(array( 'target' => $node, 'type' => 'change' )); From 46153d0ae59c625867618995994ae3b895a1a222 Mon Sep 17 00:00:00 2001 From: Greg Payne Date: Wed, 17 Sep 2014 21:01:41 -0500 Subject: [PATCH 54/59] Fixed travis-ci image [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2d70ce2..9aeb771 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Revisiting PhpQuery -[![Build Status](https://travis-ci.org/wittiws/phonarc.png?branch=master)](https://travis-ci.org/wittiws/phonarc) +[![Build Status](https://travis-ci.org/wittiws/phpquery.png?branch=master)](https://travis-ci.org/wittiws/phpquery) ## Basic usage of this fork From eaadac6c6d592879e22ebea2bd38d7b115994782 Mon Sep 17 00:00:00 2001 From: c-harris Date: Thu, 11 Aug 2016 21:31:24 +1000 Subject: [PATCH 55/59] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 3222519..6577312 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name":"wittiws/phpquery", + "name":"cagartner/phpquery", "type":"library", "description":"PHP5.3+ namespaced version of phpQuery with enhanced CSS support", - "version":"0.9.6a", + "version":"0.9.8", "keywords":[ ] From 9ef428d100237bf98b3d48d76e8364229bc1e9dc Mon Sep 17 00:00:00 2001 From: BSCheshir Date: Fri, 14 Oct 2016 10:56:55 +0400 Subject: [PATCH 56/59] can accessable --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6577312..7395617 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { - "name":"cagartner/phpquery", + "name":"bscheshir/phpquery", "type":"library", "description":"PHP5.3+ namespaced version of phpQuery with enhanced CSS support", - "version":"0.9.8", + "version":"0.9.8.1", "keywords":[ ] From 2eaff4a6e271982fd2c9226ea8c61b1d4748cc8b Mon Sep 17 00:00:00 2001 From: c-harris Date: Tue, 25 Oct 2016 01:21:25 +1000 Subject: [PATCH 57/59] Update .travis.yml --- .travis.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a1629ba..fe8b493 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,20 @@ language: php + php: - 5.5 - - 5.4 - - 5.3 -before_install: - - wget http://getcomposer.org/composer.phar; chmod +x composer.phar; ./composer.phar install + - 7.0 + +before_script: + - composer install +# - wget http://getcomposer.org/composer.phar +# - php composer.phar require satooshi/php-coveralls:dev-master --dev --no-progress --prefer-source + +script: + - mkdir -p build/logs + - phpunit --coverage-clover build/logs/clover.xml + +after_script: + - php vendor/bin/coveralls --exclude-no-stmt + +after_success: + - coveralls From 01b8aba83be6c2a1f245fbb3c32372071bb61305 Mon Sep 17 00:00:00 2001 From: c-harris Date: Tue, 25 Oct 2016 01:28:49 +1000 Subject: [PATCH 58/59] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9aeb771..5cb66c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Revisiting PhpQuery -[![Build Status](https://travis-ci.org/wittiws/phpquery.png?branch=master)](https://travis-ci.org/wittiws/phpquery) +[![Build Status](https://travis-ci.org/c-harris/phpquery.svg?branch=master)](https://travis-ci.org/c-harris/phpquery) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/c-harris/phpquery/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/c-harris/phpquery/?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/c-harris/phpquery/badge.svg?branch=master)](https://coveralls.io/github/c-harris/phpquery?branch=master) ## Basic usage of this fork From 57443110a802784e84aecc48fc291fcb6318afb5 Mon Sep 17 00:00:00 2001 From: c-harris Date: Tue, 25 Oct 2016 01:29:13 +1000 Subject: [PATCH 59/59] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fe8b493..f44309f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: php php: - 5.5 - - 7.0 + - 5.6 before_script: - composer install