Overview

Namespaces

  • Budovy
  • Kdyby
    • BootstrapFormRenderer
      • DI
      • Latte
  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Diagnostics
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
      • Diagnostics
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • PhpGenerator
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
  • NetteModule
  • Nextras
    • Datagrid
  • None
  • PHP
  • Tester
    • CodeCoverage
    • Runner
      • Output
  • Vodacek
    • Forms
      • Controls
  • WebLoader
    • Filter
    • Nette

Classes

  • Assert
  • DataProvider
  • DomQuery
  • Dumper
  • Environment
  • Helpers
  • TestCase

Exceptions

  • AssertException
  • TestCaseException
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Tester.
  5:  * Copyright (c) 2009 David Grudl (http://davidgrudl.com)
  6:  */
  7: 
  8: namespace Tester;
  9: 
 10: 
 11: /**
 12:  * DomQuery simplifies querying (X)HTML documents.
 13:  *
 14:  * @author     David Grudl
 15:  */
 16: class DomQuery extends \SimpleXMLElement
 17: {
 18: 
 19:     /**
 20:      * @return DomQuery
 21:      */
 22:     public static function fromHtml($html)
 23:     {
 24:         if (strpos($html, '<') === FALSE) {
 25:             $html = '<body>' . $html;
 26:         }
 27:         $dom = new \DOMDocument();
 28:         $dom->loadHTML($html);
 29:         return simplexml_import_dom($dom, __CLASS__);
 30:     }
 31: 
 32: 
 33:     /**
 34:      * @return DomQuery
 35:      */
 36:     public static function fromXml($xml)
 37:     {
 38:         return simplexml_load_string($xml, __CLASS__);
 39:     }
 40: 
 41: 
 42:     /**
 43:      * Returns array of descendants filtered by a selector.
 44:      * @return DomQuery[]
 45:      */
 46:     public function find($selector)
 47:     {
 48:         return $this->xpath(self::css2xpath($selector));
 49:     }
 50: 
 51: 
 52:     /**
 53:      * Check the current document against a selector.
 54:      * @return bool
 55:      */
 56:     public function has($selector)
 57:     {
 58:         return (bool) $this->find($selector);
 59:     }
 60: 
 61: 
 62:     /**
 63:      * Transforms CSS expression to XPath.
 64:      * @return string
 65:      */
 66:     public static function css2xpath($css)
 67:     {
 68:         $xpath = '//*';
 69:         preg_match_all('/
 70:             ([#.:]?)([a-z][a-z0-9_-]*)|               # id, class, pseudoclass (1,2)
 71:             \[([a-z0-9_-]+)(?:([~*^$]?)=([^\]]+))?\]| # [attr=val] (3,4,5)
 72:             \s*([>,+~])\s*|                           # > , + ~ (6)
 73:             (\s+)|                                    # whitespace (7)
 74:             (\*)                                      # * (8)
 75:         /ix', trim($css), $matches, PREG_SET_ORDER);
 76:         foreach ($matches as $m) {
 77:             if ($m[1] === '#') { // #ID
 78:                 $xpath .= "[@id='$m[2]']";
 79:             } elseif ($m[1] === '.') { // .class
 80:                 $xpath .= "[contains(concat(' ', normalize-space(@class), ' '), ' $m[2] ')]";
 81:             } elseif ($m[1] === ':') { // :pseudo-class
 82:                 throw new \InvalidArgumentException('Not implemented.');
 83:             } elseif ($m[2]) { // tag
 84:                 $xpath = rtrim($xpath, '*') . $m[2];
 85:             } elseif ($m[3]) { // [attribute]
 86:                 $attr = '@' . strtolower($m[3]);
 87:                 if (!isset($m[5])) {
 88:                     $xpath .= "[$attr]";
 89:                     continue;
 90:                 }
 91:                 $val = trim($m[5], '"\'');
 92:                 if ($m[4] === '') {
 93:                     $xpath .= "[$attr='$val']";
 94:                 } elseif ($m[4] === '~') {
 95:                     $xpath .= "[contains(concat(' ', normalize-space($attr), ' '), ' $val ')]";
 96:                 } elseif ($m[4] === '*') {
 97:                     $xpath .= "[contains($attr, '$val')]";
 98:                 } elseif ($m[4] === '^') {
 99:                     $xpath .= "[starts-with($attr, '$val')]";
100:                 } elseif ($m[4] === '$') {
101:                     $xpath .= "[substring($attr, string-length($attr)-0)='$val']";
102:                 }
103:             } elseif ($m[6] === '>') {
104:                 $xpath .= '/*';
105:             } elseif ($m[6] === ',') {
106:                 $xpath .= '|//*';
107:             } elseif ($m[6] === '~') {
108:                 $xpath .= '/following-sibling::*';
109:             } elseif ($m[6] === '+') {
110:                 throw new \InvalidArgumentException('Not implemented.');
111:             } elseif ($m[7]) {
112:                 $xpath .= '//*';
113:             }
114:         }
115:         return $xpath;
116:     }
117: 
118: }
119: 
API documentation generated by ApiGen 2.8.0