Completed
Branch master (9ef428)
by Christopher
03:56
created
src/bootstrap.php 2 patches
Doc Comments   +13 added lines patch added patch discarded remove patch
@@ -44,6 +44,10 @@  discard block
 block discarded – undo
44 44
  *  Included for mbstring pseudo-compatability.
45 45
  */
46 46
 if (!function_exists('mb_strpos')) {
47
+
48
+    /**
49
+     * @param string $needle
50
+     */
47 51
     function mb_strpos($haystack, $needle, $offset = 0)
48 52
     {
49 53
         return strpos($haystack, $needle, $offset);
@@ -55,6 +59,10 @@  discard block
 block discarded – undo
55 59
  *  Included for mbstring pseudo-compatability.
56 60
  */
57 61
 if (!function_exists('mb_stripos')) {
62
+
63
+    /**
64
+     * @param string $needle
65
+     */
58 66
     function mb_stripos($haystack, $needle, $offset = 0)
59 67
     {
60 68
         return stripos($haystack, $needle, $offset);
@@ -67,6 +75,11 @@  discard block
 block discarded – undo
67 75
  *  Included for mbstring pseudo-compatability.
68 76
  */
69 77
 if (!function_exists('mb_substr')) {
78
+
79
+    /**
80
+     * @param string $str
81
+     * @param integer $start
82
+     */
70 83
     function mb_substr($str, $start, $length = 0)
71 84
     {
72 85
         return substr($str, $start, $length);
Please login to merge, or discard this patch.
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -8,10 +8,10 @@  discard block
 block discarded – undo
8 8
  *  Included for mbstring pseudo-compatability.
9 9
  */
10 10
 if (!function_exists('mb_internal_encoding')) {
11
-    function mb_internal_encoding($enc)
12
-    {
13
-        return true;
14
-    }
11
+	function mb_internal_encoding($enc)
12
+	{
13
+		return true;
14
+	}
15 15
 }
16 16
 
17 17
 /**
@@ -20,10 +20,10 @@  discard block
 block discarded – undo
20 20
  *  Included for mbstring pseudo-compatability.
21 21
  */
22 22
 if (!function_exists('mb_regex_encoding')) {
23
-    function mb_regex_encoding($enc)
24
-    {
25
-        return true;
26
-    }
23
+	function mb_regex_encoding($enc)
24
+	{
25
+		return true;
26
+	}
27 27
 }
28 28
 
29 29
 /**
@@ -32,10 +32,10 @@  discard block
 block discarded – undo
32 32
  *  Included for mbstring pseudo-compatability.
33 33
  */
34 34
 if (!function_exists('mb_strlen')) {
35
-    function mb_strlen($str)
36
-    {
37
-        return strlen($str);
38
-    }
35
+	function mb_strlen($str)
36
+	{
37
+		return strlen($str);
38
+	}
39 39
 }
40 40
 
41 41
 /**
@@ -44,10 +44,10 @@  discard block
 block discarded – undo
44 44
  *  Included for mbstring pseudo-compatability.
45 45
  */
46 46
 if (!function_exists('mb_strpos')) {
47
-    function mb_strpos($haystack, $needle, $offset = 0)
48
-    {
49
-        return strpos($haystack, $needle, $offset);
50
-    }
47
+	function mb_strpos($haystack, $needle, $offset = 0)
48
+	{
49
+		return strpos($haystack, $needle, $offset);
50
+	}
51 51
 }
52 52
 /**
53 53
  *  mb_stripos()
@@ -55,10 +55,10 @@  discard block
 block discarded – undo
55 55
  *  Included for mbstring pseudo-compatability.
56 56
  */
57 57
 if (!function_exists('mb_stripos')) {
58
-    function mb_stripos($haystack, $needle, $offset = 0)
59
-    {
60
-        return stripos($haystack, $needle, $offset);
61
-    }
58
+	function mb_stripos($haystack, $needle, $offset = 0)
59
+	{
60
+		return stripos($haystack, $needle, $offset);
61
+	}
62 62
 }
63 63
 
64 64
 /**
@@ -67,10 +67,10 @@  discard block
 block discarded – undo
67 67
  *  Included for mbstring pseudo-compatability.
68 68
  */
69 69
 if (!function_exists('mb_substr')) {
70
-    function mb_substr($str, $start, $length = 0)
71
-    {
72
-        return substr($str, $start, $length);
73
-    }
70
+	function mb_substr($str, $start, $length = 0)
71
+	{
72
+		return substr($str, $start, $length);
73
+	}
74 74
 }
75 75
 
76 76
 /**
@@ -79,8 +79,8 @@  discard block
 block discarded – undo
79 79
  *  Included for mbstring pseudo-compatability.
80 80
  */
81 81
 if (!function_exists('mb_substr_count')) {
82
-    function mb_substr_count($haystack, $needle)
83
-    {
84
-        return substr_count($haystack, $needle);
85
-    }
82
+	function mb_substr_count($haystack, $needle)
83
+	{
84
+		return substr_count($haystack, $needle);
85
+	}
86 86
 }
Please login to merge, or discard this patch.
src/Callback/Callback.php 2 patches
Doc Comments   +8 added lines patch added patch discarded remove patch
@@ -1,6 +1,14 @@
 block discarded – undo
1 1
 <?php
2 2
 interface ICallbackNamed {
3
+
4
+	/**
5
+	 * @return boolean
6
+	 */
3 7
 	function hasName();
8
+
9
+	/**
10
+	 * @return string
11
+	 */
4 12
 	function getName();
5 13
 }
6 14
 /**
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -80,8 +80,8 @@  discard block
 block discarded – undo
80 80
 class CallbackReturnReference extends Callback
81 81
 	implements ICallbackNamed {
82 82
 	protected $reference;
83
-	public function __construct(&$reference, $name = null){
84
-		$this->reference =& $reference;
83
+	public function __construct(&$reference, $name = null) {
84
+		$this->reference = & $reference;
85 85
 		$this->callback = array($this, 'callback');
86 86
 	}
87 87
 	public function callback() {
@@ -103,8 +103,8 @@  discard block
 block discarded – undo
103 103
 	implements ICallbackNamed {
104 104
 	protected $value;
105 105
 	protected $name;
106
-	public function __construct($value, $name = null){
107
-		$this->value =& $value;
106
+	public function __construct($value, $name = null) {
107
+		$this->value = & $value;
108 108
 		$this->name = $name;
109 109
 		$this->callback = array($this, 'callback');
110 110
 	}
@@ -134,8 +134,8 @@  discard block
 block discarded – undo
134 134
 	 * @TODO implement $paramIndex; 
135 135
 	 * param index choose which callback param will be passed to reference
136 136
 	 */
137
-	public function __construct(&$reference){
138
-		$this->callback =& $reference;
137
+	public function __construct(&$reference) {
138
+		$this->callback = & $reference;
139 139
 	}
140 140
 }
141 141
 //class CallbackReference extends Callback {
Please login to merge, or discard this patch.
src/Dom/DOMDocumentWrapper.php 3 patches
Doc Comments   +8 added lines, -1 removed lines patch added patch discarded remove patch
@@ -592,6 +592,7 @@  discard block
 block discarded – undo
592 592
      *
593 593
      * @param $document DOMDocumentWrapper
594 594
      * @param $markup
595
+     * @param DOMDocumentWrapper $fragment
595 596
      * @return $document
596 597
      */
597 598
     private function documentFragmentLoadMarkup($fragment, $charset, $markup = null)
@@ -643,6 +644,9 @@  discard block
 block discarded – undo
643 644
         return true;
644 645
     }
645 646
 
647
+    /**
648
+     * @param DOMDocumentWrapper $fragment
649
+     */
646 650
     protected function documentFragmentToMarkup($fragment)
647 651
     {
648 652
         PhpQuery::debug('documentFragmentToMarkup');
@@ -760,6 +764,9 @@  discard block
 block discarded – undo
760 764
         }
761 765
     }
762 766
 
767
+    /**
768
+     * @param string $markup
769
+     */
763 770
     protected static function markupFixXHTML($markup)
764 771
     {
765 772
         $markup = self::expandEmptyTag('script', $markup);
@@ -776,7 +783,7 @@  discard block
 block discarded – undo
776 783
     /**
777 784
      * expandEmptyTag
778 785
      *
779
-     * @param $tag
786
+     * @param string $tag
780 787
      * @param $xml
781 788
      * @return string
782 789
      * @author mjaque at ilkebenson dot com
Please login to merge, or discard this patch.
Indentation   +755 added lines, -755 removed lines patch added patch discarded remove patch
@@ -15,788 +15,788 @@
 block discarded – undo
15 15
  */
16 16
 class DOMDocumentWrapper
17 17
 {
18
-    /**
19
-     * @var \DOMDocument
20
-     */
21
-    public $document;
22
-    public $id;
23
-    /**
24
-     * @todo Rewrite as method and quess if null.
25
-     * @var unknown_type
26
-     */
27
-    public $contentType = '';
28
-    public $xpath;
29
-    public $uuid = 0;
30
-    public $data = array();
31
-    public $dataNodes = array();
32
-    public $events = array();
33
-    public $eventsNodes = array();
34
-    public $eventsGlobal = array();
35
-    /**
36
-     * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28
37
-     * @var unknown_type
38
-     */
39
-    public $frames = array();
40
-    /**
41
-     * Document root, by default equals to document itself.
42
-     * Used by documentFragments.
43
-     *
44
-     * @var \DOMNode
45
-     */
46
-    public $root;
47
-    public $isDocumentFragment;
48
-    public $isXML = false;
49
-    public $isXHTML = false;
50
-    public $isHTML = false;
51
-    public $charset;
18
+	/**
19
+	 * @var \DOMDocument
20
+	 */
21
+	public $document;
22
+	public $id;
23
+	/**
24
+	 * @todo Rewrite as method and quess if null.
25
+	 * @var unknown_type
26
+	 */
27
+	public $contentType = '';
28
+	public $xpath;
29
+	public $uuid = 0;
30
+	public $data = array();
31
+	public $dataNodes = array();
32
+	public $events = array();
33
+	public $eventsNodes = array();
34
+	public $eventsGlobal = array();
35
+	/**
36
+	 * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28
37
+	 * @var unknown_type
38
+	 */
39
+	public $frames = array();
40
+	/**
41
+	 * Document root, by default equals to document itself.
42
+	 * Used by documentFragments.
43
+	 *
44
+	 * @var \DOMNode
45
+	 */
46
+	public $root;
47
+	public $isDocumentFragment;
48
+	public $isXML = false;
49
+	public $isXHTML = false;
50
+	public $isHTML = false;
51
+	public $charset;
52 52
 
53
-    public function __construct($markup = null, $contentType = null, $newDocumentID = null)
54
-    {
55
-        if (isset($markup)) {
56
-            $this->load($markup, $contentType, $newDocumentID);
57
-        }
58
-        $this->id = $newDocumentID ? $newDocumentID : md5(microtime());
59
-    }
53
+	public function __construct($markup = null, $contentType = null, $newDocumentID = null)
54
+	{
55
+		if (isset($markup)) {
56
+			$this->load($markup, $contentType, $newDocumentID);
57
+		}
58
+		$this->id = $newDocumentID ? $newDocumentID : md5(microtime());
59
+	}
60 60
 
61
-    public function load($markup, $contentType = null, $newDocumentID = null)
62
-    {
63
-        //		PhpQuery::$documents[$id] = $this;
64
-        $this->contentType = strtolower($contentType);
65
-        if ($markup instanceof \DOMDocument) {
66
-            $this->document = $markup;
67
-            $this->root     = $this->document;
68
-            $this->charset  = $this->document->encoding;
69
-            // TODO isDocumentFragment
70
-            $loaded = true;
71
-        } else {
72
-            $loaded = $this->loadMarkup($markup);
73
-        }
74
-        if ($loaded) {
75
-            //			$this->document->formatOutput = true;
76
-            $this->document->preserveWhiteSpace = true;
77
-            $this->xpath                        = new \DOMXPath($this->document);
78
-            $this->afterMarkupLoad();
79
-            return true;
80
-            // remember last loaded document
81
-            //			return PhpQuery::selectDocument($id);
82
-        }
83
-        return false;
84
-    }
61
+	public function load($markup, $contentType = null, $newDocumentID = null)
62
+	{
63
+		//		PhpQuery::$documents[$id] = $this;
64
+		$this->contentType = strtolower($contentType);
65
+		if ($markup instanceof \DOMDocument) {
66
+			$this->document = $markup;
67
+			$this->root     = $this->document;
68
+			$this->charset  = $this->document->encoding;
69
+			// TODO isDocumentFragment
70
+			$loaded = true;
71
+		} else {
72
+			$loaded = $this->loadMarkup($markup);
73
+		}
74
+		if ($loaded) {
75
+			//			$this->document->formatOutput = true;
76
+			$this->document->preserveWhiteSpace = true;
77
+			$this->xpath                        = new \DOMXPath($this->document);
78
+			$this->afterMarkupLoad();
79
+			return true;
80
+			// remember last loaded document
81
+			//			return PhpQuery::selectDocument($id);
82
+		}
83
+		return false;
84
+	}
85 85
 
86
-    protected function afterMarkupLoad()
87
-    {
88
-        if ($this->isXHTML) {
89
-            $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
90
-        }
91
-    }
86
+	protected function afterMarkupLoad()
87
+	{
88
+		if ($this->isXHTML) {
89
+			$this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
90
+		}
91
+	}
92 92
 
93
-    protected function loadMarkup($markup)
94
-    {
95
-        $loaded = false;
96
-        if ($this->contentType) {
97
-            self::debug("Load markup for content type {$this->contentType}");
98
-            // content determined by contentType
99
-            list($contentType, $charset) = $this->contentTypeToArray($this->contentType);
100
-            switch ($contentType) {
101
-                case 'text/html':
102
-                    PhpQuery::debug("Loading HTML, content type '{$this->contentType}'");
103
-                    $loaded = $this->loadMarkupHTML($markup, $charset);
104
-                    break;
105
-                case 'text/xml':
106
-                case 'application/xhtml+xml':
107
-                    PhpQuery::debug("Loading XML, content type '{$this->contentType}'");
108
-                    $loaded = $this->loadMarkupXML($markup, $charset);
109
-                    break;
110
-                default:
111
-                    // for feeds or anything that sometimes doesn't use text/xml
112
-                    if (strpos('xml', $this->contentType) !== false) {
113
-                        PhpQuery::debug("Loading XML, content type '{$this->contentType}'");
114
-                        $loaded = $this->loadMarkupXML($markup, $charset);
115
-                    } else {
116
-                        PhpQuery::debug("Could not determine document type from content type '{$this->contentType}'");
117
-                    }
118
-            }
119
-        } else {
120
-            // content type autodetection
121
-            if ($this->isXML($markup)) {
122
-                PhpQuery::debug("Loading XML, isXML() == true");
123
-                $loaded = $this->loadMarkupXML($markup);
124
-                if (!$loaded && $this->isXHTML) {
125
-                    PhpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true');
126
-                    $loaded = $this->loadMarkupHTML($markup);
127
-                }
128
-            } else {
129
-                PhpQuery::debug("Loading HTML, isXML() == false");
130
-                $loaded = $this->loadMarkupHTML($markup);
131
-            }
132
-        }
133
-        return $loaded;
134
-    }
93
+	protected function loadMarkup($markup)
94
+	{
95
+		$loaded = false;
96
+		if ($this->contentType) {
97
+			self::debug("Load markup for content type {$this->contentType}");
98
+			// content determined by contentType
99
+			list($contentType, $charset) = $this->contentTypeToArray($this->contentType);
100
+			switch ($contentType) {
101
+				case 'text/html':
102
+					PhpQuery::debug("Loading HTML, content type '{$this->contentType}'");
103
+					$loaded = $this->loadMarkupHTML($markup, $charset);
104
+					break;
105
+				case 'text/xml':
106
+				case 'application/xhtml+xml':
107
+					PhpQuery::debug("Loading XML, content type '{$this->contentType}'");
108
+					$loaded = $this->loadMarkupXML($markup, $charset);
109
+					break;
110
+				default:
111
+					// for feeds or anything that sometimes doesn't use text/xml
112
+					if (strpos('xml', $this->contentType) !== false) {
113
+						PhpQuery::debug("Loading XML, content type '{$this->contentType}'");
114
+						$loaded = $this->loadMarkupXML($markup, $charset);
115
+					} else {
116
+						PhpQuery::debug("Could not determine document type from content type '{$this->contentType}'");
117
+					}
118
+			}
119
+		} else {
120
+			// content type autodetection
121
+			if ($this->isXML($markup)) {
122
+				PhpQuery::debug("Loading XML, isXML() == true");
123
+				$loaded = $this->loadMarkupXML($markup);
124
+				if (!$loaded && $this->isXHTML) {
125
+					PhpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true');
126
+					$loaded = $this->loadMarkupHTML($markup);
127
+				}
128
+			} else {
129
+				PhpQuery::debug("Loading HTML, isXML() == false");
130
+				$loaded = $this->loadMarkupHTML($markup);
131
+			}
132
+		}
133
+		return $loaded;
134
+	}
135 135
 
136
-    protected function loadMarkupReset()
137
-    {
138
-        $this->isXML = $this->isXHTML = $this->isHTML = false;
139
-    }
136
+	protected function loadMarkupReset()
137
+	{
138
+		$this->isXML = $this->isXHTML = $this->isHTML = false;
139
+	}
140 140
 
141
-    protected function documentCreate($charset, $version = '1.0')
142
-    {
143
-        if (!$version) {
144
-            $version = '1.0';
145
-        }
146
-        $this->document = new \DOMDocument($version, $charset);
147
-        $this->charset  = $this->document->encoding;
148
-        //		$this->document->encoding = $charset;
149
-        $this->document->formatOutput       = true;
150
-        $this->document->preserveWhiteSpace = true;
151
-    }
141
+	protected function documentCreate($charset, $version = '1.0')
142
+	{
143
+		if (!$version) {
144
+			$version = '1.0';
145
+		}
146
+		$this->document = new \DOMDocument($version, $charset);
147
+		$this->charset  = $this->document->encoding;
148
+		//		$this->document->encoding = $charset;
149
+		$this->document->formatOutput       = true;
150
+		$this->document->preserveWhiteSpace = true;
151
+	}
152 152
 
153
-    protected function loadMarkupHTML($markup, $requestedCharset = null)
154
-    {
155
-        if (PhpQuery::$debug) {
156
-            PhpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250));
157
-        }
158
-        $this->loadMarkupReset();
159
-        $this->isHTML = true;
160
-        if (!isset($this->isDocumentFragment)) {
161
-            $this->isDocumentFragment = self::isDocumentFragmentHTML($markup);
162
-        }
163
-        $charset            = null;
164
-        $documentCharset    = $this->charsetFromHTML($markup);
165
-        $addDocumentCharset = false;
166
-        if ($documentCharset) {
167
-            $charset = $documentCharset;
168
-            $markup  = $this->charsetFixHTML($markup);
169
-        } else {
170
-            if ($requestedCharset) {
171
-                $charset = $requestedCharset;
172
-            }
173
-        }
174
-        if (!$charset) {
175
-            $charset = PhpQuery::$defaultCharset;
176
-        }
177
-        // HTTP 1.1 says that the default charset is ISO-8859-1
178
-        // @see http://www.w3.org/International/O-HTTP-charset
179
-        if (!$documentCharset) {
180
-            $documentCharset    = 'ISO-8859-1';
181
-            $addDocumentCharset = true;
182
-        }
183
-        // Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding'
184
-        // Worse, some pages can have mixed encodings... we'll try not to worry about that
185
-        $requestedCharset = strtoupper($requestedCharset);
186
-        $documentCharset  = strtoupper($documentCharset);
187
-        PhpQuery::debug("DOC: $documentCharset REQ: $requestedCharset");
188
-        if ($requestedCharset && $documentCharset
189
-            && $requestedCharset !== $documentCharset
190
-        ) {
191
-            PhpQuery::debug("CHARSET CONVERT");
192
-            // Document Encoding Conversion
193
-            // http://code.google.com/p/phpquery/issues/detail?id=86
194
-            if (function_exists('mb_detect_encoding')) {
195
-                $possibleCharsets = array(
196
-                    $documentCharset,
197
-                    $requestedCharset,
198
-                    'AUTO'
199
-                );
200
-                $docEncoding      = mb_detect_encoding($markup, implode(', ', $possibleCharsets));
201
-                if (!$docEncoding) {
202
-                    $docEncoding = $documentCharset;
203
-                }
204
-                // ok trust the document
205
-                PhpQuery::debug("DETECTED '$docEncoding'");
206
-                // Detected does not match what document says...
207
-                if ($docEncoding !== $documentCharset) {
208
-                    // Tricky..
209
-                }
210
-                if ($docEncoding !== $requestedCharset) {
211
-                    PhpQuery::debug("CONVERT $docEncoding => $requestedCharset");
212
-                    $markup  = mb_convert_encoding($markup, $requestedCharset, $docEncoding);
213
-                    $markup  = $this->charsetAppendToHTML($markup, $requestedCharset);
214
-                    $charset = $requestedCharset;
215
-                }
216
-            } else {
217
-                PhpQuery::debug("TODO: charset conversion without mbstring...");
218
-            }
219
-        }
220
-        $return = false;
221
-        if ($this->isDocumentFragment) {
222
-            PhpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'");
223
-            $return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
224
-        } else {
225
-            if ($addDocumentCharset) {
226
-                PhpQuery::debug("Full markup load (HTML), appending charset: '$charset'");
227
-                $markup = $this->charsetAppendToHTML($markup, $charset);
228
-            }
229
-            PhpQuery::debug("Full markup load (HTML), documentCreate('$charset')");
230
-            $this->documentCreate($charset);
231
-            $return = PhpQuery::$debug === 2 ? $this->document->loadHTML($markup)
232
-                : @$this->document->loadHTML($markup);
233
-            if ($return) {
234
-                $this->root = $this->document;
235
-            }
236
-        }
237
-        if ($return && !$this->contentType) {
238
-            $this->contentType = 'text/html';
239
-        }
240
-        return $return;
241
-    }
153
+	protected function loadMarkupHTML($markup, $requestedCharset = null)
154
+	{
155
+		if (PhpQuery::$debug) {
156
+			PhpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250));
157
+		}
158
+		$this->loadMarkupReset();
159
+		$this->isHTML = true;
160
+		if (!isset($this->isDocumentFragment)) {
161
+			$this->isDocumentFragment = self::isDocumentFragmentHTML($markup);
162
+		}
163
+		$charset            = null;
164
+		$documentCharset    = $this->charsetFromHTML($markup);
165
+		$addDocumentCharset = false;
166
+		if ($documentCharset) {
167
+			$charset = $documentCharset;
168
+			$markup  = $this->charsetFixHTML($markup);
169
+		} else {
170
+			if ($requestedCharset) {
171
+				$charset = $requestedCharset;
172
+			}
173
+		}
174
+		if (!$charset) {
175
+			$charset = PhpQuery::$defaultCharset;
176
+		}
177
+		// HTTP 1.1 says that the default charset is ISO-8859-1
178
+		// @see http://www.w3.org/International/O-HTTP-charset
179
+		if (!$documentCharset) {
180
+			$documentCharset    = 'ISO-8859-1';
181
+			$addDocumentCharset = true;
182
+		}
183
+		// Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding'
184
+		// Worse, some pages can have mixed encodings... we'll try not to worry about that
185
+		$requestedCharset = strtoupper($requestedCharset);
186
+		$documentCharset  = strtoupper($documentCharset);
187
+		PhpQuery::debug("DOC: $documentCharset REQ: $requestedCharset");
188
+		if ($requestedCharset && $documentCharset
189
+			&& $requestedCharset !== $documentCharset
190
+		) {
191
+			PhpQuery::debug("CHARSET CONVERT");
192
+			// Document Encoding Conversion
193
+			// http://code.google.com/p/phpquery/issues/detail?id=86
194
+			if (function_exists('mb_detect_encoding')) {
195
+				$possibleCharsets = array(
196
+					$documentCharset,
197
+					$requestedCharset,
198
+					'AUTO'
199
+				);
200
+				$docEncoding      = mb_detect_encoding($markup, implode(', ', $possibleCharsets));
201
+				if (!$docEncoding) {
202
+					$docEncoding = $documentCharset;
203
+				}
204
+				// ok trust the document
205
+				PhpQuery::debug("DETECTED '$docEncoding'");
206
+				// Detected does not match what document says...
207
+				if ($docEncoding !== $documentCharset) {
208
+					// Tricky..
209
+				}
210
+				if ($docEncoding !== $requestedCharset) {
211
+					PhpQuery::debug("CONVERT $docEncoding => $requestedCharset");
212
+					$markup  = mb_convert_encoding($markup, $requestedCharset, $docEncoding);
213
+					$markup  = $this->charsetAppendToHTML($markup, $requestedCharset);
214
+					$charset = $requestedCharset;
215
+				}
216
+			} else {
217
+				PhpQuery::debug("TODO: charset conversion without mbstring...");
218
+			}
219
+		}
220
+		$return = false;
221
+		if ($this->isDocumentFragment) {
222
+			PhpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'");
223
+			$return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
224
+		} else {
225
+			if ($addDocumentCharset) {
226
+				PhpQuery::debug("Full markup load (HTML), appending charset: '$charset'");
227
+				$markup = $this->charsetAppendToHTML($markup, $charset);
228
+			}
229
+			PhpQuery::debug("Full markup load (HTML), documentCreate('$charset')");
230
+			$this->documentCreate($charset);
231
+			$return = PhpQuery::$debug === 2 ? $this->document->loadHTML($markup)
232
+				: @$this->document->loadHTML($markup);
233
+			if ($return) {
234
+				$this->root = $this->document;
235
+			}
236
+		}
237
+		if ($return && !$this->contentType) {
238
+			$this->contentType = 'text/html';
239
+		}
240
+		return $return;
241
+	}
242 242
 
243
-    protected function loadMarkupXML($markup, $requestedCharset = null)
244
-    {
245
-        if (PhpQuery::$debug) {
246
-            PhpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250));
247
-        }
248
-        $this->loadMarkupReset();
249
-        $this->isXML = true;
250
-        // check agains XHTML in contentType or markup
251
-        $isContentTypeXHTML = $this->isXHTML();
252
-        $isMarkupXHTML      = $this->isXHTML($markup);
253
-        if ($isContentTypeXHTML || $isMarkupXHTML) {
254
-            self::debug('Full markup load (XML), XHTML detected');
255
-            $this->isXHTML = true;
256
-        }
257
-        // determine document fragment
258
-        if (!isset($this->isDocumentFragment)) {
259
-            $this->isDocumentFragment = $this->isXHTML ? self::isDocumentFragmentXHTML($markup)
260
-                : self::isDocumentFragmentXML($markup);
261
-        }
262
-        // this charset will be used
263
-        $charset = null;
264
-        // charset from XML declaration @var string
265
-        $documentCharset = $this->charsetFromXML($markup);
266
-        if (!$documentCharset) {
267
-            if ($this->isXHTML) {
268
-                // this is XHTML, try to get charset from content-type meta header
269
-                $documentCharset = $this->charsetFromHTML($markup);
270
-                if ($documentCharset) {
271
-                    PhpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'");
272
-                    $this->charsetAppendToXML($markup, $documentCharset);
273
-                    $charset = $documentCharset;
274
-                }
275
-            }
276
-            if (!$documentCharset) {
277
-                // if still no document charset...
278
-                $charset = $requestedCharset;
279
-            }
280
-        } else {
281
-            if ($requestedCharset) {
282
-                $charset = $requestedCharset;
283
-            }
284
-        }
285
-        if (!$charset) {
286
-            $charset = PhpQuery::$defaultCharset;
287
-        }
288
-        if ($requestedCharset && $documentCharset
289
-            && $requestedCharset != $documentCharset
290
-        ) {
291
-            // TODO place for charset conversion
292
-            //			$charset = $requestedCharset;
293
-        }
294
-        $return = false;
295
-        if ($this->isDocumentFragment) {
296
-            PhpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'");
297
-            $return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
298
-        } else {
299
-            // FIXME ???
300
-            if ($isContentTypeXHTML && !$isMarkupXHTML) {
301
-                if (!$documentCharset) {
302
-                    PhpQuery::debug("Full markup load (XML), appending charset '$charset'");
303
-                    $markup = $this->charsetAppendToXML($markup, $charset);
304
-                }
305
-            }
306
-            // see http://pl2.php.net/manual/en/book.dom.php#78929
307
-            // LIBXML_DTDLOAD (>= PHP 5.1)
308
-            // does XML ctalogues works with LIBXML_NONET
309
-            //		$this->document->resolveExternals = true;
310
-            // TODO test LIBXML_COMPACT for performance improvement
311
-            // create document
312
-            $this->documentCreate($charset);
313
-            if (phpversion() < 5.1) {
314
-                $this->document->resolveExternals = true;
315
-                $return                           = PhpQuery::$debug === 2 ? $this->document->loadXML($markup)
316
-                    : @$this->document->loadXML($markup);
317
-            } else {
318
-                /** @link http://pl2.php.net/manual/en/libxml.constants.php */
319
-                $libxmlStatic = PhpQuery::$debug === 2 ? LIBXML_DTDLOAD
320
-                    | LIBXML_DTDATTR | LIBXML_NONET
321
-                    : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING
322
-                    | LIBXML_NOERROR;
323
-                $return       = $this->document->loadXML($markup, $libxmlStatic);
324
-                // 				if (! $return)
325
-                // 					$return = $this->document->loadHTML($markup);
326
-            }
327
-            if ($return) {
328
-                $this->root = $this->document;
329
-            }
330
-        }
331
-        if ($return) {
332
-            if (!$this->contentType) {
333
-                if ($this->isXHTML) {
334
-                    $this->contentType = 'application/xhtml+xml';
335
-                } else {
336
-                    $this->contentType = 'text/xml';
337
-                }
338
-            }
339
-            return $return;
340
-        } else {
341
-            throw new \Exception("Error loading XML markup");
342
-        }
343
-    }
243
+	protected function loadMarkupXML($markup, $requestedCharset = null)
244
+	{
245
+		if (PhpQuery::$debug) {
246
+			PhpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250));
247
+		}
248
+		$this->loadMarkupReset();
249
+		$this->isXML = true;
250
+		// check agains XHTML in contentType or markup
251
+		$isContentTypeXHTML = $this->isXHTML();
252
+		$isMarkupXHTML      = $this->isXHTML($markup);
253
+		if ($isContentTypeXHTML || $isMarkupXHTML) {
254
+			self::debug('Full markup load (XML), XHTML detected');
255
+			$this->isXHTML = true;
256
+		}
257
+		// determine document fragment
258
+		if (!isset($this->isDocumentFragment)) {
259
+			$this->isDocumentFragment = $this->isXHTML ? self::isDocumentFragmentXHTML($markup)
260
+				: self::isDocumentFragmentXML($markup);
261
+		}
262
+		// this charset will be used
263
+		$charset = null;
264
+		// charset from XML declaration @var string
265
+		$documentCharset = $this->charsetFromXML($markup);
266
+		if (!$documentCharset) {
267
+			if ($this->isXHTML) {
268
+				// this is XHTML, try to get charset from content-type meta header
269
+				$documentCharset = $this->charsetFromHTML($markup);
270
+				if ($documentCharset) {
271
+					PhpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'");
272
+					$this->charsetAppendToXML($markup, $documentCharset);
273
+					$charset = $documentCharset;
274
+				}
275
+			}
276
+			if (!$documentCharset) {
277
+				// if still no document charset...
278
+				$charset = $requestedCharset;
279
+			}
280
+		} else {
281
+			if ($requestedCharset) {
282
+				$charset = $requestedCharset;
283
+			}
284
+		}
285
+		if (!$charset) {
286
+			$charset = PhpQuery::$defaultCharset;
287
+		}
288
+		if ($requestedCharset && $documentCharset
289
+			&& $requestedCharset != $documentCharset
290
+		) {
291
+			// TODO place for charset conversion
292
+			//			$charset = $requestedCharset;
293
+		}
294
+		$return = false;
295
+		if ($this->isDocumentFragment) {
296
+			PhpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'");
297
+			$return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
298
+		} else {
299
+			// FIXME ???
300
+			if ($isContentTypeXHTML && !$isMarkupXHTML) {
301
+				if (!$documentCharset) {
302
+					PhpQuery::debug("Full markup load (XML), appending charset '$charset'");
303
+					$markup = $this->charsetAppendToXML($markup, $charset);
304
+				}
305
+			}
306
+			// see http://pl2.php.net/manual/en/book.dom.php#78929
307
+			// LIBXML_DTDLOAD (>= PHP 5.1)
308
+			// does XML ctalogues works with LIBXML_NONET
309
+			//		$this->document->resolveExternals = true;
310
+			// TODO test LIBXML_COMPACT for performance improvement
311
+			// create document
312
+			$this->documentCreate($charset);
313
+			if (phpversion() < 5.1) {
314
+				$this->document->resolveExternals = true;
315
+				$return                           = PhpQuery::$debug === 2 ? $this->document->loadXML($markup)
316
+					: @$this->document->loadXML($markup);
317
+			} else {
318
+				/** @link http://pl2.php.net/manual/en/libxml.constants.php */
319
+				$libxmlStatic = PhpQuery::$debug === 2 ? LIBXML_DTDLOAD
320
+					| LIBXML_DTDATTR | LIBXML_NONET
321
+					: LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING
322
+					| LIBXML_NOERROR;
323
+				$return       = $this->document->loadXML($markup, $libxmlStatic);
324
+				// 				if (! $return)
325
+				// 					$return = $this->document->loadHTML($markup);
326
+			}
327
+			if ($return) {
328
+				$this->root = $this->document;
329
+			}
330
+		}
331
+		if ($return) {
332
+			if (!$this->contentType) {
333
+				if ($this->isXHTML) {
334
+					$this->contentType = 'application/xhtml+xml';
335
+				} else {
336
+					$this->contentType = 'text/xml';
337
+				}
338
+			}
339
+			return $return;
340
+		} else {
341
+			throw new \Exception("Error loading XML markup");
342
+		}
343
+	}
344 344
 
345
-    protected function isXHTML($markup = null)
346
-    {
347
-        if (!isset($markup)) {
348
-            return strpos($this->contentType, 'xhtml') !== false;
349
-        }
350
-        // XXX ok ?
351
-        return strpos($markup, "<!DOCTYPE html") !== false;
352
-        //		return stripos($doctype, 'xhtml') !== false;
353
-        //		$doctype = isset($dom->doctype) && is_object($dom->doctype)
354
-        //			? $dom->doctype->publicId
355
-        //			: self::$defaultDoctype;
356
-    }
345
+	protected function isXHTML($markup = null)
346
+	{
347
+		if (!isset($markup)) {
348
+			return strpos($this->contentType, 'xhtml') !== false;
349
+		}
350
+		// XXX ok ?
351
+		return strpos($markup, "<!DOCTYPE html") !== false;
352
+		//		return stripos($doctype, 'xhtml') !== false;
353
+		//		$doctype = isset($dom->doctype) && is_object($dom->doctype)
354
+		//			? $dom->doctype->publicId
355
+		//			: self::$defaultDoctype;
356
+	}
357 357
 
358
-    protected function isXML($markup)
359
-    {
360
-        //		return strpos($markup, '<?xml') !== false && stripos($markup, 'xhtml') === false;
361
-        return strpos(substr($markup, 0, 100), '<' . '?xml') !== false;
362
-    }
358
+	protected function isXML($markup)
359
+	{
360
+		//		return strpos($markup, '<?xml') !== false && stripos($markup, 'xhtml') === false;
361
+		return strpos(substr($markup, 0, 100), '<' . '?xml') !== false;
362
+	}
363 363
 
364
-    protected function contentTypeToArray($contentType)
365
-    {
366
-        $test = null;
367
-        $test = $matches = explode(';', trim(strtolower($contentType)));
368
-        if (isset($matches[1])) {
369
-            $matches[1] = explode('=', $matches[1]);
370
-            // strip 'charset='
371
-            $matches[1] = isset($matches[1][1]) && trim($matches[1][1]) ? $matches[1][1]
372
-                : $matches[1][0];
373
-        } else {
374
-            $matches[1] = null;
375
-        }
376
-        return $matches;
377
-    }
364
+	protected function contentTypeToArray($contentType)
365
+	{
366
+		$test = null;
367
+		$test = $matches = explode(';', trim(strtolower($contentType)));
368
+		if (isset($matches[1])) {
369
+			$matches[1] = explode('=', $matches[1]);
370
+			// strip 'charset='
371
+			$matches[1] = isset($matches[1][1]) && trim($matches[1][1]) ? $matches[1][1]
372
+				: $matches[1][0];
373
+		} else {
374
+			$matches[1] = null;
375
+		}
376
+		return $matches;
377
+	}
378 378
 
379
-    /**
380
-     *
381
-     * @param $markup
382
-     * @return array contentType, charset
383
-     */
384
-    protected function contentTypeFromHTML($markup)
385
-    {
386
-        $matches = array();
387
-        // find meta tag
388
-        preg_match('@<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches);
389
-        if (!isset($matches[0])) {
390
-            return array(
391
-                null,
392
-                null
393
-            );
394
-        }
395
-        // get attr 'content'
396
-        preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches);
397
-        if (!isset($matches[0])) {
398
-            return array(
399
-                null,
400
-                null
401
-            );
402
-        }
403
-        return $this->contentTypeToArray($matches[2]);
404
-    }
379
+	/**
380
+	 *
381
+	 * @param $markup
382
+	 * @return array contentType, charset
383
+	 */
384
+	protected function contentTypeFromHTML($markup)
385
+	{
386
+		$matches = array();
387
+		// find meta tag
388
+		preg_match('@<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', $markup, $matches);
389
+		if (!isset($matches[0])) {
390
+			return array(
391
+				null,
392
+				null
393
+			);
394
+		}
395
+		// get attr 'content'
396
+		preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches);
397
+		if (!isset($matches[0])) {
398
+			return array(
399
+				null,
400
+				null
401
+			);
402
+		}
403
+		return $this->contentTypeToArray($matches[2]);
404
+	}
405 405
 
406
-    protected function charsetFromHTML($markup)
407
-    {
408
-        $contentType = $this->contentTypeFromHTML($markup);
409
-        return $contentType[1];
410
-    }
406
+	protected function charsetFromHTML($markup)
407
+	{
408
+		$contentType = $this->contentTypeFromHTML($markup);
409
+		return $contentType[1];
410
+	}
411 411
 
412
-    protected function charsetFromXML($markup)
413
-    {
414
-        $matches;
415
-        // find declaration
416
-        preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches);
417
-        return isset($matches[2]) ? strtolower($matches[2]) : null;
418
-    }
412
+	protected function charsetFromXML($markup)
413
+	{
414
+		$matches;
415
+		// find declaration
416
+		preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches);
417
+		return isset($matches[2]) ? strtolower($matches[2]) : null;
418
+	}
419 419
 
420
-    /**
421
-     * Repositions meta[type=charset] at the start of head. Bypasses \DOMDocument bug.
422
-     *
423
-     * @link http://code.google.com/p/phpquery/issues/detail?id=80
424
-     * @param $html
425
-     */
426
-    protected function charsetFixHTML($markup)
427
-    {
428
-        $matches = array();
429
-        // find meta tag
430
-        preg_match(
431
-            '@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i',
432
-            $markup,
433
-            $matches,
434
-            PREG_OFFSET_CAPTURE
435
-        );
436
-        if (!isset($matches[0])) {
437
-            return;
438
-        }
439
-        $metaContentType = $matches[0][0];
440
-        $markup          = substr($markup, 0, $matches[0][1])
441
-            . substr($markup, $matches[0][1] + strlen($metaContentType));
442
-        $headStart       = stripos($markup, '<head>');
443
-        $markup          = substr($markup, 0, $headStart + 6) . $metaContentType
444
-            . substr($markup, $headStart + 6);
445
-        return $markup;
446
-    }
420
+	/**
421
+	 * Repositions meta[type=charset] at the start of head. Bypasses \DOMDocument bug.
422
+	 *
423
+	 * @link http://code.google.com/p/phpquery/issues/detail?id=80
424
+	 * @param $html
425
+	 */
426
+	protected function charsetFixHTML($markup)
427
+	{
428
+		$matches = array();
429
+		// find meta tag
430
+		preg_match(
431
+			'@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i',
432
+			$markup,
433
+			$matches,
434
+			PREG_OFFSET_CAPTURE
435
+		);
436
+		if (!isset($matches[0])) {
437
+			return;
438
+		}
439
+		$metaContentType = $matches[0][0];
440
+		$markup          = substr($markup, 0, $matches[0][1])
441
+			. substr($markup, $matches[0][1] + strlen($metaContentType));
442
+		$headStart       = stripos($markup, '<head>');
443
+		$markup          = substr($markup, 0, $headStart + 6) . $metaContentType
444
+			. substr($markup, $headStart + 6);
445
+		return $markup;
446
+	}
447 447
 
448
-    protected function charsetAppendToHTML($html, $charset, $xhtml = false)
449
-    {
450
-        // remove existing meta[type=content-type]
451
-        $html = preg_replace('@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html);
452
-        $meta = '<meta http-equiv="Content-Type" content="text/html;charset='
453
-            . $charset . '" ' . ($xhtml ? '/' : '') . '>';
454
-        if (strpos($html, '<head') === false) {
455
-            if (strpos($html, '<html') === false) {
456
-                return $meta . $html;
457
-            } else {
458
-                return preg_replace('@<html(.*?)(?(?<!\?)>)@s', "<html\\1><head>{$meta}</head>", $html);
459
-            }
460
-        } else {
461
-            return preg_replace('@<head(.*?)(?(?<!\?)>)@s', '<head\\1>' . $meta, $html);
462
-        }
463
-    }
448
+	protected function charsetAppendToHTML($html, $charset, $xhtml = false)
449
+	{
450
+		// remove existing meta[type=content-type]
451
+		$html = preg_replace('@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html);
452
+		$meta = '<meta http-equiv="Content-Type" content="text/html;charset='
453
+			. $charset . '" ' . ($xhtml ? '/' : '') . '>';
454
+		if (strpos($html, '<head') === false) {
455
+			if (strpos($html, '<html') === false) {
456
+				return $meta . $html;
457
+			} else {
458
+				return preg_replace('@<html(.*?)(?(?<!\?)>)@s', "<html\\1><head>{$meta}</head>", $html);
459
+			}
460
+		} else {
461
+			return preg_replace('@<head(.*?)(?(?<!\?)>)@s', '<head\\1>' . $meta, $html);
462
+		}
463
+	}
464 464
 
465
-    protected function charsetAppendToXML($markup, $charset)
466
-    {
467
-        $declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?'
468
-            . '>';
469
-        return $declaration . $markup;
470
-    }
465
+	protected function charsetAppendToXML($markup, $charset)
466
+	{
467
+		$declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?'
468
+			. '>';
469
+		return $declaration . $markup;
470
+	}
471 471
 
472
-    public static function isDocumentFragmentHTML($markup)
473
-    {
474
-        return stripos($markup, '<html') === false
475
-        && stripos($markup, '<!doctype') === false;
476
-    }
472
+	public static function isDocumentFragmentHTML($markup)
473
+	{
474
+		return stripos($markup, '<html') === false
475
+		&& stripos($markup, '<!doctype') === false;
476
+	}
477 477
 
478
-    public static function isDocumentFragmentXML($markup)
479
-    {
480
-        return stripos($markup, '<' . '?xml') === false;
481
-    }
478
+	public static function isDocumentFragmentXML($markup)
479
+	{
480
+		return stripos($markup, '<' . '?xml') === false;
481
+	}
482 482
 
483
-    public static function isDocumentFragmentXHTML($markup)
484
-    {
485
-        return self::isDocumentFragmentHTML($markup);
486
-    }
483
+	public static function isDocumentFragmentXHTML($markup)
484
+	{
485
+		return self::isDocumentFragmentHTML($markup);
486
+	}
487 487
 
488
-    public function importAttr($value)
489
-    {
490
-        // TODO
491
-    }
488
+	public function importAttr($value)
489
+	{
490
+		// TODO
491
+	}
492 492
 
493
-    /**
494
-     *
495
-     * @param $source
496
-     * @param $target
497
-     * @param $sourceCharset
498
-     * @return array Array of imported nodes.
499
-     */
500
-    public function import($source, $sourceCharset = null)
501
-    {
502
-        // TODO charset conversions
503
-        $return = array();
504
-        if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) {
505
-            $source = array(
506
-                $source
507
-            );
508
-        }
509
-        //		if (is_array($source)) {
510
-        //			foreach($source as $node) {
511
-        //				if (is_string($node)) {
512
-        //					// string markup
513
-        //					$fake = $this->documentFragmentCreate($node, $sourceCharset);
514
-        //					if ($fake === false)
515
-        //						throw new \Exception("Error loading documentFragment markup");
516
-        //					else
517
-        //						$return = array_merge($return,
518
-        //							$this->import($fake->root->childNodes)
519
-        //						);
520
-        //				} else {
521
-        //					$return[] = $this->document->importNode($node, true);
522
-        //				}
523
-        //			}
524
-        //			return $return;
525
-        //		} else {
526
-        //			// string markup
527
-        //			$fake = $this->documentFragmentCreate($source, $sourceCharset);
528
-        //			if ($fake === false)
529
-        //				throw new \Exception("Error loading documentFragment markup");
530
-        //			else
531
-        //				return $this->import($fake->root->childNodes);
532
-        //		}
533
-        if (is_array($source) || $source instanceof \DOMNodeList) {
534
-            // dom nodes
535
-            self::debug('Importing nodes to document');
536
-            foreach ($source as $node) {
537
-                $return[] = $this->document->importNode($node, true);
538
-            }
539
-        } else {
540
-            // string markup
541
-            $fake = $this->documentFragmentCreate($source, $sourceCharset);
542
-            if ($fake === false) {
543
-                throw new \Exception("Error loading documentFragment markup");
544
-            } else {
545
-                return $this->import($fake->root->childNodes);
546
-            }
547
-        }
548
-        return $return;
549
-    }
493
+	/**
494
+	 *
495
+	 * @param $source
496
+	 * @param $target
497
+	 * @param $sourceCharset
498
+	 * @return array Array of imported nodes.
499
+	 */
500
+	public function import($source, $sourceCharset = null)
501
+	{
502
+		// TODO charset conversions
503
+		$return = array();
504
+		if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) {
505
+			$source = array(
506
+				$source
507
+			);
508
+		}
509
+		//		if (is_array($source)) {
510
+		//			foreach($source as $node) {
511
+		//				if (is_string($node)) {
512
+		//					// string markup
513
+		//					$fake = $this->documentFragmentCreate($node, $sourceCharset);
514
+		//					if ($fake === false)
515
+		//						throw new \Exception("Error loading documentFragment markup");
516
+		//					else
517
+		//						$return = array_merge($return,
518
+		//							$this->import($fake->root->childNodes)
519
+		//						);
520
+		//				} else {
521
+		//					$return[] = $this->document->importNode($node, true);
522
+		//				}
523
+		//			}
524
+		//			return $return;
525
+		//		} else {
526
+		//			// string markup
527
+		//			$fake = $this->documentFragmentCreate($source, $sourceCharset);
528
+		//			if ($fake === false)
529
+		//				throw new \Exception("Error loading documentFragment markup");
530
+		//			else
531
+		//				return $this->import($fake->root->childNodes);
532
+		//		}
533
+		if (is_array($source) || $source instanceof \DOMNodeList) {
534
+			// dom nodes
535
+			self::debug('Importing nodes to document');
536
+			foreach ($source as $node) {
537
+				$return[] = $this->document->importNode($node, true);
538
+			}
539
+		} else {
540
+			// string markup
541
+			$fake = $this->documentFragmentCreate($source, $sourceCharset);
542
+			if ($fake === false) {
543
+				throw new \Exception("Error loading documentFragment markup");
544
+			} else {
545
+				return $this->import($fake->root->childNodes);
546
+			}
547
+		}
548
+		return $return;
549
+	}
550 550
 
551
-    /**
552
-     * Creates new document fragment.
553
-     *
554
-     * @param $source
555
-     * @return DOMDocumentWrapper
556
-     */
557
-    protected function documentFragmentCreate($source, $charset = null)
558
-    {
559
-        $fake              = new DOMDocumentWrapper();
560
-        $fake->contentType = $this->contentType;
561
-        $fake->isXML       = $this->isXML;
562
-        $fake->isHTML      = $this->isHTML;
563
-        $fake->isXHTML     = $this->isXHTML;
564
-        $fake->root        = $fake->document;
565
-        if (!$charset) {
566
-            $charset = $this->charset;
567
-        }
568
-        //	$fake->documentCreate($this->charset);
569
-        if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) {
570
-            $source = array(
571
-                $source
572
-            );
573
-        }
574
-        if (is_array($source) || $source instanceof \DOMNodeList) {
575
-            // dom nodes
576
-            // load fake document
577
-            if (!$this->documentFragmentLoadMarkup($fake, $charset)) {
578
-                return false;
579
-            }
580
-            $nodes = $fake->import($source);
581
-            foreach ($nodes as $node) {
582
-                $fake->root->appendChild($node);
583
-            }
584
-        } else {
585
-            // string markup
586
-            $this->documentFragmentLoadMarkup($fake, $charset, $source);
587
-        }
588
-        return $fake;
589
-    }
551
+	/**
552
+	 * Creates new document fragment.
553
+	 *
554
+	 * @param $source
555
+	 * @return DOMDocumentWrapper
556
+	 */
557
+	protected function documentFragmentCreate($source, $charset = null)
558
+	{
559
+		$fake              = new DOMDocumentWrapper();
560
+		$fake->contentType = $this->contentType;
561
+		$fake->isXML       = $this->isXML;
562
+		$fake->isHTML      = $this->isHTML;
563
+		$fake->isXHTML     = $this->isXHTML;
564
+		$fake->root        = $fake->document;
565
+		if (!$charset) {
566
+			$charset = $this->charset;
567
+		}
568
+		//	$fake->documentCreate($this->charset);
569
+		if ($source instanceof \DOMNode && !($source instanceof \DOMNodeList)) {
570
+			$source = array(
571
+				$source
572
+			);
573
+		}
574
+		if (is_array($source) || $source instanceof \DOMNodeList) {
575
+			// dom nodes
576
+			// load fake document
577
+			if (!$this->documentFragmentLoadMarkup($fake, $charset)) {
578
+				return false;
579
+			}
580
+			$nodes = $fake->import($source);
581
+			foreach ($nodes as $node) {
582
+				$fake->root->appendChild($node);
583
+			}
584
+		} else {
585
+			// string markup
586
+			$this->documentFragmentLoadMarkup($fake, $charset, $source);
587
+		}
588
+		return $fake;
589
+	}
590 590
 
591
-    /**
592
-     *
593
-     * @param $document DOMDocumentWrapper
594
-     * @param $markup
595
-     * @return $document
596
-     */
597
-    private function documentFragmentLoadMarkup($fragment, $charset, $markup = null)
598
-    {
599
-        // TODO error handling
600
-        // TODO copy doctype
601
-        // tempolary turn off
602
-        $fragment->isDocumentFragment = false;
603
-        if ($fragment->isXML) {
604
-            if ($fragment->isXHTML) {
605
-                // add FAKE element to set default namespace
606
-                $fragment->loadMarkupXML(
607
-                    '<?xml version="1.0" encoding="' . $charset
608
-                    . '"?>'
609
-                    . '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
610
-                    . '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
611
-                    . '<fake xmlns="http://www.w3.org/1999/xhtml">' . $markup . '</fake>'
612
-                );
613
-                $fragment->root = $fragment->document->firstChild->nextSibling;
614
-            } else {
615
-                $fragment->loadMarkupXML(
616
-                    '<?xml version="1.0" encoding="' . $charset
617
-                    . '"?><fake>' . $markup . '</fake>'
618
-                );
619
-                $fragment->root = $fragment->document->firstChild;
620
-            }
621
-        } else {
622
-            $markup2 = PhpQuery::$defaultDoctype
623
-                . '<html><head><meta http-equiv="Content-Type" content="text/html;charset='
624
-                . $charset . '"></head>';
625
-            $noBody  = strpos($markup, '<body') === false;
626
-            if ($noBody) {
627
-                $markup2 .= '<body>';
628
-            }
629
-            $markup2 .= $markup;
630
-            if ($noBody) {
631
-                $markup2 .= '</body>';
632
-            }
633
-            $markup2 .= '</html>';
634
-            $fragment->loadMarkupHTML($markup2);
635
-            // TODO resolv body tag merging issue
636
-            $fragment->root = $noBody ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling
637
-                : $fragment->document->firstChild->nextSibling->firstChild->nextSibling;
638
-        }
639
-        if (!$fragment->root) {
640
-            return false;
641
-        }
642
-        $fragment->isDocumentFragment = true;
643
-        return true;
644
-    }
591
+	/**
592
+	 *
593
+	 * @param $document DOMDocumentWrapper
594
+	 * @param $markup
595
+	 * @return $document
596
+	 */
597
+	private function documentFragmentLoadMarkup($fragment, $charset, $markup = null)
598
+	{
599
+		// TODO error handling
600
+		// TODO copy doctype
601
+		// tempolary turn off
602
+		$fragment->isDocumentFragment = false;
603
+		if ($fragment->isXML) {
604
+			if ($fragment->isXHTML) {
605
+				// add FAKE element to set default namespace
606
+				$fragment->loadMarkupXML(
607
+					'<?xml version="1.0" encoding="' . $charset
608
+					. '"?>'
609
+					. '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
610
+					. '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
611
+					. '<fake xmlns="http://www.w3.org/1999/xhtml">' . $markup . '</fake>'
612
+				);
613
+				$fragment->root = $fragment->document->firstChild->nextSibling;
614
+			} else {
615
+				$fragment->loadMarkupXML(
616
+					'<?xml version="1.0" encoding="' . $charset
617
+					. '"?><fake>' . $markup . '</fake>'
618
+				);
619
+				$fragment->root = $fragment->document->firstChild;
620
+			}
621
+		} else {
622
+			$markup2 = PhpQuery::$defaultDoctype
623
+				. '<html><head><meta http-equiv="Content-Type" content="text/html;charset='
624
+				. $charset . '"></head>';
625
+			$noBody  = strpos($markup, '<body') === false;
626
+			if ($noBody) {
627
+				$markup2 .= '<body>';
628
+			}
629
+			$markup2 .= $markup;
630
+			if ($noBody) {
631
+				$markup2 .= '</body>';
632
+			}
633
+			$markup2 .= '</html>';
634
+			$fragment->loadMarkupHTML($markup2);
635
+			// TODO resolv body tag merging issue
636
+			$fragment->root = $noBody ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling
637
+				: $fragment->document->firstChild->nextSibling->firstChild->nextSibling;
638
+		}
639
+		if (!$fragment->root) {
640
+			return false;
641
+		}
642
+		$fragment->isDocumentFragment = true;
643
+		return true;
644
+	}
645 645
 
646
-    protected function documentFragmentToMarkup($fragment)
647
-    {
648
-        PhpQuery::debug('documentFragmentToMarkup');
649
-        $tmp                          = $fragment->isDocumentFragment;
650
-        $fragment->isDocumentFragment = false;
651
-        $markup                       = $fragment->markup();
652
-        if ($fragment->isXML) {
653
-            $markup = substr($markup, 0, strrpos($markup, '</fake>'));
654
-            if ($fragment->isXHTML) {
655
-                $markup = substr($markup, strpos($markup, '<fake') + 43);
656
-            } else {
657
-                $markup = substr($markup, strpos($markup, '<fake>') + 6);
658
-            }
659
-        } else {
660
-            $markup = substr($markup, strpos($markup, '<body>') + 6);
661
-            $markup = substr($markup, 0, strrpos($markup, '</body>'));
662
-        }
663
-        $fragment->isDocumentFragment = $tmp;
664
-        if (PhpQuery::$debug) {
665
-            PhpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150));
666
-        }
667
-        return $markup;
668
-    }
646
+	protected function documentFragmentToMarkup($fragment)
647
+	{
648
+		PhpQuery::debug('documentFragmentToMarkup');
649
+		$tmp                          = $fragment->isDocumentFragment;
650
+		$fragment->isDocumentFragment = false;
651
+		$markup                       = $fragment->markup();
652
+		if ($fragment->isXML) {
653
+			$markup = substr($markup, 0, strrpos($markup, '</fake>'));
654
+			if ($fragment->isXHTML) {
655
+				$markup = substr($markup, strpos($markup, '<fake') + 43);
656
+			} else {
657
+				$markup = substr($markup, strpos($markup, '<fake>') + 6);
658
+			}
659
+		} else {
660
+			$markup = substr($markup, strpos($markup, '<body>') + 6);
661
+			$markup = substr($markup, 0, strrpos($markup, '</body>'));
662
+		}
663
+		$fragment->isDocumentFragment = $tmp;
664
+		if (PhpQuery::$debug) {
665
+			PhpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150));
666
+		}
667
+		return $markup;
668
+	}
669 669
 
670
-    /**
671
-     * Return document markup, starting with optional $nodes as root.
672
-     *
673
-     * @param $nodes    \DOMNode|\DOMNodeList
674
-     * @return string
675
-     */
676
-    public function markup($nodes = null, $innerMarkup = false)
677
-    {
678
-        if (isset($nodes) && count($nodes) == 1
679
-            && $nodes[0] instanceof \DOMDocument
680
-        ) {
681
-            $nodes = null;
682
-        }
683
-        if (isset($nodes)) {
684
-            $markup = '';
685
-            if (!is_array($nodes) && !($nodes instanceof \DOMNodeList)) {
686
-                $nodes = array(
687
-                    $nodes
688
-                );
689
-            }
690
-            if ($this->isDocumentFragment && !$innerMarkup) {
691
-                foreach ($nodes as $i => $node) {
692
-                    if ($node->isSameNode($this->root)) {
693
-                        //	var_dump($node);
694
-                        $nodes = array_slice($nodes, 0, $i)
695
-                            + PhpQuery::DOMNodeListToArray($node->childNodes)
696
-                            + array_slice($nodes, $i + 1);
697
-                    }
698
-                }
699
-            }
700
-            if ($this->isXML && !$innerMarkup) {
701
-                self::debug("Getting outerXML with charset '{$this->charset}'");
702
-                // we need outerXML, so we can benefit from
703
-                // $node param support in saveXML()
704
-                foreach ($nodes as $node) {
705
-                    $markup .= $this->document->saveXML($node);
706
-                }
707
-            } else {
708
-                $loop = array();
709
-                if ($innerMarkup) {
710
-                    foreach ($nodes as $node) {
711
-                        if ($node->childNodes) {
712
-                            foreach ($node->childNodes as $child) {
713
-                                $loop[] = $child;
714
-                            }
715
-                        } else {
716
-                            $loop[] = $node;
717
-                        }
718
-                    }
719
-                } else {
720
-                    $loop = $nodes;
721
-                }
722
-                self::debug(
723
-                    "Getting markup, moving selected nodes (" . count($loop)
724
-                    . ") to new DocumentFragment"
725
-                );
726
-                $fake   = $this->documentFragmentCreate($loop);
727
-                $markup = $this->documentFragmentToMarkup($fake);
728
-            }
729
-            if ($this->isXHTML) {
730
-                self::debug("Fixing XHTML");
731
-                $markup = self::markupFixXHTML($markup);
732
-            }
733
-            self::debug("Markup: " . substr($markup, 0, 250));
734
-            return $markup;
735
-        } else {
736
-            if ($this->isDocumentFragment) {
737
-                // documentFragment, html only...
738
-                self::debug("Getting markup, DocumentFragment detected");
739
-                //				return $this->markup(
740
-                ////					$this->document->getElementsByTagName('body')->item(0)
741
-                //					$this->document->root, true
742
-                //				);
743
-                $markup = $this->documentFragmentToMarkup($this);
744
-                // no need for markupFixXHTML, as it's done thought markup($nodes) method
745
-                return $markup;
746
-            } else {
747
-                self::debug(
748
-                    "Getting markup (" . ($this->isXML ? 'XML' : 'HTML')
749
-                    . "), final with charset '{$this->charset}'"
750
-                );
751
-                $markup = $this->isXML ? $this->document->saveXML()
752
-                    : $this->document->saveHTML();
753
-                if ($this->isXHTML) {
754
-                    self::debug("Fixing XHTML");
755
-                    $markup = self::markupFixXHTML($markup);
756
-                }
757
-                self::debug("Markup: " . substr($markup, 0, 250));
758
-                return $markup;
759
-            }
760
-        }
761
-    }
670
+	/**
671
+	 * Return document markup, starting with optional $nodes as root.
672
+	 *
673
+	 * @param $nodes    \DOMNode|\DOMNodeList
674
+	 * @return string
675
+	 */
676
+	public function markup($nodes = null, $innerMarkup = false)
677
+	{
678
+		if (isset($nodes) && count($nodes) == 1
679
+			&& $nodes[0] instanceof \DOMDocument
680
+		) {
681
+			$nodes = null;
682
+		}
683
+		if (isset($nodes)) {
684
+			$markup = '';
685
+			if (!is_array($nodes) && !($nodes instanceof \DOMNodeList)) {
686
+				$nodes = array(
687
+					$nodes
688
+				);
689
+			}
690
+			if ($this->isDocumentFragment && !$innerMarkup) {
691
+				foreach ($nodes as $i => $node) {
692
+					if ($node->isSameNode($this->root)) {
693
+						//	var_dump($node);
694
+						$nodes = array_slice($nodes, 0, $i)
695
+							+ PhpQuery::DOMNodeListToArray($node->childNodes)
696
+							+ array_slice($nodes, $i + 1);
697
+					}
698
+				}
699
+			}
700
+			if ($this->isXML && !$innerMarkup) {
701
+				self::debug("Getting outerXML with charset '{$this->charset}'");
702
+				// we need outerXML, so we can benefit from
703
+				// $node param support in saveXML()
704
+				foreach ($nodes as $node) {
705
+					$markup .= $this->document->saveXML($node);
706
+				}
707
+			} else {
708
+				$loop = array();
709
+				if ($innerMarkup) {
710
+					foreach ($nodes as $node) {
711
+						if ($node->childNodes) {
712
+							foreach ($node->childNodes as $child) {
713
+								$loop[] = $child;
714
+							}
715
+						} else {
716
+							$loop[] = $node;
717
+						}
718
+					}
719
+				} else {
720
+					$loop = $nodes;
721
+				}
722
+				self::debug(
723
+					"Getting markup, moving selected nodes (" . count($loop)
724
+					. ") to new DocumentFragment"
725
+				);
726
+				$fake   = $this->documentFragmentCreate($loop);
727
+				$markup = $this->documentFragmentToMarkup($fake);
728
+			}
729
+			if ($this->isXHTML) {
730
+				self::debug("Fixing XHTML");
731
+				$markup = self::markupFixXHTML($markup);
732
+			}
733
+			self::debug("Markup: " . substr($markup, 0, 250));
734
+			return $markup;
735
+		} else {
736
+			if ($this->isDocumentFragment) {
737
+				// documentFragment, html only...
738
+				self::debug("Getting markup, DocumentFragment detected");
739
+				//				return $this->markup(
740
+				////					$this->document->getElementsByTagName('body')->item(0)
741
+				//					$this->document->root, true
742
+				//				);
743
+				$markup = $this->documentFragmentToMarkup($this);
744
+				// no need for markupFixXHTML, as it's done thought markup($nodes) method
745
+				return $markup;
746
+			} else {
747
+				self::debug(
748
+					"Getting markup (" . ($this->isXML ? 'XML' : 'HTML')
749
+					. "), final with charset '{$this->charset}'"
750
+				);
751
+				$markup = $this->isXML ? $this->document->saveXML()
752
+					: $this->document->saveHTML();
753
+				if ($this->isXHTML) {
754
+					self::debug("Fixing XHTML");
755
+					$markup = self::markupFixXHTML($markup);
756
+				}
757
+				self::debug("Markup: " . substr($markup, 0, 250));
758
+				return $markup;
759
+			}
760
+		}
761
+	}
762 762
 
763
-    protected static function markupFixXHTML($markup)
764
-    {
765
-        $markup = self::expandEmptyTag('script', $markup);
766
-        $markup = self::expandEmptyTag('select', $markup);
767
-        $markup = self::expandEmptyTag('textarea', $markup);
768
-        return $markup;
769
-    }
763
+	protected static function markupFixXHTML($markup)
764
+	{
765
+		$markup = self::expandEmptyTag('script', $markup);
766
+		$markup = self::expandEmptyTag('select', $markup);
767
+		$markup = self::expandEmptyTag('textarea', $markup);
768
+		return $markup;
769
+	}
770 770
 
771
-    public static function debug($text)
772
-    {
773
-        PhpQuery::debug($text);
774
-    }
771
+	public static function debug($text)
772
+	{
773
+		PhpQuery::debug($text);
774
+	}
775 775
 
776
-    /**
777
-     * expandEmptyTag
778
-     *
779
-     * @param $tag
780
-     * @param $xml
781
-     * @return string
782
-     * @author mjaque at ilkebenson dot com
783
-     * @link   http://php.net/manual/en/domdocument.savehtml.php#81256
784
-     */
785
-    public static function expandEmptyTag($tag, $xml)
786
-    {
787
-        $indice = 0;
788
-        while ($indice < strlen($xml)) {
789
-            $pos = strpos($xml, "<$tag ", $indice);
790
-            if ($pos) {
791
-                $posCierre = strpos($xml, ">", $pos);
792
-                if ($xml[$posCierre - 1] == "/") {
793
-                    $xml = substr_replace($xml, "></$tag>", $posCierre - 1, 2);
794
-                }
795
-                $indice = $posCierre;
796
-            } else {
797
-                break;
798
-            }
799
-        }
800
-        return $xml;
801
-    }
776
+	/**
777
+	 * expandEmptyTag
778
+	 *
779
+	 * @param $tag
780
+	 * @param $xml
781
+	 * @return string
782
+	 * @author mjaque at ilkebenson dot com
783
+	 * @link   http://php.net/manual/en/domdocument.savehtml.php#81256
784
+	 */
785
+	public static function expandEmptyTag($tag, $xml)
786
+	{
787
+		$indice = 0;
788
+		while ($indice < strlen($xml)) {
789
+			$pos = strpos($xml, "<$tag ", $indice);
790
+			if ($pos) {
791
+				$posCierre = strpos($xml, ">", $pos);
792
+				if ($xml[$posCierre - 1] == "/") {
793
+					$xml = substr_replace($xml, "></$tag>", $posCierre - 1, 2);
794
+				}
795
+				$indice = $posCierre;
796
+			} else {
797
+				break;
798
+			}
799
+		}
800
+		return $xml;
801
+	}
802 802
 }
Please login to merge, or discard this patch.
Spacing   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
     protected function loadMarkupHTML($markup, $requestedCharset = null)
154 154
     {
155 155
         if (PhpQuery::$debug) {
156
-            PhpQuery::debug('Full markup load (HTML): ' . substr($markup, 0, 250));
156
+            PhpQuery::debug('Full markup load (HTML): '.substr($markup, 0, 250));
157 157
         }
158 158
         $this->loadMarkupReset();
159 159
         $this->isHTML = true;
@@ -197,7 +197,7 @@  discard block
 block discarded – undo
197 197
                     $requestedCharset,
198 198
                     'AUTO'
199 199
                 );
200
-                $docEncoding      = mb_detect_encoding($markup, implode(', ', $possibleCharsets));
200
+                $docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets));
201 201
                 if (!$docEncoding) {
202 202
                     $docEncoding = $documentCharset;
203 203
                 }
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
     protected function loadMarkupXML($markup, $requestedCharset = null)
244 244
     {
245 245
         if (PhpQuery::$debug) {
246
-            PhpQuery::debug('Full markup load (XML): ' . substr($markup, 0, 250));
246
+            PhpQuery::debug('Full markup load (XML): '.substr($markup, 0, 250));
247 247
         }
248 248
         $this->loadMarkupReset();
249 249
         $this->isXML = true;
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
                     | LIBXML_DTDATTR | LIBXML_NONET
321 321
                     : LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NONET | LIBXML_NOWARNING
322 322
                     | LIBXML_NOERROR;
323
-                $return       = $this->document->loadXML($markup, $libxmlStatic);
323
+                $return = $this->document->loadXML($markup, $libxmlStatic);
324 324
                 // 				if (! $return)
325 325
                 // 					$return = $this->document->loadHTML($markup);
326 326
             }
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
     protected function isXML($markup)
359 359
     {
360 360
         //		return strpos($markup, '<?xml') !== false && stripos($markup, 'xhtml') === false;
361
-        return strpos(substr($markup, 0, 100), '<' . '?xml') !== false;
361
+        return strpos(substr($markup, 0, 100), '<'.'?xml') !== false;
362 362
     }
363 363
 
364 364
     protected function contentTypeToArray($contentType)
@@ -413,7 +413,7 @@  discard block
 block discarded – undo
413 413
     {
414 414
         $matches;
415 415
         // find declaration
416
-        preg_match('@<' . '?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches);
416
+        preg_match('@<'.'?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i', $markup, $matches);
417 417
         return isset($matches[2]) ? strtolower($matches[2]) : null;
418 418
     }
419 419
 
@@ -440,7 +440,7 @@  discard block
 block discarded – undo
440 440
         $markup          = substr($markup, 0, $matches[0][1])
441 441
             . substr($markup, $matches[0][1] + strlen($metaContentType));
442 442
         $headStart       = stripos($markup, '<head>');
443
-        $markup          = substr($markup, 0, $headStart + 6) . $metaContentType
443
+        $markup          = substr($markup, 0, $headStart + 6).$metaContentType
444 444
             . substr($markup, $headStart + 6);
445 445
         return $markup;
446 446
     }
@@ -450,23 +450,23 @@  discard block
 block discarded – undo
450 450
         // remove existing meta[type=content-type]
451 451
         $html = preg_replace('@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i', '', $html);
452 452
         $meta = '<meta http-equiv="Content-Type" content="text/html;charset='
453
-            . $charset . '" ' . ($xhtml ? '/' : '') . '>';
453
+            . $charset.'" '.($xhtml ? '/' : '').'>';
454 454
         if (strpos($html, '<head') === false) {
455 455
             if (strpos($html, '<html') === false) {
456
-                return $meta . $html;
456
+                return $meta.$html;
457 457
             } else {
458 458
                 return preg_replace('@<html(.*?)(?(?<!\?)>)@s', "<html\\1><head>{$meta}</head>", $html);
459 459
             }
460 460
         } else {
461
-            return preg_replace('@<head(.*?)(?(?<!\?)>)@s', '<head\\1>' . $meta, $html);
461
+            return preg_replace('@<head(.*?)(?(?<!\?)>)@s', '<head\\1>'.$meta, $html);
462 462
         }
463 463
     }
464 464
 
465 465
     protected function charsetAppendToXML($markup, $charset)
466 466
     {
467
-        $declaration = '<' . '?xml version="1.0" encoding="' . $charset . '"?'
467
+        $declaration = '<'.'?xml version="1.0" encoding="'.$charset.'"?'
468 468
             . '>';
469
-        return $declaration . $markup;
469
+        return $declaration.$markup;
470 470
     }
471 471
 
472 472
     public static function isDocumentFragmentHTML($markup)
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
 
478 478
     public static function isDocumentFragmentXML($markup)
479 479
     {
480
-        return stripos($markup, '<' . '?xml') === false;
480
+        return stripos($markup, '<'.'?xml') === false;
481 481
     }
482 482
 
483 483
     public static function isDocumentFragmentXHTML($markup)
@@ -604,24 +604,24 @@  discard block
 block discarded – undo
604 604
             if ($fragment->isXHTML) {
605 605
                 // add FAKE element to set default namespace
606 606
                 $fragment->loadMarkupXML(
607
-                    '<?xml version="1.0" encoding="' . $charset
607
+                    '<?xml version="1.0" encoding="'.$charset
608 608
                     . '"?>'
609 609
                     . '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
610 610
                     . '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
611
-                    . '<fake xmlns="http://www.w3.org/1999/xhtml">' . $markup . '</fake>'
611
+                    . '<fake xmlns="http://www.w3.org/1999/xhtml">'.$markup.'</fake>'
612 612
                 );
613 613
                 $fragment->root = $fragment->document->firstChild->nextSibling;
614 614
             } else {
615 615
                 $fragment->loadMarkupXML(
616
-                    '<?xml version="1.0" encoding="' . $charset
617
-                    . '"?><fake>' . $markup . '</fake>'
616
+                    '<?xml version="1.0" encoding="'.$charset
617
+                    . '"?><fake>'.$markup.'</fake>'
618 618
                 );
619 619
                 $fragment->root = $fragment->document->firstChild;
620 620
             }
621 621
         } else {
622 622
             $markup2 = PhpQuery::$defaultDoctype
623 623
                 . '<html><head><meta http-equiv="Content-Type" content="text/html;charset='
624
-                . $charset . '"></head>';
624
+                . $charset.'"></head>';
625 625
             $noBody  = strpos($markup, '<body') === false;
626 626
             if ($noBody) {
627 627
                 $markup2 .= '<body>';
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
         }
663 663
         $fragment->isDocumentFragment = $tmp;
664 664
         if (PhpQuery::$debug) {
665
-            PhpQuery::debug('documentFragmentToMarkup: ' . substr($markup, 0, 150));
665
+            PhpQuery::debug('documentFragmentToMarkup: '.substr($markup, 0, 150));
666 666
         }
667 667
         return $markup;
668 668
     }
@@ -720,7 +720,7 @@  discard block
 block discarded – undo
720 720
                     $loop = $nodes;
721 721
                 }
722 722
                 self::debug(
723
-                    "Getting markup, moving selected nodes (" . count($loop)
723
+                    "Getting markup, moving selected nodes (".count($loop)
724 724
                     . ") to new DocumentFragment"
725 725
                 );
726 726
                 $fake   = $this->documentFragmentCreate($loop);
@@ -730,7 +730,7 @@  discard block
 block discarded – undo
730 730
                 self::debug("Fixing XHTML");
731 731
                 $markup = self::markupFixXHTML($markup);
732 732
             }
733
-            self::debug("Markup: " . substr($markup, 0, 250));
733
+            self::debug("Markup: ".substr($markup, 0, 250));
734 734
             return $markup;
735 735
         } else {
736 736
             if ($this->isDocumentFragment) {
@@ -745,7 +745,7 @@  discard block
 block discarded – undo
745 745
                 return $markup;
746 746
             } else {
747 747
                 self::debug(
748
-                    "Getting markup (" . ($this->isXML ? 'XML' : 'HTML')
748
+                    "Getting markup (".($this->isXML ? 'XML' : 'HTML')
749 749
                     . "), final with charset '{$this->charset}'"
750 750
                 );
751 751
                 $markup = $this->isXML ? $this->document->saveXML()
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
                     self::debug("Fixing XHTML");
755 755
                     $markup = self::markupFixXHTML($markup);
756 756
                 }
757
-                self::debug("Markup: " . substr($markup, 0, 250));
757
+                self::debug("Markup: ".substr($markup, 0, 250));
758 758
                 return $markup;
759 759
             }
760 760
         }
Please login to merge, or discard this patch.
src/PhpQuery.php 4 patches
Doc Comments   +17 added lines, -5 removed lines patch added patch discarded remove patch
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
      * Creates new document from markup.
339 339
      * Chainable.
340 340
      *
341
-     * @param null $markup
341
+     * @param string $markup
342 342
      * @param null $charset
343 343
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
344 344
      */
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
      * Creates new document from markup.
381 381
      * Chainable.
382 382
      *
383
-     * @param null   $markup
383
+     * @param string   $markup
384 384
      * @param string $contentType
385 385
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
386 386
      */
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
     /**
572 572
      * Enter description here...
573 573
      *
574
-     * @param      $html
574
+     * @param      string $html
575 575
      * @param null $contentType
576 576
      * @param null $documentID
577 577
      * @return null|string
@@ -737,7 +737,7 @@  discard block
 block discarded – undo
737 737
     /**
738 738
      * Unloades all or specified document from memory.
739 739
      *
740
-     * @param null $id
740
+     * @param string $id
741 741
      * @internal param mixed $documentID @see PhpQuery::getDocumentID() for supported types.
742 742
      */
743 743
     public static function unloadDocuments($id = null)
@@ -1128,6 +1128,9 @@  discard block
 block discarded – undo
1128 1128
         self::$ajaxSettings = array_merge(self::$ajaxSettings, $options);
1129 1129
     }
1130 1130
 
1131
+    /**
1132
+     * @param string|false $host1
1133
+     */
1131 1134
     public static function ajaxAllowHost($host1, $host2 = null, $host3 = null)
1132 1135
     {
1133 1136
         $loop = is_array($host1) ? $host1 : func_get_args();
@@ -1138,6 +1141,9 @@  discard block
 block discarded – undo
1138 1141
         }
1139 1142
     }
1140 1143
 
1144
+    /**
1145
+     * @param string $url1
1146
+     */
1141 1147
     public static function ajaxAllowURL($url1, $url2 = null, $url3 = null)
1142 1148
     {
1143 1149
         $loop = is_array($url1) ? $url1 : func_get_args();
@@ -1515,7 +1521,7 @@  discard block
 block discarded – undo
1515 1521
 
1516 1522
     /**
1517 1523
      *
1518
-     * @param $type
1524
+     * @param string $type
1519 1525
      * @param $code
1520 1526
      * @return string
1521 1527
      */
@@ -1558,6 +1564,9 @@  discard block
 block discarded – undo
1558 1564
         }
1559 1565
     }
1560 1566
 
1567
+    /**
1568
+     * @param string $documentID
1569
+     */
1561 1570
     public static function data($node, $name, $data, $documentID = null)
1562 1571
     {
1563 1572
         if (!$documentID)
@@ -1579,6 +1588,9 @@  discard block
 block discarded – undo
1579 1588
             return $id;
1580 1589
     }
1581 1590
 
1591
+    /**
1592
+     * @param string $documentID
1593
+     */
1582 1594
     public static function removeData($node, $name, $documentID)
1583 1595
     {
1584 1596
         if (!$documentID)
Please login to merge, or discard this patch.
Indentation   +1568 added lines, -1568 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
  */
30 30
 function pq($arg1, $context = null)
31 31
 {
32
-    return PhpQuery::pq($arg1, $context);
32
+	return PhpQuery::pq($arg1, $context);
33 33
 }
34 34
 
35 35
 /**
@@ -40,1565 +40,1565 @@  discard block
 block discarded – undo
40 40
  */
41 41
 abstract class PhpQuery
42 42
 {
43
-    /**
44
-     * XXX: Workaround for mbstring problems
45
-     *
46
-     * @var bool
47
-     */
48
-    public static $mbstringSupport = true;
49
-    public static $debug = false;
50
-    public static $documents = array();
51
-    public static $defaultDocumentID = null;
52
-    //	public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"';
53
-    /**
54
-     * Applies only to HTML.
55
-     *
56
-     * @var string
57
-     */
58
-    public static $defaultDoctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
43
+	/**
44
+	 * XXX: Workaround for mbstring problems
45
+	 *
46
+	 * @var bool
47
+	 */
48
+	public static $mbstringSupport = true;
49
+	public static $debug = false;
50
+	public static $documents = array();
51
+	public static $defaultDocumentID = null;
52
+	//	public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"';
53
+	/**
54
+	 * Applies only to HTML.
55
+	 *
56
+	 * @var string
57
+	 */
58
+	public static $defaultDoctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
59 59
 "http://www.w3.org/TR/html4/loose.dtd">';
60
-    public static $defaultCharset = 'UTF-8';
61
-    /**
62
-     * Static namespace for plugins.
63
-     *
64
-     * @var object
65
-     */
66
-    public static $plugins = array();
67
-    /**
68
-     * List of loaded plugins.
69
-     *
70
-     * @var array
71
-     */
72
-    public static $pluginsLoaded = array();
73
-    public static $pluginsMethods = array();
74
-    public static $pluginsStaticMethods = array();
75
-    public static $extendMethods = array();
76
-    /**
77
-     * @TODO implement
78
-     */
79
-    public static $extendStaticMethods = array();
80
-    /**
81
-     * Hosts allowed for AJAX connections.
82
-     * Dot '.' means $_SERVER['HTTP_HOST'] (if any).
83
-     *
84
-     * @var array
85
-     */
86
-    public static $ajaxAllowedHosts = array(
87
-        '.'
88
-    );
89
-    /**
90
-     * AJAX settings.
91
-     *
92
-     * @var array
93
-     * XXX should it be static or not ?
94
-     */
95
-    public static $ajaxSettings = array(
96
-        'url'         => '',
97
-        //TODO
98
-        'global'      => true,
99
-        'type'        => "GET",
100
-        'timeout'     => null,
101
-        'contentType' => "application/x-www-form-urlencoded",
102
-        'processData' => true,
103
-        //		'async' => true,
104
-        'data'        => null,
105
-        'username'    => null,
106
-        'password'    => null,
107
-        'dataType'    => null,
108
-        'ifModified'  => null,
109
-        'accepts'     => array(
110
-            'xml'      => "application/xml, text/xml",
111
-            'html'     => "text/html",
112
-            'script'   => "text/javascript, application/javascript",
113
-            'json'     => "application/json, text/javascript",
114
-            'text'     => "text/plain",
115
-            '_default' => "*/*"
116
-        )
117
-    );
118
-    public static $lastModified = null;
119
-    public static $active = 0;
120
-    public static $dumpCount = 0;
121
-    public static $enableCssShorthand = false;
122
-
123
-    public static function use_function($ns = '\\', $func = 'pq')
124
-    {
125
-        if ($ns{0} !== '\\') {
126
-            $ns = '\\' . $ns;
127
-        }
128
-        if (!function_exists($ns . '\\' . $func)) {
129
-            if ($ns === '\\') {
130
-                eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }");
131
-            } else {
132
-                $ns = substr($ns, 1);
133
-                eval("namespace $ns { function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); } }");
134
-            }
135
-        }
136
-    }
137
-
138
-
139
-    /**
140
-     * Multi-purpose function.
141
-     * Use pq() as shortcut.
142
-     *
143
-     * In below examples, $pq is any result of pq(); function.
144
-     *
145
-     * 1. Import markup into existing document (without any attaching):
146
-     * - Import into selected document:
147
-     *   pq('<div/>')                // DOESNT accept text nodes at beginning of input string !
148
-     * - Import into document with ID from $pq->getDocumentID():
149
-     *   pq('<div/>', $pq->getDocumentID())
150
-     * - Import into same document as \DOMNode belongs to:
151
-     *   pq('<div/>', \DOMNode)
152
-     * - Import into document from PhpQuery object:
153
-     *   pq('<div/>', $pq)
154
-     *
155
-     * 2. Run query:
156
-     * - Run query on last selected document:
157
-     *   pq('div.myClass')
158
-     * - Run query on document with ID from $pq->getDocumentID():
159
-     *   pq('div.myClass', $pq->getDocumentID())
160
-     * - Run query on same document as \DOMNode belongs to and use node(s)as root for query:
161
-     *   pq('div.myClass', \DOMNode)
162
-     * - Run query on document from PhpQuery object
163
-     *   and use object's stack as root node(s) for query:
164
-     *   pq('div.myClass', $pq)
165
-     *
166
-     * @param string|\DOMNode|\DOMNodeList|array $arg1    HTML markup, CSS Selector, \DOMNode or array of \DOMNodes
167
-     * @param string|PhpQueryObject|\DOMNode     $context DOM ID from $pq->getDocumentID(), PhpQuery object (determines also query root) or \DOMNode (determines also query root)
168
-     *
169
-     * @throws \Exception
170
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false
171
-     * PhpQuery object or false in case of error.
172
-     */
173
-    public static function pq($arg1, $context = null)
174
-    {
175
-        if ($arg1 instanceof \DOMNode && !isset($context)) {
176
-            foreach (PhpQuery::$documents as $documentWrapper) {
177
-                $compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument;
178
-                if ($documentWrapper->document->isSameNode($compare)) {
179
-                    $context = $documentWrapper->id;
180
-                }
181
-            }
182
-        }
183
-        if (!$context) {
184
-            $domId = self::$defaultDocumentID;
185
-            if (!$domId) {
186
-                throw new \Exception("Can't use last created DOM, because there isn't any. Use PhpQuery::newDocument() first.");
187
-            }
188
-            //		} else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject')))
189
-        } else {
190
-            if (is_object($context) && $context instanceof PhpQueryObject) {
191
-                $domId = $context->getDocumentID();
192
-            } else {
193
-                if ($context instanceof \DOMDocument) {
194
-                    $domId = self::getDocumentID($context);
195
-                    if (!$domId) {
196
-                        //throw new \Exception('Orphaned \DOMDocument');
197
-                        $domId = self::newDocument($context)->getDocumentID();
198
-                    }
199
-                } else {
200
-                    if ($context instanceof \DOMNode) {
201
-                        $domId = self::getDocumentID($context);
202
-                        if (!$domId) {
203
-                            throw new \Exception('Orphaned DOMNode');
204
-                            //				$domId = self::newDocument($context->ownerDocument);
205
-                        }
206
-                    } else {
207
-                        $domId = $context;
208
-                    }
209
-                }
210
-            }
211
-        }
212
-        if ($arg1 instanceof PhpQueryObject) {
213
-            //		if (is_object($arg1) && (get_class($arg1) == 'PhpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'PhpQueryObject'))) {
214
-            /**
215
-             * Return $arg1 or import $arg1 stack if document differs:
216
-             * pq(pq('<div/>'))
217
-             */
218
-            if ($arg1->getDocumentID() == $domId) {
219
-                return $arg1;
220
-            }
221
-            $class = get_class($arg1);
222
-            // support inheritance by passing old object to overloaded constructor
223
-            $PhpQuery           = $class != 'PhpQuery' ? new $class($arg1, $domId)
224
-                : new PhpQueryObject($domId);
225
-            $PhpQuery->elements = array();
226
-            foreach ($arg1->elements as $node) {
227
-                $PhpQuery->elements[] = $PhpQuery->document->importNode($node, true);
228
-            }
229
-            return $PhpQuery;
230
-        } else {
231
-            if ($arg1 instanceof \DOMNode
232
-                || (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode)
233
-            ) {
234
-                /*
60
+	public static $defaultCharset = 'UTF-8';
61
+	/**
62
+	 * Static namespace for plugins.
63
+	 *
64
+	 * @var object
65
+	 */
66
+	public static $plugins = array();
67
+	/**
68
+	 * List of loaded plugins.
69
+	 *
70
+	 * @var array
71
+	 */
72
+	public static $pluginsLoaded = array();
73
+	public static $pluginsMethods = array();
74
+	public static $pluginsStaticMethods = array();
75
+	public static $extendMethods = array();
76
+	/**
77
+	 * @TODO implement
78
+	 */
79
+	public static $extendStaticMethods = array();
80
+	/**
81
+	 * Hosts allowed for AJAX connections.
82
+	 * Dot '.' means $_SERVER['HTTP_HOST'] (if any).
83
+	 *
84
+	 * @var array
85
+	 */
86
+	public static $ajaxAllowedHosts = array(
87
+		'.'
88
+	);
89
+	/**
90
+	 * AJAX settings.
91
+	 *
92
+	 * @var array
93
+	 * XXX should it be static or not ?
94
+	 */
95
+	public static $ajaxSettings = array(
96
+		'url'         => '',
97
+		//TODO
98
+		'global'      => true,
99
+		'type'        => "GET",
100
+		'timeout'     => null,
101
+		'contentType' => "application/x-www-form-urlencoded",
102
+		'processData' => true,
103
+		//		'async' => true,
104
+		'data'        => null,
105
+		'username'    => null,
106
+		'password'    => null,
107
+		'dataType'    => null,
108
+		'ifModified'  => null,
109
+		'accepts'     => array(
110
+			'xml'      => "application/xml, text/xml",
111
+			'html'     => "text/html",
112
+			'script'   => "text/javascript, application/javascript",
113
+			'json'     => "application/json, text/javascript",
114
+			'text'     => "text/plain",
115
+			'_default' => "*/*"
116
+		)
117
+	);
118
+	public static $lastModified = null;
119
+	public static $active = 0;
120
+	public static $dumpCount = 0;
121
+	public static $enableCssShorthand = false;
122
+
123
+	public static function use_function($ns = '\\', $func = 'pq')
124
+	{
125
+		if ($ns{0} !== '\\') {
126
+			$ns = '\\' . $ns;
127
+		}
128
+		if (!function_exists($ns . '\\' . $func)) {
129
+			if ($ns === '\\') {
130
+				eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }");
131
+			} else {
132
+				$ns = substr($ns, 1);
133
+				eval("namespace $ns { function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); } }");
134
+			}
135
+		}
136
+	}
137
+
138
+
139
+	/**
140
+	 * Multi-purpose function.
141
+	 * Use pq() as shortcut.
142
+	 *
143
+	 * In below examples, $pq is any result of pq(); function.
144
+	 *
145
+	 * 1. Import markup into existing document (without any attaching):
146
+	 * - Import into selected document:
147
+	 *   pq('<div/>')                // DOESNT accept text nodes at beginning of input string !
148
+	 * - Import into document with ID from $pq->getDocumentID():
149
+	 *   pq('<div/>', $pq->getDocumentID())
150
+	 * - Import into same document as \DOMNode belongs to:
151
+	 *   pq('<div/>', \DOMNode)
152
+	 * - Import into document from PhpQuery object:
153
+	 *   pq('<div/>', $pq)
154
+	 *
155
+	 * 2. Run query:
156
+	 * - Run query on last selected document:
157
+	 *   pq('div.myClass')
158
+	 * - Run query on document with ID from $pq->getDocumentID():
159
+	 *   pq('div.myClass', $pq->getDocumentID())
160
+	 * - Run query on same document as \DOMNode belongs to and use node(s)as root for query:
161
+	 *   pq('div.myClass', \DOMNode)
162
+	 * - Run query on document from PhpQuery object
163
+	 *   and use object's stack as root node(s) for query:
164
+	 *   pq('div.myClass', $pq)
165
+	 *
166
+	 * @param string|\DOMNode|\DOMNodeList|array $arg1    HTML markup, CSS Selector, \DOMNode or array of \DOMNodes
167
+	 * @param string|PhpQueryObject|\DOMNode     $context DOM ID from $pq->getDocumentID(), PhpQuery object (determines also query root) or \DOMNode (determines also query root)
168
+	 *
169
+	 * @throws \Exception
170
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false
171
+	 * PhpQuery object or false in case of error.
172
+	 */
173
+	public static function pq($arg1, $context = null)
174
+	{
175
+		if ($arg1 instanceof \DOMNode && !isset($context)) {
176
+			foreach (PhpQuery::$documents as $documentWrapper) {
177
+				$compare = $arg1 instanceof \DOMDocument ? $arg1 : $arg1->ownerDocument;
178
+				if ($documentWrapper->document->isSameNode($compare)) {
179
+					$context = $documentWrapper->id;
180
+				}
181
+			}
182
+		}
183
+		if (!$context) {
184
+			$domId = self::$defaultDocumentID;
185
+			if (!$domId) {
186
+				throw new \Exception("Can't use last created DOM, because there isn't any. Use PhpQuery::newDocument() first.");
187
+			}
188
+			//		} else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject')))
189
+		} else {
190
+			if (is_object($context) && $context instanceof PhpQueryObject) {
191
+				$domId = $context->getDocumentID();
192
+			} else {
193
+				if ($context instanceof \DOMDocument) {
194
+					$domId = self::getDocumentID($context);
195
+					if (!$domId) {
196
+						//throw new \Exception('Orphaned \DOMDocument');
197
+						$domId = self::newDocument($context)->getDocumentID();
198
+					}
199
+				} else {
200
+					if ($context instanceof \DOMNode) {
201
+						$domId = self::getDocumentID($context);
202
+						if (!$domId) {
203
+							throw new \Exception('Orphaned DOMNode');
204
+							//				$domId = self::newDocument($context->ownerDocument);
205
+						}
206
+					} else {
207
+						$domId = $context;
208
+					}
209
+				}
210
+			}
211
+		}
212
+		if ($arg1 instanceof PhpQueryObject) {
213
+			//		if (is_object($arg1) && (get_class($arg1) == 'PhpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'PhpQueryObject'))) {
214
+			/**
215
+			 * Return $arg1 or import $arg1 stack if document differs:
216
+			 * pq(pq('<div/>'))
217
+			 */
218
+			if ($arg1->getDocumentID() == $domId) {
219
+				return $arg1;
220
+			}
221
+			$class = get_class($arg1);
222
+			// support inheritance by passing old object to overloaded constructor
223
+			$PhpQuery           = $class != 'PhpQuery' ? new $class($arg1, $domId)
224
+				: new PhpQueryObject($domId);
225
+			$PhpQuery->elements = array();
226
+			foreach ($arg1->elements as $node) {
227
+				$PhpQuery->elements[] = $PhpQuery->document->importNode($node, true);
228
+			}
229
+			return $PhpQuery;
230
+		} else {
231
+			if ($arg1 instanceof \DOMNode
232
+				|| (is_array($arg1) && isset($arg1[0]) && $arg1[0] instanceof \DOMNode)
233
+			) {
234
+				/*
235 235
                  * Wrap DOM nodes with PhpQuery object, import into document when needed:
236 236
                  * pq(array($domNode1, $domNode2))
237 237
                  */
238
-                $PhpQuery = new PhpQueryObject($domId);
239
-                if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) {
240
-                    $arg1 = array(
241
-                        $arg1
242
-                    );
243
-                }
244
-                $PhpQuery->elements = array();
245
-                foreach ($arg1 as $node) {
246
-                    $sameDocument         = $node->ownerDocument instanceof \DOMDocument
247
-                        && !$node->ownerDocument->isSameNode($PhpQuery->document);
248
-                    $PhpQuery->elements[] = $sameDocument ? $PhpQuery->document->importNode($node, true)
249
-                        : $node;
250
-                }
251
-                return $PhpQuery;
252
-            } else {
253
-                if (self::isMarkup($arg1)) {
254
-                    /**
255
-                     * Import HTML:
256
-                     * pq('<div/>')
257
-                     */
258
-                    $PhpQuery = new PhpQueryObject($domId);
259
-                    return $PhpQuery->newInstance($PhpQuery->documentWrapper->import($arg1));
260
-                } else {
261
-                    /**
262
-                     * Run CSS query:
263
-                     * pq('div.myClass')
264
-                     */
265
-                    $PhpQuery = new PhpQueryObject($domId);
266
-                    //			if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject')))
267
-                    if ($context && $context instanceof PhpQueryObject) {
268
-                        $PhpQuery->elements = $context->elements;
269
-                    } else {
270
-                        if ($context && $context instanceof \DOMNodeList) {
271
-                            $PhpQuery->elements = array();
272
-                            foreach ($context as $node) {
273
-                                $PhpQuery->elements[] = $node;
274
-                            }
275
-                        } else {
276
-                            if ($context && $context instanceof \DOMNode) {
277
-                                $PhpQuery->elements = array(
278
-                                    $context
279
-                                );
280
-                            }
281
-                        }
282
-                    }
283
-                    return $PhpQuery->find($arg1);
284
-                }
285
-            }
286
-        }
287
-    }
288
-
289
-    /**
290
-     * Sets default document to $id. Document has to be loaded prior
291
-     * to using this method.
292
-     * $id can be retrived via getDocumentID() or getDocumentIDRef().
293
-     *
294
-     * @param string $id
295
-     */
296
-    public static function selectDocument($id)
297
-    {
298
-        $id = self::getDocumentID($id);
299
-        self::debug("Selecting document '$id' as default one");
300
-        self::$defaultDocumentID = self::getDocumentID($id);
301
-    }
302
-
303
-    /**
304
-     * Returns document with id $id or last used as PhpQueryObject.
305
-     * $id can be retrived via getDocumentID() or getDocumentIDRef().
306
-     * Chainable.
307
-     *
308
-     * @see PhpQuery::selectDocument()
309
-     * @param null $id
310
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
311
-     */
312
-    public static function getDocument($id = null)
313
-    {
314
-        if ($id)
315
-            PhpQuery::selectDocument($id);
316
-        else
317
-            $id = PhpQuery::$defaultDocumentID;
318
-        return new PhpQueryObject($id);
319
-    }
320
-
321
-    /**
322
-     * Creates new document from markup.
323
-     * Chainable.
324
-     *
325
-     * @param null $markup
326
-     * @param null $contentType
327
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
328
-     */
329
-    public static function newDocument($markup = null, $contentType = null)
330
-    {
331
-        if (!$markup)
332
-            $markup = '';
333
-        $documentID = PhpQuery::createDocumentWrapper($markup, $contentType);
334
-        return new PhpQueryObject($documentID);
335
-    }
336
-
337
-    /**
338
-     * Creates new document from markup.
339
-     * Chainable.
340
-     *
341
-     * @param null $markup
342
-     * @param null $charset
343
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
344
-     */
345
-    public static function newDocumentHTML($markup = null, $charset = null)
346
-    {
347
-        $contentType = $charset ? ";charset=$charset" : '';
348
-        return self::newDocument($markup, "text/html{$contentType}");
349
-    }
350
-
351
-    /**
352
-     * Creates new document from markup.
353
-     * Chainable.
354
-     *
355
-     * @param null $markup
356
-     * @param null $charset
357
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
358
-     */
359
-    public static function newDocumentXML($markup = null, $charset = null)
360
-    {
361
-        $contentType = $charset ? ";charset=$charset" : '';
362
-        return self::newDocument($markup, "text/xml{$contentType}");
363
-    }
364
-
365
-    /**
366
-     * Creates new document from markup.
367
-     * Chainable.
368
-     *
369
-     * @param null $markup
370
-     * @param null $charset
371
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
372
-     */
373
-    public static function newDocumentXHTML($markup = null, $charset = null)
374
-    {
375
-        $contentType = $charset ? ";charset=$charset" : '';
376
-        return self::newDocument($markup, "application/xhtml+xml{$contentType}");
377
-    }
378
-
379
-    /**
380
-     * Creates new document from markup.
381
-     * Chainable.
382
-     *
383
-     * @param null   $markup
384
-     * @param string $contentType
385
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
386
-     */
387
-    public static function newDocumentPHP($markup = null, $contentType = "text/html")
388
-    {
389
-        // TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function)
390
-        $markup = PhpQuery::phpToMarkup($markup, self::$defaultCharset);
391
-        return self::newDocument($markup, $contentType);
392
-    }
393
-
394
-    public static function phpToMarkup($php, $charset = 'utf-8')
395
-    {
396
-        $regexes = array(
397
-            '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<'
398
-            . '?php?(.*?)(?:\\?>)([^\']*)\'@s',
399
-            '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<'
400
-            . '?php?(.*?)(?:\\?>)([^"]*)"@s',
401
-        );
402
-        foreach ($regexes as $regex)
403
-            while (preg_match($regex, $php, $matches)) {
404
-                $php = preg_replace_callback(
405
-                    $regex,
406
-                    //					create_function('$m, $charset = "'.$charset.'"',
407
-                    //						'return $m[1].$m[2]
408
-                    //							.htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset)
409
-                    //							.$m[5].$m[2];'
410
-                    //					),
411
-                    array(
412
-                        'PhpQuery',
413
-                        '_phpToMarkupCallback'
414
-                    ),
415
-                    $php
416
-                );
417
-            }
418
-        $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s';
419
-        //preg_match_all($regex, $php, $matches);
420
-        //var_dump($matches);
421
-        $php = preg_replace($regex, '\\1<php><!-- \\3 --></php>', $php);
422
-        return $php;
423
-    }
424
-
425
-    public static function _phpToMarkupCallback($m, $charset = 'utf-8')
426
-    {
427
-        return $m[1] . $m[2]
428
-        . htmlspecialchars(
429
-            "<" . "?php" . $m[4] . "?" . ">",
430
-            ENT_QUOTES
431
-            | ENT_NOQUOTES,
432
-            $charset
433
-        ) . $m[5] . $m[2];
434
-    }
435
-
436
-    public static function _markupToPHPCallback($m)
437
-    {
438
-        return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">";
439
-    }
440
-
441
-    /**
442
-     * Converts document markup containing PHP code generated by PhpQuery::php()
443
-     * into valid (executable) PHP code syntax.
444
-     *
445
-     * @param string|PhpQueryObject $content
446
-     * @return string PHP code.
447
-     */
448
-    public static function markupToPHP($content)
449
-    {
450
-        if ($content instanceof PhpQueryObject)
451
-            $content = $content->markupOuter();
452
-        /* <php>...</php> to <?php...? > */
453
-        $content = preg_replace_callback(
454
-            '@<php>\s*<!--(.*?)-->\s*</php>@s',
455
-            //			create_function('$m',
456
-            //				'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";'
457
-            //			),
458
-            array(
459
-                'PhpQuery',
460
-                '_markupToPHPCallback'
461
-            ),
462
-            $content
463
-        );
464
-        /* <node attr='< ?php ? >'> extra space added to save highlighters */
465
-        $regexes = array(
466
-            '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^\']*)\'@s',
467
-            '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^"]*)"@s',
468
-        );
469
-        foreach ($regexes as $regex)
470
-            while (preg_match($regex, $content))
471
-                $content = preg_replace_callback(
472
-                    $regex,
473
-                    create_function(
474
-                        '$m',
475
-                        'return $m[1].$m[2].$m[3]."<?php "
238
+				$PhpQuery = new PhpQueryObject($domId);
239
+				if (!($arg1 instanceof \DOMNodeList) && !is_array($arg1)) {
240
+					$arg1 = array(
241
+						$arg1
242
+					);
243
+				}
244
+				$PhpQuery->elements = array();
245
+				foreach ($arg1 as $node) {
246
+					$sameDocument         = $node->ownerDocument instanceof \DOMDocument
247
+						&& !$node->ownerDocument->isSameNode($PhpQuery->document);
248
+					$PhpQuery->elements[] = $sameDocument ? $PhpQuery->document->importNode($node, true)
249
+						: $node;
250
+				}
251
+				return $PhpQuery;
252
+			} else {
253
+				if (self::isMarkup($arg1)) {
254
+					/**
255
+					 * Import HTML:
256
+					 * pq('<div/>')
257
+					 */
258
+					$PhpQuery = new PhpQueryObject($domId);
259
+					return $PhpQuery->newInstance($PhpQuery->documentWrapper->import($arg1));
260
+				} else {
261
+					/**
262
+					 * Run CSS query:
263
+					 * pq('div.myClass')
264
+					 */
265
+					$PhpQuery = new PhpQueryObject($domId);
266
+					//			if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'PhpQueryObject')))
267
+					if ($context && $context instanceof PhpQueryObject) {
268
+						$PhpQuery->elements = $context->elements;
269
+					} else {
270
+						if ($context && $context instanceof \DOMNodeList) {
271
+							$PhpQuery->elements = array();
272
+							foreach ($context as $node) {
273
+								$PhpQuery->elements[] = $node;
274
+							}
275
+						} else {
276
+							if ($context && $context instanceof \DOMNode) {
277
+								$PhpQuery->elements = array(
278
+									$context
279
+								);
280
+							}
281
+						}
282
+					}
283
+					return $PhpQuery->find($arg1);
284
+				}
285
+			}
286
+		}
287
+	}
288
+
289
+	/**
290
+	 * Sets default document to $id. Document has to be loaded prior
291
+	 * to using this method.
292
+	 * $id can be retrived via getDocumentID() or getDocumentIDRef().
293
+	 *
294
+	 * @param string $id
295
+	 */
296
+	public static function selectDocument($id)
297
+	{
298
+		$id = self::getDocumentID($id);
299
+		self::debug("Selecting document '$id' as default one");
300
+		self::$defaultDocumentID = self::getDocumentID($id);
301
+	}
302
+
303
+	/**
304
+	 * Returns document with id $id or last used as PhpQueryObject.
305
+	 * $id can be retrived via getDocumentID() or getDocumentIDRef().
306
+	 * Chainable.
307
+	 *
308
+	 * @see PhpQuery::selectDocument()
309
+	 * @param null $id
310
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
311
+	 */
312
+	public static function getDocument($id = null)
313
+	{
314
+		if ($id)
315
+			PhpQuery::selectDocument($id);
316
+		else
317
+			$id = PhpQuery::$defaultDocumentID;
318
+		return new PhpQueryObject($id);
319
+	}
320
+
321
+	/**
322
+	 * Creates new document from markup.
323
+	 * Chainable.
324
+	 *
325
+	 * @param null $markup
326
+	 * @param null $contentType
327
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
328
+	 */
329
+	public static function newDocument($markup = null, $contentType = null)
330
+	{
331
+		if (!$markup)
332
+			$markup = '';
333
+		$documentID = PhpQuery::createDocumentWrapper($markup, $contentType);
334
+		return new PhpQueryObject($documentID);
335
+	}
336
+
337
+	/**
338
+	 * Creates new document from markup.
339
+	 * Chainable.
340
+	 *
341
+	 * @param null $markup
342
+	 * @param null $charset
343
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
344
+	 */
345
+	public static function newDocumentHTML($markup = null, $charset = null)
346
+	{
347
+		$contentType = $charset ? ";charset=$charset" : '';
348
+		return self::newDocument($markup, "text/html{$contentType}");
349
+	}
350
+
351
+	/**
352
+	 * Creates new document from markup.
353
+	 * Chainable.
354
+	 *
355
+	 * @param null $markup
356
+	 * @param null $charset
357
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
358
+	 */
359
+	public static function newDocumentXML($markup = null, $charset = null)
360
+	{
361
+		$contentType = $charset ? ";charset=$charset" : '';
362
+		return self::newDocument($markup, "text/xml{$contentType}");
363
+	}
364
+
365
+	/**
366
+	 * Creates new document from markup.
367
+	 * Chainable.
368
+	 *
369
+	 * @param null $markup
370
+	 * @param null $charset
371
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
372
+	 */
373
+	public static function newDocumentXHTML($markup = null, $charset = null)
374
+	{
375
+		$contentType = $charset ? ";charset=$charset" : '';
376
+		return self::newDocument($markup, "application/xhtml+xml{$contentType}");
377
+	}
378
+
379
+	/**
380
+	 * Creates new document from markup.
381
+	 * Chainable.
382
+	 *
383
+	 * @param null   $markup
384
+	 * @param string $contentType
385
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
386
+	 */
387
+	public static function newDocumentPHP($markup = null, $contentType = "text/html")
388
+	{
389
+		// TODO pass charset to phpToMarkup if possible (use DOMDocumentWrapper function)
390
+		$markup = PhpQuery::phpToMarkup($markup, self::$defaultCharset);
391
+		return self::newDocument($markup, $contentType);
392
+	}
393
+
394
+	public static function phpToMarkup($php, $charset = 'utf-8')
395
+	{
396
+		$regexes = array(
397
+			'@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<'
398
+			. '?php?(.*?)(?:\\?>)([^\']*)\'@s',
399
+			'@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<'
400
+			. '?php?(.*?)(?:\\?>)([^"]*)"@s',
401
+		);
402
+		foreach ($regexes as $regex)
403
+			while (preg_match($regex, $php, $matches)) {
404
+				$php = preg_replace_callback(
405
+					$regex,
406
+					//					create_function('$m, $charset = "'.$charset.'"',
407
+					//						'return $m[1].$m[2]
408
+					//							.htmlspecialchars("<"."?php".$m[4]."?".">", ENT_QUOTES|ENT_NOQUOTES, $charset)
409
+					//							.$m[5].$m[2];'
410
+					//					),
411
+					array(
412
+						'PhpQuery',
413
+						'_phpToMarkupCallback'
414
+					),
415
+					$php
416
+				);
417
+			}
418
+		$regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s';
419
+		//preg_match_all($regex, $php, $matches);
420
+		//var_dump($matches);
421
+		$php = preg_replace($regex, '\\1<php><!-- \\3 --></php>', $php);
422
+		return $php;
423
+	}
424
+
425
+	public static function _phpToMarkupCallback($m, $charset = 'utf-8')
426
+	{
427
+		return $m[1] . $m[2]
428
+		. htmlspecialchars(
429
+			"<" . "?php" . $m[4] . "?" . ">",
430
+			ENT_QUOTES
431
+			| ENT_NOQUOTES,
432
+			$charset
433
+		) . $m[5] . $m[2];
434
+	}
435
+
436
+	public static function _markupToPHPCallback($m)
437
+	{
438
+		return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">";
439
+	}
440
+
441
+	/**
442
+	 * Converts document markup containing PHP code generated by PhpQuery::php()
443
+	 * into valid (executable) PHP code syntax.
444
+	 *
445
+	 * @param string|PhpQueryObject $content
446
+	 * @return string PHP code.
447
+	 */
448
+	public static function markupToPHP($content)
449
+	{
450
+		if ($content instanceof PhpQueryObject)
451
+			$content = $content->markupOuter();
452
+		/* <php>...</php> to <?php...? > */
453
+		$content = preg_replace_callback(
454
+			'@<php>\s*<!--(.*?)-->\s*</php>@s',
455
+			//			create_function('$m',
456
+			//				'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";'
457
+			//			),
458
+			array(
459
+				'PhpQuery',
460
+				'_markupToPHPCallback'
461
+			),
462
+			$content
463
+		);
464
+		/* <node attr='< ?php ? >'> extra space added to save highlighters */
465
+		$regexes = array(
466
+			'@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^\']*)\'@s',
467
+			'@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^"]*)"@s',
468
+		);
469
+		foreach ($regexes as $regex)
470
+			while (preg_match($regex, $content))
471
+				$content = preg_replace_callback(
472
+					$regex,
473
+					create_function(
474
+						'$m',
475
+						'return $m[1].$m[2].$m[3]."<?php "
476 476
                                                    .str_replace(
477 477
                                                        array("%20", "%3E", "%09", "&#10;", "&#9;", "%7B", "%24", "%7D", "%22", "%5B", "%5D"),
478 478
                                                        array(" ", ">", "	", "\n", "	", "{", "$", "}", \'"\', "[", "]"),
479 479
                                                        htmlspecialchars_decode($m[4])
480 480
                                                    )
481 481
                                                    ." ?>".$m[5].$m[2];'
482
-                    ),
483
-                    $content
484
-                );
485
-        return $content;
486
-    }
487
-
488
-    /**
489
-     * Creates new document from file $file.
490
-     * Chainable.
491
-     *
492
-     * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources.
493
-     * @param null   $contentType
494
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
495
-     */
496
-    public static function newDocumentFile($file, $contentType = null)
497
-    {
498
-        $documentID = self::createDocumentWrapper(file_get_contents($file), $contentType);
499
-        return new PhpQueryObject($documentID);
500
-    }
501
-
502
-    /**
503
-     * Creates new document from markup.
504
-     * Chainable.
505
-     *
506
-     * @param      $file
507
-     * @param null $charset
508
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
509
-     */
510
-    public static function newDocumentFileHTML($file, $charset = null)
511
-    {
512
-        $contentType = $charset ? ";charset=$charset" : '';
513
-        return self::newDocumentFile($file, "text/html{$contentType}");
514
-    }
515
-
516
-    /**
517
-     * Creates new document from markup.
518
-     * Chainable.
519
-     *
520
-     * @param      $file
521
-     * @param null $charset
522
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
523
-     */
524
-    public static function newDocumentFileXML($file, $charset = null)
525
-    {
526
-        $contentType = $charset ? ";charset=$charset" : '';
527
-        return self::newDocumentFile($file, "text/xml{$contentType}");
528
-    }
529
-
530
-    /**
531
-     * Creates new document from markup.
532
-     * Chainable.
533
-     *
534
-     * @param      $file
535
-     * @param null $charset
536
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
537
-     */
538
-    public static function newDocumentFileXHTML($file, $charset = null)
539
-    {
540
-        $contentType = $charset ? ";charset=$charset" : '';
541
-        return self::newDocumentFile($file, "application/xhtml+xml{$contentType}");
542
-    }
543
-
544
-    /**
545
-     * Creates new document from markup.
546
-     * Chainable.
547
-     *
548
-     * @param      $file
549
-     * @param null $contentType
550
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
551
-     */
552
-    public static function newDocumentFilePHP($file, $contentType = null)
553
-    {
554
-        return self::newDocumentPHP(file_get_contents($file), $contentType);
555
-    }
556
-
557
-    /**
558
-     * Reuses existing \DOMDocument object.
559
-     * Chainable.
560
-     *
561
-     * @param $document \DOMDocument
562
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
563
-     * @TODO support \DOMDocument
564
-     */
565
-    public static function loadDocument($document)
566
-    {
567
-        // TODO
568
-        die('TODO loadDocument');
569
-    }
570
-
571
-    /**
572
-     * Enter description here...
573
-     *
574
-     * @param      $html
575
-     * @param null $contentType
576
-     * @param null $documentID
577
-     * @return null|string
578
-     * @throws \Exception
579
-     * @todo support PHP tags in input
580
-     * @todo support passing \DOMDocument object from self::loadDocument
581
-     */
582
-    protected static function createDocumentWrapper($html, $contentType = null, $documentID = null)
583
-    {
584
-        if (function_exists('domxml_open_mem'))
585
-            throw new \Exception("Old PHP4 DOM XML extension detected. PhpQuery won't work until this extension is enabled.");
586
-        //		$id = $documentID
587
-        //			? $documentID
588
-        //			: md5(microtime());
589
-        $document = null;
590
-        if ($html instanceof \DOMDocument) {
591
-            if (self::getDocumentID($html)) {
592
-                // document already exists in PhpQuery::$documents, make a copy
593
-                $document = clone $html;
594
-            } else {
595
-                // new document, add it to PhpQuery::$documents
596
-                $wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID);
597
-            }
598
-        } else {
599
-            $wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID);
600
-        }
601
-        //		$wrapper->id = $id;
602
-        // bind document
603
-        PhpQuery::$documents[$wrapper->id] = $wrapper;
604
-        // remember last loaded document
605
-        PhpQuery::selectDocument($wrapper->id);
606
-        return $wrapper->id;
607
-    }
608
-
609
-    /**
610
-     * Extend class namespace.
611
-     *
612
-     * @param string|array $target
613
-     * @param array        $source
614
-     * @throws \Exception
615
-     * @return bool
616
-     * @TODO support string $source
617
-     */
618
-    public static function extend($target, $source)
619
-    {
620
-        switch ($target) {
621
-            case 'PhpQueryObject':
622
-                $targetRef  = & self::$extendMethods;
623
-                $targetRef2 = & self::$pluginsMethods;
624
-                break;
625
-            case 'PhpQuery':
626
-                $targetRef  = & self::$extendStaticMethods;
627
-                $targetRef2 = & self::$pluginsStaticMethods;
628
-                break;
629
-            default:
630
-                throw new \Exception("Unsupported \$target type");
631
-        }
632
-        if (is_string($source))
633
-            $source = array(
634
-                $source => $source
635
-            );
636
-        foreach ($source as $method => $callback) {
637
-            if (isset($targetRef[$method])) {
638
-                //				throw new \Exception
639
-                self::debug("Duplicate method '{$method}', can\'t extend '{$target}'");
640
-                continue;
641
-            }
642
-            if (isset($targetRef2[$method])) {
643
-                //				throw new \Exception
644
-                self::debug(
645
-                    "Duplicate method '{$method}' from plugin '{$targetRef2[$method]}',"
646
-                    . " can\'t extend '{$target}'"
647
-                );
648
-                continue;
649
-            }
650
-            $targetRef[$method] = $callback;
651
-        }
652
-        return true;
653
-    }
654
-
655
-    /**
656
-     * Extend PhpQuery with $class from $file.
657
-     *
658
-     * @param string $class Extending class name. Real class name can be prepended PhpQuery_.
659
-     * @param string $file  Filename to include. Defaults to "{$class}.php".
660
-     * @throws \Exception
661
-     * @return bool
662
-     */
663
-    public static function plugin($class, $file = null)
664
-    {
665
-        // TODO $class checked agains PhpQuery_$class
666
-        //		if (strpos($class, 'PhpQuery') === 0)
667
-        //			$class = substr($class, 8);
668
-        if (in_array($class, self::$pluginsLoaded))
669
-            return true;
670
-        if (!$file)
671
-            $file = $class . '.php';
672
-        $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class);
673
-        $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class);
674
-        if (!$objectClassExists && !$staticClassExists)
675
-            require_once($file);
676
-        self::$pluginsLoaded[] = $class;
677
-        // static methods
678
-        if (class_exists('\PhpQuery\Plugin\Util' . $class)) {
679
-            $realClass = '\PhpQuery\Plugin\Util' . $class;
680
-            $vars      = get_class_vars($realClass);
681
-            $loop      = isset($vars['PhpQueryMethods'])
682
-            && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
683
-                : get_class_methods($realClass);
684
-            foreach ($loop as $method) {
685
-                if ($method == '__initialize')
686
-                    continue;
687
-                if (!is_callable(
688
-                    array(
689
-                        $realClass,
690
-                        $method
691
-                    )
692
-                )
693
-                )
694
-                    continue;
695
-                if (isset(self::$pluginsStaticMethods[$method])) {
696
-                    throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '"
697
-                                         . self::$pluginsStaticMethods[$method] . "'");
698
-                }
699
-                self::$pluginsStaticMethods[$method] = $class;
700
-            }
701
-            if (method_exists($realClass, '__initialize'))
702
-                call_user_func_array(
703
-                    array(
704
-                        $realClass,
705
-                        '__initialize'
706
-                    ),
707
-                    array()
708
-                );
709
-        }
710
-        // object methods
711
-        if (class_exists('\\PhpQuery\\Plugin\\' . $class)) {
712
-            $realClass = '\\PhpQuery\\Plugin\\' . $class;
713
-            $vars      = get_class_vars($realClass);
714
-            $loop      = isset($vars['PhpQueryMethods'])
715
-            && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
716
-                : get_class_methods($realClass);
717
-            foreach ($loop as $method) {
718
-                if (!is_callable(
719
-                    array(
720
-                        $realClass,
721
-                        $method
722
-                    )
723
-                )
724
-                )
725
-                    continue;
726
-                if (isset(self::$pluginsMethods[$method])) {
727
-                    throw new \Exception("Duplicate method '{$method}' from plugin '{$class}' conflicts with same method from plugin '"
728
-                                         . self::$pluginsMethods[$method] . "'");
729
-                    continue;
730
-                }
731
-                self::$pluginsMethods[$method] = $class;
732
-            }
733
-        }
734
-        return true;
735
-    }
736
-
737
-    /**
738
-     * Unloades all or specified document from memory.
739
-     *
740
-     * @param null $id
741
-     * @internal param mixed $documentID @see PhpQuery::getDocumentID() for supported types.
742
-     */
743
-    public static function unloadDocuments($id = null)
744
-    {
745
-        if (isset($id)) {
746
-            if ($id = self::getDocumentID($id))
747
-                unset(PhpQuery::$documents[$id]);
748
-        } else {
749
-            foreach (PhpQuery::$documents as $k => $v) {
750
-                unset(PhpQuery::$documents[$k]);
751
-            }
752
-        }
753
-    }
754
-
755
-    /**
756
-     * Parses PhpQuery object or HTML result against PHP tags and makes them active.
757
-     *
758
-     * @param PhpQuery|string $content
759
-     * @deprecated
760
-     * @return string
761
-     */
762
-    public static function unsafePHPTags($content)
763
-    {
764
-        return self::markupToPHP($content);
765
-    }
766
-
767
-    public static function DOMNodeListToArray($DOMNodeList)
768
-    {
769
-        $array = array();
770
-        if (!$DOMNodeList)
771
-            return $array;
772
-        foreach ($DOMNodeList as $node)
773
-            $array[] = $node;
774
-        return $array;
775
-    }
776
-
777
-    /**
778
-     * Checks if $input is HTML string, which has to start with '<'.
779
-     *
780
-     * @deprecated
781
-     * @param String $input
782
-     * @return Bool
783
-     * @todo still used ?
784
-     */
785
-    public static function isMarkup($input)
786
-    {
787
-        return is_string($input) && substr(trim($input), 0, 1) == '<';
788
-    }
789
-
790
-    public static function debug($text)
791
-    {
792
-        if (self::$debug)
793
-            print var_dump($text);
794
-    }
795
-
796
-    /**
797
-     * Make an AJAX request.
798
-     *
799
-     * @param array $options
800
-     * @param null  $xhr
801
-     * @throws \Exception
802
-     * @internal param \PhpQuery\See $array $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions
803
-     * Additional options are:
804
-     * 'document' - document for global events, @see PhpQuery::getDocumentID()
805
-     * 'referer' - implemented
806
-     * 'requested_with' - TODO; not implemented (X-Requested-With)
807
-     * @return \Zend_Http_Client
808
-     * @link     http://docs.jquery.com/Ajax/jQuery.ajax
809
-     *
810
-     * @TODO $options['cache']
811
-     * @TODO $options['processData']
812
-     * @TODO $options['xhr']
813
-     * @TODO $options['data'] as string
814
-     * @TODO     XHR interface
815
-     */
816
-    public static function ajax($options = array(), $xhr = null)
817
-    {
818
-        $options    = array_merge(self::$ajaxSettings, $options);
819
-        $documentID = isset($options['document']) ? self::getDocumentID($options['document'])
820
-            : null;
821
-        if ($xhr) {
822
-            // reuse existing XHR object, but clean it up
823
-            $client = $xhr;
824
-            //			$client->setParameterPost(null);
825
-            //			$client->setParameterGet(null);
826
-            $client->setAuth(false);
827
-            $client->setHeaders("If-Modified-Since", null);
828
-            $client->setHeaders("Referer", null);
829
-            $client->resetParameters();
830
-        } else {
831
-            // create new XHR object
832
-            $client = new \Zend_Http_Client();
833
-            $client->setCookieJar();
834
-        }
835
-        if (isset($options['timeout']))
836
-            $client->setConfig(
837
-                array(
838
-                    'timeout' => $options['timeout'],
839
-                )
840
-            );
841
-        //			'maxredirects' => 0,
842
-        foreach (self::$ajaxAllowedHosts as $k => $host)
843
-            if ($host == '.' && isset($_SERVER['HTTP_HOST']))
844
-                self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST'];
845
-        $host = parse_url($options['url'], PHP_URL_HOST);
846
-        if (!in_array($host, self::$ajaxAllowedHosts)) {
847
-            throw new \Exception("Request not permitted, host '$host' not present in "
848
-                                 . "PhpQuery::\$ajaxAllowedHosts");
849
-        }
850
-        // JSONP
851
-        $jsre = "/=\\?(&|$)/";
852
-        if (isset($options['dataType']) && $options['dataType'] == 'jsonp') {
853
-            $jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback';
854
-            if (strtolower($options['type']) == 'get') {
855
-                if (!preg_match($jsre, $options['url'])) {
856
-                    $sep = strpos($options['url'], '?') ? '&' : '?';
857
-                    $options['url'] .= "$sep$jsonpCallbackParam=?";
858
-                }
859
-            } else if ($options['data']) {
860
-                $jsonp = false;
861
-                foreach ($options['data'] as $n => $v) {
862
-                    if ($v == '?')
863
-                        $jsonp = true;
864
-                }
865
-                if (!$jsonp) {
866
-                    $options['data'][$jsonpCallbackParam] = '?';
867
-                }
868
-            }
869
-            $options['dataType'] = 'json';
870
-        }
871
-        if (isset($options['dataType']) && $options['dataType'] == 'json') {
872
-            $jsonpCallback = 'json_' . md5(microtime());
873
-            $jsonpData     = $jsonpUrl = false;
874
-            if ($options['data']) {
875
-                foreach ($options['data'] as $n => $v) {
876
-                    if ($v == '?')
877
-                        $jsonpData = $n;
878
-                }
879
-            }
880
-            if (preg_match($jsre, $options['url']))
881
-                $jsonpUrl = true;
882
-            if ($jsonpData !== false || $jsonpUrl) {
883
-                // remember callback name for httpData()
884
-                $options['_jsonp'] = $jsonpCallback;
885
-                if ($jsonpData !== false)
886
-                    $options['data'][$jsonpData] = $jsonpCallback;
887
-                if ($jsonpUrl)
888
-                    $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']);
889
-            }
890
-        }
891
-        $client->setUri($options['url']);
892
-        $client->setMethod(strtoupper($options['type']));
893
-        if (isset($options['referer']) && $options['referer'])
894
-            $client->setHeaders('Referer', $options['referer']);
895
-        $client->setHeaders(
896
-            array(
897
-                //			'content-type' => $options['contentType'],
898
-                'User-Agent'      => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko'
899
-                    . '/2008122010 Firefox/3.0.5',
900
-                // TODO custom charset
901
-                'Accept-Charset'  => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
902
-                // 	 		'Connection' => 'keep-alive',
903
-                // 			'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
904
-                'Accept-Language' => 'en-us,en;q=0.5',
905
-            )
906
-        );
907
-        if ($options['username'])
908
-            $client->setAuth($options['username'], $options['password']);
909
-        if (isset($options['ifModified']) && $options['ifModified'])
910
-            $client->setHeaders(
911
-                "If-Modified-Since",
912
-                self::$lastModified ? self::$lastModified
913
-                    : "Thu, 01 Jan 1970 00:00:00 GMT"
914
-            );
915
-        $client->setHeaders(
916
-            "Accept",
917
-            isset($options['dataType'])
918
-            && isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']]
919
-                . ", */*" : self::$ajaxSettings['accepts']['_default']
920
-        );
921
-        // TODO $options['processData']
922
-        if ($options['data'] instanceof PhpQueryObject) {
923
-            $serialized      = $options['data']->serializeArray($options['data']);
924
-            $options['data'] = array();
925
-            foreach ($serialized as $r)
926
-                $options['data'][$r['name']] = $r['value'];
927
-        }
928
-        if (strtolower($options['type']) == 'get') {
929
-            $client->setParameterGet($options['data']);
930
-        } else if (strtolower($options['type']) == 'post') {
931
-            $client->setEncType($options['contentType']);
932
-            $client->setParameterPost($options['data']);
933
-        }
934
-        if (self::$active == 0 && $options['global'])
935
-            PhpQueryEvents::trigger($documentID, 'ajaxStart');
936
-        self::$active++;
937
-        // beforeSend callback
938
-        if (isset($options['beforeSend']) && $options['beforeSend'])
939
-            PhpQuery::callbackRun(
940
-                $options['beforeSend'],
941
-                array(
942
-                    $client
943
-                )
944
-            );
945
-        // ajaxSend event
946
-        if ($options['global'])
947
-            PhpQueryEvents::trigger(
948
-                $documentID,
949
-                'ajaxSend',
950
-                array(
951
-                    $client,
952
-                    $options
953
-                )
954
-            );
955
-        if (PhpQuery::$debug) {
956
-            self::debug("{$options['type']}: {$options['url']}\n");
957
-            self::debug("Options: <pre>" . var_export($options, true) . "</pre>\n");
958
-            //			if ($client->getCookieJar())
959
-            //				self::debug("Cookies: <pre>".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."</pre>\n");
960
-        }
961
-        // request
962
-        $response = $client->request();
963
-        if (PhpQuery::$debug) {
964
-            self::debug(
965
-                'Status: ' . $response->getStatus() . ' / '
966
-                . $response->getMessage()
967
-            );
968
-            self::debug($client->getLastRequest());
969
-            self::debug($response->getHeaders());
970
-        }
971
-        if ($response->isSuccessful()) {
972
-            // XXX tempolary
973
-            self::$lastModified = $response->getHeader('Last-Modified');
974
-            $data               = self::httpData($response->getBody(), $options['dataType'], $options);
975
-            if (isset($options['success']) && $options['success'])
976
-                PhpQuery::callbackRun(
977
-                    $options['success'],
978
-                    array(
979
-                        $data,
980
-                        $response->getStatus(),
981
-                        $options
982
-                    )
983
-                );
984
-            if ($options['global'])
985
-                PhpQueryEvents::trigger(
986
-                    $documentID,
987
-                    'ajaxSuccess',
988
-                    array(
989
-                        $client,
990
-                        $options
991
-                    )
992
-                );
993
-        } else {
994
-            if (isset($options['error']) && $options['error'])
995
-                PhpQuery::callbackRun(
996
-                    $options['error'],
997
-                    array(
998
-                        $client,
999
-                        $response->getStatus(),
1000
-                        $response->getMessage()
1001
-                    )
1002
-                );
1003
-            if ($options['global'])
1004
-                PhpQueryEvents::trigger(
1005
-                    $documentID,
1006
-                    'ajaxError',
1007
-                    array(
1008
-                        $client,
1009
-                        /*$response->getStatus(),*/
1010
-                        $response->getMessage(),
1011
-                        $options
1012
-                    )
1013
-                );
1014
-        }
1015
-        if (isset($options['complete']) && $options['complete'])
1016
-            PhpQuery::callbackRun(
1017
-                $options['complete'],
1018
-                array(
1019
-                    $client,
1020
-                    $response->getStatus()
1021
-                )
1022
-            );
1023
-        if ($options['global'])
1024
-            PhpQueryEvents::trigger(
1025
-                $documentID,
1026
-                'ajaxComplete',
1027
-                array(
1028
-                    $client,
1029
-                    $options
1030
-                )
1031
-            );
1032
-        if ($options['global'] && !--self::$active)
1033
-            PhpQueryEvents::trigger($documentID, 'ajaxStop');
1034
-        return $client;
1035
-        //		if (is_null($domId))
1036
-        //			$domId = self::$defaultDocumentID ? self::$defaultDocumentID : false;
1037
-        //		return new PhpQueryAjaxResponse($response, $domId);
1038
-    }
1039
-
1040
-    protected static function httpData($data, $type, $options)
1041
-    {
1042
-        if (isset($options['dataFilter']) && $options['dataFilter'])
1043
-            $data = self::callbackRun(
1044
-                $options['dataFilter'],
1045
-                array(
1046
-                    $data,
1047
-                    $type
1048
-                )
1049
-            );
1050
-        if (is_string($data)) {
1051
-            if ($type == "json") {
1052
-                if (isset($options['_jsonp']) && $options['_jsonp']) {
1053
-                    $data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data);
1054
-                }
1055
-                $data = self::parseJSON($data);
1056
-            }
1057
-        }
1058
-        return $data;
1059
-    }
1060
-
1061
-    /**
1062
-     * Enter description here...
1063
-     *
1064
-     * @param array|PhpQuery $data
1065
-     *
1066
-     * @return string
1067
-     */
1068
-    public static function param($data)
1069
-    {
1070
-        return http_build_query($data, null, '&');
1071
-    }
1072
-
1073
-    public static function get($url, $data = null, $callback = null, $type = null)
1074
-    {
1075
-        if (!is_array($data)) {
1076
-            $callback = $data;
1077
-            $data     = null;
1078
-        }
1079
-        // TODO some array_values on this shit
1080
-        return PhpQuery::ajax(
1081
-            array(
1082
-                'type'     => 'GET',
1083
-                'url'      => $url,
1084
-                'data'     => $data,
1085
-                'success'  => $callback,
1086
-                'dataType' => $type,
1087
-            )
1088
-        );
1089
-    }
1090
-
1091
-    public static function post($url, $data = null, $callback = null, $type = null)
1092
-    {
1093
-        if (!is_array($data)) {
1094
-            $callback = $data;
1095
-            $data     = null;
1096
-        }
1097
-        return PhpQuery::ajax(
1098
-            array(
1099
-                'type'     => 'POST',
1100
-                'url'      => $url,
1101
-                'data'     => $data,
1102
-                'success'  => $callback,
1103
-                'dataType' => $type,
1104
-            )
1105
-        );
1106
-    }
1107
-
1108
-    public static function getJSON($url, $data = null, $callback = null)
1109
-    {
1110
-        if (!is_array($data)) {
1111
-            $callback = $data;
1112
-            $data     = null;
1113
-        }
1114
-        // TODO some array_values on this shit
1115
-        return PhpQuery::ajax(
1116
-            array(
1117
-                'type'     => 'GET',
1118
-                'url'      => $url,
1119
-                'data'     => $data,
1120
-                'success'  => $callback,
1121
-                'dataType' => 'json',
1122
-            )
1123
-        );
1124
-    }
1125
-
1126
-    public static function ajaxSetup($options)
1127
-    {
1128
-        self::$ajaxSettings = array_merge(self::$ajaxSettings, $options);
1129
-    }
1130
-
1131
-    public static function ajaxAllowHost($host1, $host2 = null, $host3 = null)
1132
-    {
1133
-        $loop = is_array($host1) ? $host1 : func_get_args();
1134
-        foreach ($loop as $host) {
1135
-            if ($host && !in_array($host, PhpQuery::$ajaxAllowedHosts)) {
1136
-                PhpQuery::$ajaxAllowedHosts[] = $host;
1137
-            }
1138
-        }
1139
-    }
1140
-
1141
-    public static function ajaxAllowURL($url1, $url2 = null, $url3 = null)
1142
-    {
1143
-        $loop = is_array($url1) ? $url1 : func_get_args();
1144
-        foreach ($loop as $url)
1145
-            PhpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST));
1146
-    }
1147
-
1148
-    /**
1149
-     * Returns JSON representation of $data.
1150
-     *
1151
-     * @static
1152
-     * @param mixed $data
1153
-     * @return string
1154
-     */
1155
-    public static function toJSON($data)
1156
-    {
1157
-        if (function_exists('json_encode'))
1158
-            return json_encode($data);
1159
-        require_once('Zend/Json/Encoder.php');
1160
-        return \Zend_Json_Encoder::encode($data);
1161
-    }
1162
-
1163
-    /**
1164
-     * Parses JSON into proper PHP type.
1165
-     *
1166
-     * @static
1167
-     * @param string $json
1168
-     * @return mixed
1169
-     */
1170
-    public static function parseJSON($json)
1171
-    {
1172
-        if (function_exists('json_decode')) {
1173
-            $return = json_decode(trim($json), true);
1174
-            // json_decode and UTF8 issues
1175
-            if (isset($return))
1176
-                return $return;
1177
-        }
1178
-        require_once('Zend/Json/Decoder.php');
1179
-        return \Zend_Json_Decoder::decode($json);
1180
-    }
1181
-
1182
-    /**
1183
-     * Returns source's document ID.
1184
-     *
1185
-     * @param $source \DOMNode|PhpQueryObject
1186
-     * @return string
1187
-     */
1188
-    public static function getDocumentID($source)
1189
-    {
1190
-        if ($source instanceof \DOMDocument) {
1191
-            foreach (PhpQuery::$documents as $id => $document) {
1192
-                if ($source->isSameNode($document->document))
1193
-                    return $id;
1194
-            }
1195
-        } else if ($source instanceof \DOMNode) {
1196
-            foreach (PhpQuery::$documents as $id => $document) {
1197
-                if ($source->ownerDocument->isSameNode($document->document))
1198
-                    return $id;
1199
-            }
1200
-        } else if ($source instanceof PhpQueryObject)
1201
-            return $source->getDocumentID();
1202
-        else if (is_string($source) && isset(PhpQuery::$documents[$source]))
1203
-            return $source;
1204
-    }
1205
-
1206
-    /**
1207
-     * Get \DOMDocument object related to $source.
1208
-     * Returns null if such document doesn't exist.
1209
-     *
1210
-     * @param $source \DOMNode|PhpQueryObject|string
1211
-     * @return string
1212
-     */
1213
-    public static function getDOMDocument($source)
1214
-    {
1215
-        if ($source instanceof \DOMDocument)
1216
-            return $source;
1217
-        $source = self::getDocumentID($source);
1218
-        return $source ? self::$documents[$id]['document'] : null;
1219
-    }
1220
-
1221
-    // UTILITIES
1222
-    // http://docs.jquery.com/Utilities
1223
-
1224
-    /**
1225
-     *
1226
-     * @link     http://docs.jquery.com/Utilities/jQuery.makeArray
1227
-     * @param $object
1228
-     * @return array
1229
-     */
1230
-    public static function makeArray($object)
1231
-    {
1232
-        $array = array();
1233
-        if (is_object($object) && $object instanceof \DOMNodeList) {
1234
-            foreach ($object as $value)
1235
-                $array[] = $value;
1236
-        } else if (is_object($object) && !($object instanceof \Iterator)) {
1237
-            foreach (get_object_vars($object) as $name => $value)
1238
-                $array[0][$name] = $value;
1239
-        } else {
1240
-            foreach ($object as $name => $value)
1241
-                $array[0][$name] = $value;
1242
-        }
1243
-        return $array;
1244
-    }
1245
-
1246
-    public static function inArray($value, $array)
1247
-    {
1248
-        return in_array($value, $array);
1249
-    }
1250
-
1251
-    /**
1252
-     *
1253
-     * @param      $object
1254
-     * @param      $callback
1255
-     * @param null $param1
1256
-     * @param null $param2
1257
-     * @param null $param3
1258
-     * @link http://docs.jquery.com/Utilities/jQuery.each
1259
-     */
1260
-    public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null)
1261
-    {
1262
-        $paramStructure = null;
1263
-        if (func_num_args() > 2) {
1264
-            $paramStructure = func_get_args();
1265
-            $paramStructure = array_slice($paramStructure, 2);
1266
-        }
1267
-        if (is_object($object) && !($object instanceof \Iterator)) {
1268
-            foreach (get_object_vars($object) as $name => $value)
1269
-                PhpQuery::callbackRun(
1270
-                    $callback,
1271
-                    array(
1272
-                        $name,
1273
-                        $value
1274
-                    ),
1275
-                    $paramStructure
1276
-                );
1277
-        } else {
1278
-            foreach ($object as $name => $value)
1279
-                PhpQuery::callbackRun(
1280
-                    $callback,
1281
-                    array(
1282
-                        $name,
1283
-                        $value
1284
-                    ),
1285
-                    $paramStructure
1286
-                );
1287
-        }
1288
-    }
1289
-
1290
-    /**
1291
-     *
1292
-     * @link http://docs.jquery.com/Utilities/jQuery.map
1293
-     */
1294
-    public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null)
1295
-    {
1296
-        $result         = array();
1297
-        $paramStructure = null;
1298
-        if (func_num_args() > 2) {
1299
-            $paramStructure = func_get_args();
1300
-            $paramStructure = array_slice($paramStructure, 2);
1301
-        }
1302
-        foreach ($array as $v) {
1303
-            $vv = PhpQuery::callbackRun(
1304
-                $callback,
1305
-                array(
1306
-                    $v
1307
-                ),
1308
-                $paramStructure
1309
-            );
1310
-            //			$callbackArgs = $args;
1311
-            //			foreach($args as $i => $arg) {
1312
-            //				$callbackArgs[$i] = $arg instanceof CallbackParam
1313
-            //					? $v
1314
-            //					: $arg;
1315
-            //			}
1316
-            //			$vv = call_user_func_array($callback, $callbackArgs);
1317
-            if (is_array($vv)) {
1318
-                foreach ($vv as $vvv)
1319
-                    $result[] = $vvv;
1320
-            } else if ($vv !== null) {
1321
-                $result[] = $vv;
1322
-            }
1323
-        }
1324
-        return $result;
1325
-    }
1326
-
1327
-    /**
1328
-     *
1329
-     * @param $callback Callback
1330
-     * @param $params
1331
-     * @param $paramStructure
1332
-     * @return bool|mixed
1333
-     */
1334
-    public static function callbackRun($callback, $params = array(), $paramStructure = null)
1335
-    {
1336
-        if (!$callback)
1337
-            return;
1338
-        if ($callback instanceof \CallbackParameterToReference) {
1339
-            // TODO support ParamStructure to select which $param push to reference
1340
-            if (isset($params[0]))
1341
-                $callback->callback = $params[0];
1342
-            return true;
1343
-        }
1344
-        if ($callback instanceof \Callback) {
1345
-            $paramStructure = $callback->params;
1346
-            $callback       = $callback->callback;
1347
-        }
1348
-        if (!$paramStructure)
1349
-            return call_user_func_array($callback, $params);
1350
-        $p = 0;
1351
-        foreach ($paramStructure as $i => $v) {
1352
-            $paramStructure[$i] = $v instanceof \CallbackParam ? $params[$p++] : $v;
1353
-        }
1354
-        return call_user_func_array($callback, $paramStructure);
1355
-    }
1356
-
1357
-    /**
1358
-     * Merge 2 PhpQuery objects.
1359
-     * @param array $one
1360
-     * @param array $two
1361
-     * @return array
1362
-     * @protected
1363
-     * @todo node lists, PhpQueryObject
1364
-     */
1365
-    public static function merge($one, $two)
1366
-    {
1367
-        $elements = $one->elements;
1368
-        foreach ($two->elements as $node) {
1369
-            $exists = false;
1370
-            foreach ($elements as $node2) {
1371
-                if ($node2->isSameNode($node))
1372
-                    $exists = true;
1373
-            }
1374
-            if (!$exists)
1375
-                $elements[] = $node;
1376
-        }
1377
-        return $elements;
1378
-        //		$one = $one->newInstance();
1379
-        //		$one->elements = $elements;
1380
-        //		return $one;
1381
-    }
1382
-
1383
-    /**
1384
-     *
1385
-     * @param $array
1386
-     * @param $callback
1387
-     * @param $invert
1388
-     * @return array
1389
-     * @link http://docs.jquery.com/Utilities/jQuery.grep
1390
-     */
1391
-    public static function grep($array, $callback, $invert = false)
1392
-    {
1393
-        $result = array();
1394
-        foreach ($array as $k => $v) {
1395
-            $r = call_user_func_array(
1396
-                $callback,
1397
-                array(
1398
-                    $v,
1399
-                    $k
1400
-                )
1401
-            );
1402
-            if ($r === !(bool) $invert)
1403
-                $result[] = $v;
1404
-        }
1405
-        return $result;
1406
-    }
1407
-
1408
-    public static function unique($array)
1409
-    {
1410
-        return array_unique($array);
1411
-    }
1412
-
1413
-    /**
1414
-     *
1415
-     * @param $function
1416
-     * @return bool
1417
-     * @TODO there are problems with non-static methods, second parameter pass it
1418
-     *    but doesnt verify is method is really callable
1419
-     */
1420
-    public static function isFunction($function)
1421
-    {
1422
-        return is_callable($function);
1423
-    }
1424
-
1425
-    public static function trim($str)
1426
-    {
1427
-        return trim($str);
1428
-    }
1429
-    /* PLUGINS NAMESPACE */
1430
-    /**
1431
-     *
1432
-     * @param $url
1433
-     * @param $callback
1434
-     * @param $param1
1435
-     * @param $param2
1436
-     * @param $param3
1437
-     * @return PhpQueryObject
1438
-     */
1439
-    public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null)
1440
-    {
1441
-        if (self::plugin('WebBrowser')) {
1442
-            $params = func_get_args();
1443
-            return self::callbackRun(
1444
-                array(
1445
-                    self::$plugins,
1446
-                    'browserGet'
1447
-                ),
1448
-                $params
1449
-            );
1450
-        } else {
1451
-            self::debug('WebBrowser plugin not available...');
1452
-        }
1453
-    }
1454
-
1455
-    /**
1456
-     *
1457
-     * @param $url
1458
-     * @param $data
1459
-     * @param $callback
1460
-     * @param $param1
1461
-     * @param $param2
1462
-     * @param $param3
1463
-     * @return PhpQueryObject
1464
-     */
1465
-    public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null)
1466
-    {
1467
-        if (self::plugin('WebBrowser')) {
1468
-            $params = func_get_args();
1469
-            return self::callbackRun(
1470
-                array(
1471
-                    self::$plugins,
1472
-                    'browserPost'
1473
-                ),
1474
-                $params
1475
-            );
1476
-        } else {
1477
-            self::debug('WebBrowser plugin not available...');
1478
-        }
1479
-    }
1480
-
1481
-    /**
1482
-     *
1483
-     * @param $ajaxSettings
1484
-     * @param $callback
1485
-     * @param $param1
1486
-     * @param $param2
1487
-     * @param $param3
1488
-     * @return PhpQueryObject
1489
-     */
1490
-    public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null)
1491
-    {
1492
-        if (self::plugin('WebBrowser')) {
1493
-            $params = func_get_args();
1494
-            return self::callbackRun(
1495
-                array(
1496
-                    self::$plugins,
1497
-                    'browser'
1498
-                ),
1499
-                $params
1500
-            );
1501
-        } else {
1502
-            self::debug('WebBrowser plugin not available...');
1503
-        }
1504
-    }
1505
-
1506
-    /**
1507
-     *
1508
-     * @param $code
1509
-     * @return string
1510
-     */
1511
-    public static function php($code)
1512
-    {
1513
-        return self::code('php', $code);
1514
-    }
1515
-
1516
-    /**
1517
-     *
1518
-     * @param $type
1519
-     * @param $code
1520
-     * @return string
1521
-     */
1522
-    public static function code($type, $code)
1523
-    {
1524
-        return "<$type><!-- " . trim($code) . " --></$type>";
1525
-    }
1526
-
1527
-    public static function __callStatic($method, $params)
1528
-    {
1529
-        return call_user_func_array(
1530
-            array(
1531
-                PhpQuery::$plugins,
1532
-                $method
1533
-            ),
1534
-            $params
1535
-        );
1536
-    }
1537
-
1538
-    protected static function dataSetupNode($node, $documentID)
1539
-    {
1540
-        // search are return if alredy exists
1541
-        foreach (PhpQuery::$documents[$documentID]->dataNodes as $dataNode) {
1542
-            if ($node->isSameNode($dataNode))
1543
-                return $dataNode;
1544
-        }
1545
-        // if doesn't, add it
1546
-        PhpQuery::$documents[$documentID]->dataNodes[] = $node;
1547
-        return $node;
1548
-    }
1549
-
1550
-    protected static function dataRemoveNode($node, $documentID)
1551
-    {
1552
-        // search are return if alredy exists
1553
-        foreach (PhpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) {
1554
-            if ($node->isSameNode($dataNode)) {
1555
-                unset(self::$documents[$documentID]->dataNodes[$k]);
1556
-                unset(self::$documents[$documentID]->data[$dataNode->dataID]);
1557
-            }
1558
-        }
1559
-    }
1560
-
1561
-    public static function data($node, $name, $data, $documentID = null)
1562
-    {
1563
-        if (!$documentID)
1564
-            // TODO check if this works
1565
-            $documentID = self::getDocumentID($node);
1566
-        $document = PhpQuery::$documents[$documentID];
1567
-        $node     = self::dataSetupNode($node, $documentID);
1568
-        if (!isset($node->dataID))
1569
-            $node->dataID = ++PhpQuery::$documents[$documentID]->uuid;
1570
-        $id = $node->dataID;
1571
-        if (!isset($document->data[$id]))
1572
-            $document->data[$id] = array();
1573
-        if (!is_null($data))
1574
-            $document->data[$id][$name] = $data;
1575
-        if ($name) {
1576
-            if (isset($document->data[$id][$name]))
1577
-                return $document->data[$id][$name];
1578
-        } else
1579
-            return $id;
1580
-    }
1581
-
1582
-    public static function removeData($node, $name, $documentID)
1583
-    {
1584
-        if (!$documentID)
1585
-            // TODO check if this works
1586
-            $documentID = self::getDocumentID($node);
1587
-        $document = PhpQuery::$documents[$documentID];
1588
-        $node     = self::dataSetupNode($node, $documentID);
1589
-        $id       = $node->dataID;
1590
-        if ($name) {
1591
-            if (isset($document->data[$id][$name]))
1592
-                unset($document->data[$id][$name]);
1593
-            $name = null;
1594
-            foreach ($document->data[$id] as $name)
1595
-                break;
1596
-            if (!$name)
1597
-                self::removeData($node, $name, $documentID);
1598
-        } else {
1599
-            self::dataRemoveNode($node, $documentID);
1600
-        }
1601
-    }
482
+					),
483
+					$content
484
+				);
485
+		return $content;
486
+	}
487
+
488
+	/**
489
+	 * Creates new document from file $file.
490
+	 * Chainable.
491
+	 *
492
+	 * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources.
493
+	 * @param null   $contentType
494
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
495
+	 */
496
+	public static function newDocumentFile($file, $contentType = null)
497
+	{
498
+		$documentID = self::createDocumentWrapper(file_get_contents($file), $contentType);
499
+		return new PhpQueryObject($documentID);
500
+	}
501
+
502
+	/**
503
+	 * Creates new document from markup.
504
+	 * Chainable.
505
+	 *
506
+	 * @param      $file
507
+	 * @param null $charset
508
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
509
+	 */
510
+	public static function newDocumentFileHTML($file, $charset = null)
511
+	{
512
+		$contentType = $charset ? ";charset=$charset" : '';
513
+		return self::newDocumentFile($file, "text/html{$contentType}");
514
+	}
515
+
516
+	/**
517
+	 * Creates new document from markup.
518
+	 * Chainable.
519
+	 *
520
+	 * @param      $file
521
+	 * @param null $charset
522
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
523
+	 */
524
+	public static function newDocumentFileXML($file, $charset = null)
525
+	{
526
+		$contentType = $charset ? ";charset=$charset" : '';
527
+		return self::newDocumentFile($file, "text/xml{$contentType}");
528
+	}
529
+
530
+	/**
531
+	 * Creates new document from markup.
532
+	 * Chainable.
533
+	 *
534
+	 * @param      $file
535
+	 * @param null $charset
536
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
537
+	 */
538
+	public static function newDocumentFileXHTML($file, $charset = null)
539
+	{
540
+		$contentType = $charset ? ";charset=$charset" : '';
541
+		return self::newDocumentFile($file, "application/xhtml+xml{$contentType}");
542
+	}
543
+
544
+	/**
545
+	 * Creates new document from markup.
546
+	 * Chainable.
547
+	 *
548
+	 * @param      $file
549
+	 * @param null $contentType
550
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
551
+	 */
552
+	public static function newDocumentFilePHP($file, $contentType = null)
553
+	{
554
+		return self::newDocumentPHP(file_get_contents($file), $contentType);
555
+	}
556
+
557
+	/**
558
+	 * Reuses existing \DOMDocument object.
559
+	 * Chainable.
560
+	 *
561
+	 * @param $document \DOMDocument
562
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
563
+	 * @TODO support \DOMDocument
564
+	 */
565
+	public static function loadDocument($document)
566
+	{
567
+		// TODO
568
+		die('TODO loadDocument');
569
+	}
570
+
571
+	/**
572
+	 * Enter description here...
573
+	 *
574
+	 * @param      $html
575
+	 * @param null $contentType
576
+	 * @param null $documentID
577
+	 * @return null|string
578
+	 * @throws \Exception
579
+	 * @todo support PHP tags in input
580
+	 * @todo support passing \DOMDocument object from self::loadDocument
581
+	 */
582
+	protected static function createDocumentWrapper($html, $contentType = null, $documentID = null)
583
+	{
584
+		if (function_exists('domxml_open_mem'))
585
+			throw new \Exception("Old PHP4 DOM XML extension detected. PhpQuery won't work until this extension is enabled.");
586
+		//		$id = $documentID
587
+		//			? $documentID
588
+		//			: md5(microtime());
589
+		$document = null;
590
+		if ($html instanceof \DOMDocument) {
591
+			if (self::getDocumentID($html)) {
592
+				// document already exists in PhpQuery::$documents, make a copy
593
+				$document = clone $html;
594
+			} else {
595
+				// new document, add it to PhpQuery::$documents
596
+				$wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID);
597
+			}
598
+		} else {
599
+			$wrapper = new Dom\DOMDocumentWrapper($html, $contentType, $documentID);
600
+		}
601
+		//		$wrapper->id = $id;
602
+		// bind document
603
+		PhpQuery::$documents[$wrapper->id] = $wrapper;
604
+		// remember last loaded document
605
+		PhpQuery::selectDocument($wrapper->id);
606
+		return $wrapper->id;
607
+	}
608
+
609
+	/**
610
+	 * Extend class namespace.
611
+	 *
612
+	 * @param string|array $target
613
+	 * @param array        $source
614
+	 * @throws \Exception
615
+	 * @return bool
616
+	 * @TODO support string $source
617
+	 */
618
+	public static function extend($target, $source)
619
+	{
620
+		switch ($target) {
621
+			case 'PhpQueryObject':
622
+				$targetRef  = & self::$extendMethods;
623
+				$targetRef2 = & self::$pluginsMethods;
624
+				break;
625
+			case 'PhpQuery':
626
+				$targetRef  = & self::$extendStaticMethods;
627
+				$targetRef2 = & self::$pluginsStaticMethods;
628
+				break;
629
+			default:
630
+				throw new \Exception("Unsupported \$target type");
631
+		}
632
+		if (is_string($source))
633
+			$source = array(
634
+				$source => $source
635
+			);
636
+		foreach ($source as $method => $callback) {
637
+			if (isset($targetRef[$method])) {
638
+				//				throw new \Exception
639
+				self::debug("Duplicate method '{$method}', can\'t extend '{$target}'");
640
+				continue;
641
+			}
642
+			if (isset($targetRef2[$method])) {
643
+				//				throw new \Exception
644
+				self::debug(
645
+					"Duplicate method '{$method}' from plugin '{$targetRef2[$method]}',"
646
+					. " can\'t extend '{$target}'"
647
+				);
648
+				continue;
649
+			}
650
+			$targetRef[$method] = $callback;
651
+		}
652
+		return true;
653
+	}
654
+
655
+	/**
656
+	 * Extend PhpQuery with $class from $file.
657
+	 *
658
+	 * @param string $class Extending class name. Real class name can be prepended PhpQuery_.
659
+	 * @param string $file  Filename to include. Defaults to "{$class}.php".
660
+	 * @throws \Exception
661
+	 * @return bool
662
+	 */
663
+	public static function plugin($class, $file = null)
664
+	{
665
+		// TODO $class checked agains PhpQuery_$class
666
+		//		if (strpos($class, 'PhpQuery') === 0)
667
+		//			$class = substr($class, 8);
668
+		if (in_array($class, self::$pluginsLoaded))
669
+			return true;
670
+		if (!$file)
671
+			$file = $class . '.php';
672
+		$objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class);
673
+		$staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class);
674
+		if (!$objectClassExists && !$staticClassExists)
675
+			require_once($file);
676
+		self::$pluginsLoaded[] = $class;
677
+		// static methods
678
+		if (class_exists('\PhpQuery\Plugin\Util' . $class)) {
679
+			$realClass = '\PhpQuery\Plugin\Util' . $class;
680
+			$vars      = get_class_vars($realClass);
681
+			$loop      = isset($vars['PhpQueryMethods'])
682
+			&& !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
683
+				: get_class_methods($realClass);
684
+			foreach ($loop as $method) {
685
+				if ($method == '__initialize')
686
+					continue;
687
+				if (!is_callable(
688
+					array(
689
+						$realClass,
690
+						$method
691
+					)
692
+				)
693
+				)
694
+					continue;
695
+				if (isset(self::$pluginsStaticMethods[$method])) {
696
+					throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '"
697
+										 . self::$pluginsStaticMethods[$method] . "'");
698
+				}
699
+				self::$pluginsStaticMethods[$method] = $class;
700
+			}
701
+			if (method_exists($realClass, '__initialize'))
702
+				call_user_func_array(
703
+					array(
704
+						$realClass,
705
+						'__initialize'
706
+					),
707
+					array()
708
+				);
709
+		}
710
+		// object methods
711
+		if (class_exists('\\PhpQuery\\Plugin\\' . $class)) {
712
+			$realClass = '\\PhpQuery\\Plugin\\' . $class;
713
+			$vars      = get_class_vars($realClass);
714
+			$loop      = isset($vars['PhpQueryMethods'])
715
+			&& !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
716
+				: get_class_methods($realClass);
717
+			foreach ($loop as $method) {
718
+				if (!is_callable(
719
+					array(
720
+						$realClass,
721
+						$method
722
+					)
723
+				)
724
+				)
725
+					continue;
726
+				if (isset(self::$pluginsMethods[$method])) {
727
+					throw new \Exception("Duplicate method '{$method}' from plugin '{$class}' conflicts with same method from plugin '"
728
+										 . self::$pluginsMethods[$method] . "'");
729
+					continue;
730
+				}
731
+				self::$pluginsMethods[$method] = $class;
732
+			}
733
+		}
734
+		return true;
735
+	}
736
+
737
+	/**
738
+	 * Unloades all or specified document from memory.
739
+	 *
740
+	 * @param null $id
741
+	 * @internal param mixed $documentID @see PhpQuery::getDocumentID() for supported types.
742
+	 */
743
+	public static function unloadDocuments($id = null)
744
+	{
745
+		if (isset($id)) {
746
+			if ($id = self::getDocumentID($id))
747
+				unset(PhpQuery::$documents[$id]);
748
+		} else {
749
+			foreach (PhpQuery::$documents as $k => $v) {
750
+				unset(PhpQuery::$documents[$k]);
751
+			}
752
+		}
753
+	}
754
+
755
+	/**
756
+	 * Parses PhpQuery object or HTML result against PHP tags and makes them active.
757
+	 *
758
+	 * @param PhpQuery|string $content
759
+	 * @deprecated
760
+	 * @return string
761
+	 */
762
+	public static function unsafePHPTags($content)
763
+	{
764
+		return self::markupToPHP($content);
765
+	}
766
+
767
+	public static function DOMNodeListToArray($DOMNodeList)
768
+	{
769
+		$array = array();
770
+		if (!$DOMNodeList)
771
+			return $array;
772
+		foreach ($DOMNodeList as $node)
773
+			$array[] = $node;
774
+		return $array;
775
+	}
776
+
777
+	/**
778
+	 * Checks if $input is HTML string, which has to start with '<'.
779
+	 *
780
+	 * @deprecated
781
+	 * @param String $input
782
+	 * @return Bool
783
+	 * @todo still used ?
784
+	 */
785
+	public static function isMarkup($input)
786
+	{
787
+		return is_string($input) && substr(trim($input), 0, 1) == '<';
788
+	}
789
+
790
+	public static function debug($text)
791
+	{
792
+		if (self::$debug)
793
+			print var_dump($text);
794
+	}
795
+
796
+	/**
797
+	 * Make an AJAX request.
798
+	 *
799
+	 * @param array $options
800
+	 * @param null  $xhr
801
+	 * @throws \Exception
802
+	 * @internal param \PhpQuery\See $array $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions
803
+	 * Additional options are:
804
+	 * 'document' - document for global events, @see PhpQuery::getDocumentID()
805
+	 * 'referer' - implemented
806
+	 * 'requested_with' - TODO; not implemented (X-Requested-With)
807
+	 * @return \Zend_Http_Client
808
+	 * @link     http://docs.jquery.com/Ajax/jQuery.ajax
809
+	 *
810
+	 * @TODO $options['cache']
811
+	 * @TODO $options['processData']
812
+	 * @TODO $options['xhr']
813
+	 * @TODO $options['data'] as string
814
+	 * @TODO     XHR interface
815
+	 */
816
+	public static function ajax($options = array(), $xhr = null)
817
+	{
818
+		$options    = array_merge(self::$ajaxSettings, $options);
819
+		$documentID = isset($options['document']) ? self::getDocumentID($options['document'])
820
+			: null;
821
+		if ($xhr) {
822
+			// reuse existing XHR object, but clean it up
823
+			$client = $xhr;
824
+			//			$client->setParameterPost(null);
825
+			//			$client->setParameterGet(null);
826
+			$client->setAuth(false);
827
+			$client->setHeaders("If-Modified-Since", null);
828
+			$client->setHeaders("Referer", null);
829
+			$client->resetParameters();
830
+		} else {
831
+			// create new XHR object
832
+			$client = new \Zend_Http_Client();
833
+			$client->setCookieJar();
834
+		}
835
+		if (isset($options['timeout']))
836
+			$client->setConfig(
837
+				array(
838
+					'timeout' => $options['timeout'],
839
+				)
840
+			);
841
+		//			'maxredirects' => 0,
842
+		foreach (self::$ajaxAllowedHosts as $k => $host)
843
+			if ($host == '.' && isset($_SERVER['HTTP_HOST']))
844
+				self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST'];
845
+		$host = parse_url($options['url'], PHP_URL_HOST);
846
+		if (!in_array($host, self::$ajaxAllowedHosts)) {
847
+			throw new \Exception("Request not permitted, host '$host' not present in "
848
+								 . "PhpQuery::\$ajaxAllowedHosts");
849
+		}
850
+		// JSONP
851
+		$jsre = "/=\\?(&|$)/";
852
+		if (isset($options['dataType']) && $options['dataType'] == 'jsonp') {
853
+			$jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback';
854
+			if (strtolower($options['type']) == 'get') {
855
+				if (!preg_match($jsre, $options['url'])) {
856
+					$sep = strpos($options['url'], '?') ? '&' : '?';
857
+					$options['url'] .= "$sep$jsonpCallbackParam=?";
858
+				}
859
+			} else if ($options['data']) {
860
+				$jsonp = false;
861
+				foreach ($options['data'] as $n => $v) {
862
+					if ($v == '?')
863
+						$jsonp = true;
864
+				}
865
+				if (!$jsonp) {
866
+					$options['data'][$jsonpCallbackParam] = '?';
867
+				}
868
+			}
869
+			$options['dataType'] = 'json';
870
+		}
871
+		if (isset($options['dataType']) && $options['dataType'] == 'json') {
872
+			$jsonpCallback = 'json_' . md5(microtime());
873
+			$jsonpData     = $jsonpUrl = false;
874
+			if ($options['data']) {
875
+				foreach ($options['data'] as $n => $v) {
876
+					if ($v == '?')
877
+						$jsonpData = $n;
878
+				}
879
+			}
880
+			if (preg_match($jsre, $options['url']))
881
+				$jsonpUrl = true;
882
+			if ($jsonpData !== false || $jsonpUrl) {
883
+				// remember callback name for httpData()
884
+				$options['_jsonp'] = $jsonpCallback;
885
+				if ($jsonpData !== false)
886
+					$options['data'][$jsonpData] = $jsonpCallback;
887
+				if ($jsonpUrl)
888
+					$options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']);
889
+			}
890
+		}
891
+		$client->setUri($options['url']);
892
+		$client->setMethod(strtoupper($options['type']));
893
+		if (isset($options['referer']) && $options['referer'])
894
+			$client->setHeaders('Referer', $options['referer']);
895
+		$client->setHeaders(
896
+			array(
897
+				//			'content-type' => $options['contentType'],
898
+				'User-Agent'      => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko'
899
+					. '/2008122010 Firefox/3.0.5',
900
+				// TODO custom charset
901
+				'Accept-Charset'  => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
902
+				// 	 		'Connection' => 'keep-alive',
903
+				// 			'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
904
+				'Accept-Language' => 'en-us,en;q=0.5',
905
+			)
906
+		);
907
+		if ($options['username'])
908
+			$client->setAuth($options['username'], $options['password']);
909
+		if (isset($options['ifModified']) && $options['ifModified'])
910
+			$client->setHeaders(
911
+				"If-Modified-Since",
912
+				self::$lastModified ? self::$lastModified
913
+					: "Thu, 01 Jan 1970 00:00:00 GMT"
914
+			);
915
+		$client->setHeaders(
916
+			"Accept",
917
+			isset($options['dataType'])
918
+			&& isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']]
919
+				. ", */*" : self::$ajaxSettings['accepts']['_default']
920
+		);
921
+		// TODO $options['processData']
922
+		if ($options['data'] instanceof PhpQueryObject) {
923
+			$serialized      = $options['data']->serializeArray($options['data']);
924
+			$options['data'] = array();
925
+			foreach ($serialized as $r)
926
+				$options['data'][$r['name']] = $r['value'];
927
+		}
928
+		if (strtolower($options['type']) == 'get') {
929
+			$client->setParameterGet($options['data']);
930
+		} else if (strtolower($options['type']) == 'post') {
931
+			$client->setEncType($options['contentType']);
932
+			$client->setParameterPost($options['data']);
933
+		}
934
+		if (self::$active == 0 && $options['global'])
935
+			PhpQueryEvents::trigger($documentID, 'ajaxStart');
936
+		self::$active++;
937
+		// beforeSend callback
938
+		if (isset($options['beforeSend']) && $options['beforeSend'])
939
+			PhpQuery::callbackRun(
940
+				$options['beforeSend'],
941
+				array(
942
+					$client
943
+				)
944
+			);
945
+		// ajaxSend event
946
+		if ($options['global'])
947
+			PhpQueryEvents::trigger(
948
+				$documentID,
949
+				'ajaxSend',
950
+				array(
951
+					$client,
952
+					$options
953
+				)
954
+			);
955
+		if (PhpQuery::$debug) {
956
+			self::debug("{$options['type']}: {$options['url']}\n");
957
+			self::debug("Options: <pre>" . var_export($options, true) . "</pre>\n");
958
+			//			if ($client->getCookieJar())
959
+			//				self::debug("Cookies: <pre>".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."</pre>\n");
960
+		}
961
+		// request
962
+		$response = $client->request();
963
+		if (PhpQuery::$debug) {
964
+			self::debug(
965
+				'Status: ' . $response->getStatus() . ' / '
966
+				. $response->getMessage()
967
+			);
968
+			self::debug($client->getLastRequest());
969
+			self::debug($response->getHeaders());
970
+		}
971
+		if ($response->isSuccessful()) {
972
+			// XXX tempolary
973
+			self::$lastModified = $response->getHeader('Last-Modified');
974
+			$data               = self::httpData($response->getBody(), $options['dataType'], $options);
975
+			if (isset($options['success']) && $options['success'])
976
+				PhpQuery::callbackRun(
977
+					$options['success'],
978
+					array(
979
+						$data,
980
+						$response->getStatus(),
981
+						$options
982
+					)
983
+				);
984
+			if ($options['global'])
985
+				PhpQueryEvents::trigger(
986
+					$documentID,
987
+					'ajaxSuccess',
988
+					array(
989
+						$client,
990
+						$options
991
+					)
992
+				);
993
+		} else {
994
+			if (isset($options['error']) && $options['error'])
995
+				PhpQuery::callbackRun(
996
+					$options['error'],
997
+					array(
998
+						$client,
999
+						$response->getStatus(),
1000
+						$response->getMessage()
1001
+					)
1002
+				);
1003
+			if ($options['global'])
1004
+				PhpQueryEvents::trigger(
1005
+					$documentID,
1006
+					'ajaxError',
1007
+					array(
1008
+						$client,
1009
+						/*$response->getStatus(),*/
1010
+						$response->getMessage(),
1011
+						$options
1012
+					)
1013
+				);
1014
+		}
1015
+		if (isset($options['complete']) && $options['complete'])
1016
+			PhpQuery::callbackRun(
1017
+				$options['complete'],
1018
+				array(
1019
+					$client,
1020
+					$response->getStatus()
1021
+				)
1022
+			);
1023
+		if ($options['global'])
1024
+			PhpQueryEvents::trigger(
1025
+				$documentID,
1026
+				'ajaxComplete',
1027
+				array(
1028
+					$client,
1029
+					$options
1030
+				)
1031
+			);
1032
+		if ($options['global'] && !--self::$active)
1033
+			PhpQueryEvents::trigger($documentID, 'ajaxStop');
1034
+		return $client;
1035
+		//		if (is_null($domId))
1036
+		//			$domId = self::$defaultDocumentID ? self::$defaultDocumentID : false;
1037
+		//		return new PhpQueryAjaxResponse($response, $domId);
1038
+	}
1039
+
1040
+	protected static function httpData($data, $type, $options)
1041
+	{
1042
+		if (isset($options['dataFilter']) && $options['dataFilter'])
1043
+			$data = self::callbackRun(
1044
+				$options['dataFilter'],
1045
+				array(
1046
+					$data,
1047
+					$type
1048
+				)
1049
+			);
1050
+		if (is_string($data)) {
1051
+			if ($type == "json") {
1052
+				if (isset($options['_jsonp']) && $options['_jsonp']) {
1053
+					$data = preg_replace('/^\s*\w+\((.*)\)\s*$/s', '$1', $data);
1054
+				}
1055
+				$data = self::parseJSON($data);
1056
+			}
1057
+		}
1058
+		return $data;
1059
+	}
1060
+
1061
+	/**
1062
+	 * Enter description here...
1063
+	 *
1064
+	 * @param array|PhpQuery $data
1065
+	 *
1066
+	 * @return string
1067
+	 */
1068
+	public static function param($data)
1069
+	{
1070
+		return http_build_query($data, null, '&');
1071
+	}
1072
+
1073
+	public static function get($url, $data = null, $callback = null, $type = null)
1074
+	{
1075
+		if (!is_array($data)) {
1076
+			$callback = $data;
1077
+			$data     = null;
1078
+		}
1079
+		// TODO some array_values on this shit
1080
+		return PhpQuery::ajax(
1081
+			array(
1082
+				'type'     => 'GET',
1083
+				'url'      => $url,
1084
+				'data'     => $data,
1085
+				'success'  => $callback,
1086
+				'dataType' => $type,
1087
+			)
1088
+		);
1089
+	}
1090
+
1091
+	public static function post($url, $data = null, $callback = null, $type = null)
1092
+	{
1093
+		if (!is_array($data)) {
1094
+			$callback = $data;
1095
+			$data     = null;
1096
+		}
1097
+		return PhpQuery::ajax(
1098
+			array(
1099
+				'type'     => 'POST',
1100
+				'url'      => $url,
1101
+				'data'     => $data,
1102
+				'success'  => $callback,
1103
+				'dataType' => $type,
1104
+			)
1105
+		);
1106
+	}
1107
+
1108
+	public static function getJSON($url, $data = null, $callback = null)
1109
+	{
1110
+		if (!is_array($data)) {
1111
+			$callback = $data;
1112
+			$data     = null;
1113
+		}
1114
+		// TODO some array_values on this shit
1115
+		return PhpQuery::ajax(
1116
+			array(
1117
+				'type'     => 'GET',
1118
+				'url'      => $url,
1119
+				'data'     => $data,
1120
+				'success'  => $callback,
1121
+				'dataType' => 'json',
1122
+			)
1123
+		);
1124
+	}
1125
+
1126
+	public static function ajaxSetup($options)
1127
+	{
1128
+		self::$ajaxSettings = array_merge(self::$ajaxSettings, $options);
1129
+	}
1130
+
1131
+	public static function ajaxAllowHost($host1, $host2 = null, $host3 = null)
1132
+	{
1133
+		$loop = is_array($host1) ? $host1 : func_get_args();
1134
+		foreach ($loop as $host) {
1135
+			if ($host && !in_array($host, PhpQuery::$ajaxAllowedHosts)) {
1136
+				PhpQuery::$ajaxAllowedHosts[] = $host;
1137
+			}
1138
+		}
1139
+	}
1140
+
1141
+	public static function ajaxAllowURL($url1, $url2 = null, $url3 = null)
1142
+	{
1143
+		$loop = is_array($url1) ? $url1 : func_get_args();
1144
+		foreach ($loop as $url)
1145
+			PhpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST));
1146
+	}
1147
+
1148
+	/**
1149
+	 * Returns JSON representation of $data.
1150
+	 *
1151
+	 * @static
1152
+	 * @param mixed $data
1153
+	 * @return string
1154
+	 */
1155
+	public static function toJSON($data)
1156
+	{
1157
+		if (function_exists('json_encode'))
1158
+			return json_encode($data);
1159
+		require_once('Zend/Json/Encoder.php');
1160
+		return \Zend_Json_Encoder::encode($data);
1161
+	}
1162
+
1163
+	/**
1164
+	 * Parses JSON into proper PHP type.
1165
+	 *
1166
+	 * @static
1167
+	 * @param string $json
1168
+	 * @return mixed
1169
+	 */
1170
+	public static function parseJSON($json)
1171
+	{
1172
+		if (function_exists('json_decode')) {
1173
+			$return = json_decode(trim($json), true);
1174
+			// json_decode and UTF8 issues
1175
+			if (isset($return))
1176
+				return $return;
1177
+		}
1178
+		require_once('Zend/Json/Decoder.php');
1179
+		return \Zend_Json_Decoder::decode($json);
1180
+	}
1181
+
1182
+	/**
1183
+	 * Returns source's document ID.
1184
+	 *
1185
+	 * @param $source \DOMNode|PhpQueryObject
1186
+	 * @return string
1187
+	 */
1188
+	public static function getDocumentID($source)
1189
+	{
1190
+		if ($source instanceof \DOMDocument) {
1191
+			foreach (PhpQuery::$documents as $id => $document) {
1192
+				if ($source->isSameNode($document->document))
1193
+					return $id;
1194
+			}
1195
+		} else if ($source instanceof \DOMNode) {
1196
+			foreach (PhpQuery::$documents as $id => $document) {
1197
+				if ($source->ownerDocument->isSameNode($document->document))
1198
+					return $id;
1199
+			}
1200
+		} else if ($source instanceof PhpQueryObject)
1201
+			return $source->getDocumentID();
1202
+		else if (is_string($source) && isset(PhpQuery::$documents[$source]))
1203
+			return $source;
1204
+	}
1205
+
1206
+	/**
1207
+	 * Get \DOMDocument object related to $source.
1208
+	 * Returns null if such document doesn't exist.
1209
+	 *
1210
+	 * @param $source \DOMNode|PhpQueryObject|string
1211
+	 * @return string
1212
+	 */
1213
+	public static function getDOMDocument($source)
1214
+	{
1215
+		if ($source instanceof \DOMDocument)
1216
+			return $source;
1217
+		$source = self::getDocumentID($source);
1218
+		return $source ? self::$documents[$id]['document'] : null;
1219
+	}
1220
+
1221
+	// UTILITIES
1222
+	// http://docs.jquery.com/Utilities
1223
+
1224
+	/**
1225
+	 *
1226
+	 * @link     http://docs.jquery.com/Utilities/jQuery.makeArray
1227
+	 * @param $object
1228
+	 * @return array
1229
+	 */
1230
+	public static function makeArray($object)
1231
+	{
1232
+		$array = array();
1233
+		if (is_object($object) && $object instanceof \DOMNodeList) {
1234
+			foreach ($object as $value)
1235
+				$array[] = $value;
1236
+		} else if (is_object($object) && !($object instanceof \Iterator)) {
1237
+			foreach (get_object_vars($object) as $name => $value)
1238
+				$array[0][$name] = $value;
1239
+		} else {
1240
+			foreach ($object as $name => $value)
1241
+				$array[0][$name] = $value;
1242
+		}
1243
+		return $array;
1244
+	}
1245
+
1246
+	public static function inArray($value, $array)
1247
+	{
1248
+		return in_array($value, $array);
1249
+	}
1250
+
1251
+	/**
1252
+	 *
1253
+	 * @param      $object
1254
+	 * @param      $callback
1255
+	 * @param null $param1
1256
+	 * @param null $param2
1257
+	 * @param null $param3
1258
+	 * @link http://docs.jquery.com/Utilities/jQuery.each
1259
+	 */
1260
+	public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null)
1261
+	{
1262
+		$paramStructure = null;
1263
+		if (func_num_args() > 2) {
1264
+			$paramStructure = func_get_args();
1265
+			$paramStructure = array_slice($paramStructure, 2);
1266
+		}
1267
+		if (is_object($object) && !($object instanceof \Iterator)) {
1268
+			foreach (get_object_vars($object) as $name => $value)
1269
+				PhpQuery::callbackRun(
1270
+					$callback,
1271
+					array(
1272
+						$name,
1273
+						$value
1274
+					),
1275
+					$paramStructure
1276
+				);
1277
+		} else {
1278
+			foreach ($object as $name => $value)
1279
+				PhpQuery::callbackRun(
1280
+					$callback,
1281
+					array(
1282
+						$name,
1283
+						$value
1284
+					),
1285
+					$paramStructure
1286
+				);
1287
+		}
1288
+	}
1289
+
1290
+	/**
1291
+	 *
1292
+	 * @link http://docs.jquery.com/Utilities/jQuery.map
1293
+	 */
1294
+	public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null)
1295
+	{
1296
+		$result         = array();
1297
+		$paramStructure = null;
1298
+		if (func_num_args() > 2) {
1299
+			$paramStructure = func_get_args();
1300
+			$paramStructure = array_slice($paramStructure, 2);
1301
+		}
1302
+		foreach ($array as $v) {
1303
+			$vv = PhpQuery::callbackRun(
1304
+				$callback,
1305
+				array(
1306
+					$v
1307
+				),
1308
+				$paramStructure
1309
+			);
1310
+			//			$callbackArgs = $args;
1311
+			//			foreach($args as $i => $arg) {
1312
+			//				$callbackArgs[$i] = $arg instanceof CallbackParam
1313
+			//					? $v
1314
+			//					: $arg;
1315
+			//			}
1316
+			//			$vv = call_user_func_array($callback, $callbackArgs);
1317
+			if (is_array($vv)) {
1318
+				foreach ($vv as $vvv)
1319
+					$result[] = $vvv;
1320
+			} else if ($vv !== null) {
1321
+				$result[] = $vv;
1322
+			}
1323
+		}
1324
+		return $result;
1325
+	}
1326
+
1327
+	/**
1328
+	 *
1329
+	 * @param $callback Callback
1330
+	 * @param $params
1331
+	 * @param $paramStructure
1332
+	 * @return bool|mixed
1333
+	 */
1334
+	public static function callbackRun($callback, $params = array(), $paramStructure = null)
1335
+	{
1336
+		if (!$callback)
1337
+			return;
1338
+		if ($callback instanceof \CallbackParameterToReference) {
1339
+			// TODO support ParamStructure to select which $param push to reference
1340
+			if (isset($params[0]))
1341
+				$callback->callback = $params[0];
1342
+			return true;
1343
+		}
1344
+		if ($callback instanceof \Callback) {
1345
+			$paramStructure = $callback->params;
1346
+			$callback       = $callback->callback;
1347
+		}
1348
+		if (!$paramStructure)
1349
+			return call_user_func_array($callback, $params);
1350
+		$p = 0;
1351
+		foreach ($paramStructure as $i => $v) {
1352
+			$paramStructure[$i] = $v instanceof \CallbackParam ? $params[$p++] : $v;
1353
+		}
1354
+		return call_user_func_array($callback, $paramStructure);
1355
+	}
1356
+
1357
+	/**
1358
+	 * Merge 2 PhpQuery objects.
1359
+	 * @param array $one
1360
+	 * @param array $two
1361
+	 * @return array
1362
+	 * @protected
1363
+	 * @todo node lists, PhpQueryObject
1364
+	 */
1365
+	public static function merge($one, $two)
1366
+	{
1367
+		$elements = $one->elements;
1368
+		foreach ($two->elements as $node) {
1369
+			$exists = false;
1370
+			foreach ($elements as $node2) {
1371
+				if ($node2->isSameNode($node))
1372
+					$exists = true;
1373
+			}
1374
+			if (!$exists)
1375
+				$elements[] = $node;
1376
+		}
1377
+		return $elements;
1378
+		//		$one = $one->newInstance();
1379
+		//		$one->elements = $elements;
1380
+		//		return $one;
1381
+	}
1382
+
1383
+	/**
1384
+	 *
1385
+	 * @param $array
1386
+	 * @param $callback
1387
+	 * @param $invert
1388
+	 * @return array
1389
+	 * @link http://docs.jquery.com/Utilities/jQuery.grep
1390
+	 */
1391
+	public static function grep($array, $callback, $invert = false)
1392
+	{
1393
+		$result = array();
1394
+		foreach ($array as $k => $v) {
1395
+			$r = call_user_func_array(
1396
+				$callback,
1397
+				array(
1398
+					$v,
1399
+					$k
1400
+				)
1401
+			);
1402
+			if ($r === !(bool) $invert)
1403
+				$result[] = $v;
1404
+		}
1405
+		return $result;
1406
+	}
1407
+
1408
+	public static function unique($array)
1409
+	{
1410
+		return array_unique($array);
1411
+	}
1412
+
1413
+	/**
1414
+	 *
1415
+	 * @param $function
1416
+	 * @return bool
1417
+	 * @TODO there are problems with non-static methods, second parameter pass it
1418
+	 *    but doesnt verify is method is really callable
1419
+	 */
1420
+	public static function isFunction($function)
1421
+	{
1422
+		return is_callable($function);
1423
+	}
1424
+
1425
+	public static function trim($str)
1426
+	{
1427
+		return trim($str);
1428
+	}
1429
+	/* PLUGINS NAMESPACE */
1430
+	/**
1431
+	 *
1432
+	 * @param $url
1433
+	 * @param $callback
1434
+	 * @param $param1
1435
+	 * @param $param2
1436
+	 * @param $param3
1437
+	 * @return PhpQueryObject
1438
+	 */
1439
+	public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null)
1440
+	{
1441
+		if (self::plugin('WebBrowser')) {
1442
+			$params = func_get_args();
1443
+			return self::callbackRun(
1444
+				array(
1445
+					self::$plugins,
1446
+					'browserGet'
1447
+				),
1448
+				$params
1449
+			);
1450
+		} else {
1451
+			self::debug('WebBrowser plugin not available...');
1452
+		}
1453
+	}
1454
+
1455
+	/**
1456
+	 *
1457
+	 * @param $url
1458
+	 * @param $data
1459
+	 * @param $callback
1460
+	 * @param $param1
1461
+	 * @param $param2
1462
+	 * @param $param3
1463
+	 * @return PhpQueryObject
1464
+	 */
1465
+	public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null)
1466
+	{
1467
+		if (self::plugin('WebBrowser')) {
1468
+			$params = func_get_args();
1469
+			return self::callbackRun(
1470
+				array(
1471
+					self::$plugins,
1472
+					'browserPost'
1473
+				),
1474
+				$params
1475
+			);
1476
+		} else {
1477
+			self::debug('WebBrowser plugin not available...');
1478
+		}
1479
+	}
1480
+
1481
+	/**
1482
+	 *
1483
+	 * @param $ajaxSettings
1484
+	 * @param $callback
1485
+	 * @param $param1
1486
+	 * @param $param2
1487
+	 * @param $param3
1488
+	 * @return PhpQueryObject
1489
+	 */
1490
+	public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null)
1491
+	{
1492
+		if (self::plugin('WebBrowser')) {
1493
+			$params = func_get_args();
1494
+			return self::callbackRun(
1495
+				array(
1496
+					self::$plugins,
1497
+					'browser'
1498
+				),
1499
+				$params
1500
+			);
1501
+		} else {
1502
+			self::debug('WebBrowser plugin not available...');
1503
+		}
1504
+	}
1505
+
1506
+	/**
1507
+	 *
1508
+	 * @param $code
1509
+	 * @return string
1510
+	 */
1511
+	public static function php($code)
1512
+	{
1513
+		return self::code('php', $code);
1514
+	}
1515
+
1516
+	/**
1517
+	 *
1518
+	 * @param $type
1519
+	 * @param $code
1520
+	 * @return string
1521
+	 */
1522
+	public static function code($type, $code)
1523
+	{
1524
+		return "<$type><!-- " . trim($code) . " --></$type>";
1525
+	}
1526
+
1527
+	public static function __callStatic($method, $params)
1528
+	{
1529
+		return call_user_func_array(
1530
+			array(
1531
+				PhpQuery::$plugins,
1532
+				$method
1533
+			),
1534
+			$params
1535
+		);
1536
+	}
1537
+
1538
+	protected static function dataSetupNode($node, $documentID)
1539
+	{
1540
+		// search are return if alredy exists
1541
+		foreach (PhpQuery::$documents[$documentID]->dataNodes as $dataNode) {
1542
+			if ($node->isSameNode($dataNode))
1543
+				return $dataNode;
1544
+		}
1545
+		// if doesn't, add it
1546
+		PhpQuery::$documents[$documentID]->dataNodes[] = $node;
1547
+		return $node;
1548
+	}
1549
+
1550
+	protected static function dataRemoveNode($node, $documentID)
1551
+	{
1552
+		// search are return if alredy exists
1553
+		foreach (PhpQuery::$documents[$documentID]->dataNodes as $k => $dataNode) {
1554
+			if ($node->isSameNode($dataNode)) {
1555
+				unset(self::$documents[$documentID]->dataNodes[$k]);
1556
+				unset(self::$documents[$documentID]->data[$dataNode->dataID]);
1557
+			}
1558
+		}
1559
+	}
1560
+
1561
+	public static function data($node, $name, $data, $documentID = null)
1562
+	{
1563
+		if (!$documentID)
1564
+			// TODO check if this works
1565
+			$documentID = self::getDocumentID($node);
1566
+		$document = PhpQuery::$documents[$documentID];
1567
+		$node     = self::dataSetupNode($node, $documentID);
1568
+		if (!isset($node->dataID))
1569
+			$node->dataID = ++PhpQuery::$documents[$documentID]->uuid;
1570
+		$id = $node->dataID;
1571
+		if (!isset($document->data[$id]))
1572
+			$document->data[$id] = array();
1573
+		if (!is_null($data))
1574
+			$document->data[$id][$name] = $data;
1575
+		if ($name) {
1576
+			if (isset($document->data[$id][$name]))
1577
+				return $document->data[$id][$name];
1578
+		} else
1579
+			return $id;
1580
+	}
1581
+
1582
+	public static function removeData($node, $name, $documentID)
1583
+	{
1584
+		if (!$documentID)
1585
+			// TODO check if this works
1586
+			$documentID = self::getDocumentID($node);
1587
+		$document = PhpQuery::$documents[$documentID];
1588
+		$node     = self::dataSetupNode($node, $documentID);
1589
+		$id       = $node->dataID;
1590
+		if ($name) {
1591
+			if (isset($document->data[$id][$name]))
1592
+				unset($document->data[$id][$name]);
1593
+			$name = null;
1594
+			foreach ($document->data[$id] as $name)
1595
+				break;
1596
+			if (!$name)
1597
+				self::removeData($node, $name, $documentID);
1598
+		} else {
1599
+			self::dataRemoveNode($node, $documentID);
1600
+		}
1601
+	}
1602 1602
 }
1603 1603
 
1604 1604
 /**
@@ -1610,24 +1610,24 @@  discard block
 block discarded – undo
1610 1610
  */
1611 1611
 class PhpQueryPlugins
1612 1612
 {
1613
-    public function __call($method, $args)
1614
-    {
1615
-        if (isset(PhpQuery::$extendStaticMethods[$method])) {
1616
-            $return = call_user_func_array(PhpQuery::$extendStaticMethods[$method], $args);
1617
-        } else if (isset(PhpQuery::$pluginsStaticMethods[$method])) {
1618
-            $class     = PhpQuery::$pluginsStaticMethods[$method];
1619
-            $realClass = "\PhpQuery\Plugin\Util$class";
1620
-            $return    = call_user_func_array(
1621
-                array(
1622
-                    $realClass,
1623
-                    $method
1624
-                ),
1625
-                $args
1626
-            );
1627
-            return isset($return) ? $return : $this;
1628
-        } else
1629
-            throw new \Exception("Method '{$method}' doesnt exist");
1630
-    }
1613
+	public function __call($method, $args)
1614
+	{
1615
+		if (isset(PhpQuery::$extendStaticMethods[$method])) {
1616
+			$return = call_user_func_array(PhpQuery::$extendStaticMethods[$method], $args);
1617
+		} else if (isset(PhpQuery::$pluginsStaticMethods[$method])) {
1618
+			$class     = PhpQuery::$pluginsStaticMethods[$method];
1619
+			$realClass = "\PhpQuery\Plugin\Util$class";
1620
+			$return    = call_user_func_array(
1621
+				array(
1622
+					$realClass,
1623
+					$method
1624
+				),
1625
+				$args
1626
+			);
1627
+			return isset($return) ? $return : $this;
1628
+		} else
1629
+			throw new \Exception("Method '{$method}' doesnt exist");
1630
+	}
1631 1631
 }
1632 1632
 
1633 1633
 PhpQuery::$plugins = new PhpQueryPlugins();
1634 1634
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 
15 15
 namespace PhpQuery;
16 16
 
17
-require_once __DIR__ . '/bootstrap.php';
17
+require_once __DIR__.'/bootstrap.php';
18 18
 
19 19
 /**
20 20
  * Shortcut to PhpQuery::pq($arg1, $context)
@@ -123,9 +123,9 @@  discard block
 block discarded – undo
123 123
     public static function use_function($ns = '\\', $func = 'pq')
124 124
     {
125 125
         if ($ns{0} !== '\\') {
126
-            $ns = '\\' . $ns;
126
+            $ns = '\\'.$ns;
127 127
         }
128
-        if (!function_exists($ns . '\\' . $func)) {
128
+        if (!function_exists($ns.'\\'.$func)) {
129 129
             if ($ns === '\\') {
130 130
                 eval("function $func(\$a, \$b = '') { return \\PhpQuery\\PhpQuery::pq(\$a, \$b); }");
131 131
             } else {
@@ -424,18 +424,18 @@  discard block
 block discarded – undo
424 424
 
425 425
     public static function _phpToMarkupCallback($m, $charset = 'utf-8')
426 426
     {
427
-        return $m[1] . $m[2]
427
+        return $m[1].$m[2]
428 428
         . htmlspecialchars(
429
-            "<" . "?php" . $m[4] . "?" . ">",
429
+            "<"."?php".$m[4]."?".">",
430 430
             ENT_QUOTES
431 431
             | ENT_NOQUOTES,
432 432
             $charset
433
-        ) . $m[5] . $m[2];
433
+        ).$m[5].$m[2];
434 434
     }
435 435
 
436 436
     public static function _markupToPHPCallback($m)
437 437
     {
438
-        return "<" . "?php " . htmlspecialchars_decode($m[1]) . " ?" . ">";
438
+        return "<"."?php ".htmlspecialchars_decode($m[1])." ?".">";
439 439
     }
440 440
 
441 441
     /**
@@ -668,15 +668,15 @@  discard block
 block discarded – undo
668 668
         if (in_array($class, self::$pluginsLoaded))
669 669
             return true;
670 670
         if (!$file)
671
-            $file = $class . '.php';
672
-        $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class);
673
-        $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class);
671
+            $file = $class.'.php';
672
+        $objectClassExists = class_exists('\\PhpQuery\\Plugin\\'.$class);
673
+        $staticClassExists = class_exists('\PhpQuery\Plugin\Util'.$class);
674 674
         if (!$objectClassExists && !$staticClassExists)
675 675
             require_once($file);
676 676
         self::$pluginsLoaded[] = $class;
677 677
         // static methods
678
-        if (class_exists('\PhpQuery\Plugin\Util' . $class)) {
679
-            $realClass = '\PhpQuery\Plugin\Util' . $class;
678
+        if (class_exists('\PhpQuery\Plugin\Util'.$class)) {
679
+            $realClass = '\PhpQuery\Plugin\Util'.$class;
680 680
             $vars      = get_class_vars($realClass);
681 681
             $loop      = isset($vars['PhpQueryMethods'])
682 682
             && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
@@ -694,7 +694,7 @@  discard block
 block discarded – undo
694 694
                     continue;
695 695
                 if (isset(self::$pluginsStaticMethods[$method])) {
696 696
                     throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '"
697
-                                         . self::$pluginsStaticMethods[$method] . "'");
697
+                                         . self::$pluginsStaticMethods[$method]."'");
698 698
                 }
699 699
                 self::$pluginsStaticMethods[$method] = $class;
700 700
             }
@@ -708,8 +708,8 @@  discard block
 block discarded – undo
708 708
                 );
709 709
         }
710 710
         // object methods
711
-        if (class_exists('\\PhpQuery\\Plugin\\' . $class)) {
712
-            $realClass = '\\PhpQuery\\Plugin\\' . $class;
711
+        if (class_exists('\\PhpQuery\\Plugin\\'.$class)) {
712
+            $realClass = '\\PhpQuery\\Plugin\\'.$class;
713 713
             $vars      = get_class_vars($realClass);
714 714
             $loop      = isset($vars['PhpQueryMethods'])
715 715
             && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
@@ -725,7 +725,7 @@  discard block
 block discarded – undo
725 725
                     continue;
726 726
                 if (isset(self::$pluginsMethods[$method])) {
727 727
                     throw new \Exception("Duplicate method '{$method}' from plugin '{$class}' conflicts with same method from plugin '"
728
-                                         . self::$pluginsMethods[$method] . "'");
728
+                                         . self::$pluginsMethods[$method]."'");
729 729
                     continue;
730 730
                 }
731 731
                 self::$pluginsMethods[$method] = $class;
@@ -869,7 +869,7 @@  discard block
 block discarded – undo
869 869
             $options['dataType'] = 'json';
870 870
         }
871 871
         if (isset($options['dataType']) && $options['dataType'] == 'json') {
872
-            $jsonpCallback = 'json_' . md5(microtime());
872
+            $jsonpCallback = 'json_'.md5(microtime());
873 873
             $jsonpData     = $jsonpUrl = false;
874 874
             if ($options['data']) {
875 875
                 foreach ($options['data'] as $n => $v) {
@@ -954,7 +954,7 @@  discard block
 block discarded – undo
954 954
             );
955 955
         if (PhpQuery::$debug) {
956 956
             self::debug("{$options['type']}: {$options['url']}\n");
957
-            self::debug("Options: <pre>" . var_export($options, true) . "</pre>\n");
957
+            self::debug("Options: <pre>".var_export($options, true)."</pre>\n");
958 958
             //			if ($client->getCookieJar())
959 959
             //				self::debug("Cookies: <pre>".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."</pre>\n");
960 960
         }
@@ -962,7 +962,7 @@  discard block
 block discarded – undo
962 962
         $response = $client->request();
963 963
         if (PhpQuery::$debug) {
964 964
             self::debug(
965
-                'Status: ' . $response->getStatus() . ' / '
965
+                'Status: '.$response->getStatus().' / '
966 966
                 . $response->getMessage()
967 967
             );
968 968
             self::debug($client->getLastRequest());
@@ -1521,7 +1521,7 @@  discard block
 block discarded – undo
1521 1521
      */
1522 1522
     public static function code($type, $code)
1523 1523
     {
1524
-        return "<$type><!-- " . trim($code) . " --></$type>";
1524
+        return "<$type><!-- ".trim($code)." --></$type>";
1525 1525
     }
1526 1526
 
1527 1527
     public static function __callStatic($method, $params)
Please login to merge, or discard this patch.
Braces   +217 added lines, -146 removed lines patch added patch discarded remove patch
@@ -311,10 +311,11 @@  discard block
 block discarded – undo
311 311
      */
312 312
     public static function getDocument($id = null)
313 313
     {
314
-        if ($id)
315
-            PhpQuery::selectDocument($id);
316
-        else
317
-            $id = PhpQuery::$defaultDocumentID;
314
+        if ($id) {
315
+                    PhpQuery::selectDocument($id);
316
+        } else {
317
+                    $id = PhpQuery::$defaultDocumentID;
318
+        }
318 319
         return new PhpQueryObject($id);
319 320
     }
320 321
 
@@ -328,8 +329,9 @@  discard block
 block discarded – undo
328 329
      */
329 330
     public static function newDocument($markup = null, $contentType = null)
330 331
     {
331
-        if (!$markup)
332
-            $markup = '';
332
+        if (!$markup) {
333
+                    $markup = '';
334
+        }
333 335
         $documentID = PhpQuery::createDocumentWrapper($markup, $contentType);
334 336
         return new PhpQueryObject($documentID);
335 337
     }
@@ -399,8 +401,8 @@  discard block
 block discarded – undo
399 401
             '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<'
400 402
             . '?php?(.*?)(?:\\?>)([^"]*)"@s',
401 403
         );
402
-        foreach ($regexes as $regex)
403
-            while (preg_match($regex, $php, $matches)) {
404
+        foreach ($regexes as $regex) {
405
+                    while (preg_match($regex, $php, $matches)) {
404 406
                 $php = preg_replace_callback(
405 407
                     $regex,
406 408
                     //					create_function('$m, $charset = "'.$charset.'"',
@@ -414,6 +416,7 @@  discard block
 block discarded – undo
414 416
                     ),
415 417
                     $php
416 418
                 );
419
+        }
417 420
             }
418 421
         $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s';
419 422
         //preg_match_all($regex, $php, $matches);
@@ -447,8 +450,9 @@  discard block
 block discarded – undo
447 450
      */
448 451
     public static function markupToPHP($content)
449 452
     {
450
-        if ($content instanceof PhpQueryObject)
451
-            $content = $content->markupOuter();
453
+        if ($content instanceof PhpQueryObject) {
454
+                    $content = $content->markupOuter();
455
+        }
452 456
         /* <php>...</php> to <?php...? > */
453 457
         $content = preg_replace_callback(
454 458
             '@<php>\s*<!--(.*?)-->\s*</php>@s',
@@ -466,8 +470,8 @@  discard block
 block discarded – undo
466 470
             '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^\']*)\'@s',
467 471
             '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^"]*)"@s',
468 472
         );
469
-        foreach ($regexes as $regex)
470
-            while (preg_match($regex, $content))
473
+        foreach ($regexes as $regex) {
474
+                    while (preg_match($regex, $content))
471 475
                 $content = preg_replace_callback(
472 476
                     $regex,
473 477
                     create_function(
@@ -482,6 +486,7 @@  discard block
 block discarded – undo
482 486
                     ),
483 487
                     $content
484 488
                 );
489
+        }
485 490
         return $content;
486 491
     }
487 492
 
@@ -581,8 +586,9 @@  discard block
 block discarded – undo
581 586
      */
582 587
     protected static function createDocumentWrapper($html, $contentType = null, $documentID = null)
583 588
     {
584
-        if (function_exists('domxml_open_mem'))
585
-            throw new \Exception("Old PHP4 DOM XML extension detected. PhpQuery won't work until this extension is enabled.");
589
+        if (function_exists('domxml_open_mem')) {
590
+                    throw new \Exception("Old PHP4 DOM XML extension detected. PhpQuery won't work until this extension is enabled.");
591
+        }
586 592
         //		$id = $documentID
587 593
         //			? $documentID
588 594
         //			: md5(microtime());
@@ -629,10 +635,11 @@  discard block
 block discarded – undo
629 635
             default:
630 636
                 throw new \Exception("Unsupported \$target type");
631 637
         }
632
-        if (is_string($source))
633
-            $source = array(
638
+        if (is_string($source)) {
639
+                    $source = array(
634 640
                 $source => $source
635 641
             );
642
+        }
636 643
         foreach ($source as $method => $callback) {
637 644
             if (isset($targetRef[$method])) {
638 645
                 //				throw new \Exception
@@ -665,14 +672,17 @@  discard block
 block discarded – undo
665 672
         // TODO $class checked agains PhpQuery_$class
666 673
         //		if (strpos($class, 'PhpQuery') === 0)
667 674
         //			$class = substr($class, 8);
668
-        if (in_array($class, self::$pluginsLoaded))
669
-            return true;
670
-        if (!$file)
671
-            $file = $class . '.php';
675
+        if (in_array($class, self::$pluginsLoaded)) {
676
+                    return true;
677
+        }
678
+        if (!$file) {
679
+                    $file = $class . '.php';
680
+        }
672 681
         $objectClassExists = class_exists('\\PhpQuery\\Plugin\\' . $class);
673 682
         $staticClassExists = class_exists('\PhpQuery\Plugin\Util' . $class);
674
-        if (!$objectClassExists && !$staticClassExists)
675
-            require_once($file);
683
+        if (!$objectClassExists && !$staticClassExists) {
684
+                    require_once($file);
685
+        }
676 686
         self::$pluginsLoaded[] = $class;
677 687
         // static methods
678 688
         if (class_exists('\PhpQuery\Plugin\Util' . $class)) {
@@ -682,30 +692,33 @@  discard block
 block discarded – undo
682 692
             && !is_null($vars['PhpQueryMethods']) ? $vars['PhpQueryMethods']
683 693
                 : get_class_methods($realClass);
684 694
             foreach ($loop as $method) {
685
-                if ($method == '__initialize')
686
-                    continue;
695
+                if ($method == '__initialize') {
696
+                                    continue;
697
+                }
687 698
                 if (!is_callable(
688 699
                     array(
689 700
                         $realClass,
690 701
                         $method
691 702
                     )
692 703
                 )
693
-                )
694
-                    continue;
704
+                ) {
705
+                                    continue;
706
+                }
695 707
                 if (isset(self::$pluginsStaticMethods[$method])) {
696 708
                     throw new \Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '"
697 709
                                          . self::$pluginsStaticMethods[$method] . "'");
698 710
                 }
699 711
                 self::$pluginsStaticMethods[$method] = $class;
700 712
             }
701
-            if (method_exists($realClass, '__initialize'))
702
-                call_user_func_array(
713
+            if (method_exists($realClass, '__initialize')) {
714
+                            call_user_func_array(
703 715
                     array(
704 716
                         $realClass,
705 717
                         '__initialize'
706 718
                     ),
707 719
                     array()
708 720
                 );
721
+            }
709 722
         }
710 723
         // object methods
711 724
         if (class_exists('\\PhpQuery\\Plugin\\' . $class)) {
@@ -721,8 +734,9 @@  discard block
 block discarded – undo
721 734
                         $method
722 735
                     )
723 736
                 )
724
-                )
725
-                    continue;
737
+                ) {
738
+                                    continue;
739
+                }
726 740
                 if (isset(self::$pluginsMethods[$method])) {
727 741
                     throw new \Exception("Duplicate method '{$method}' from plugin '{$class}' conflicts with same method from plugin '"
728 742
                                          . self::$pluginsMethods[$method] . "'");
@@ -743,8 +757,9 @@  discard block
 block discarded – undo
743 757
     public static function unloadDocuments($id = null)
744 758
     {
745 759
         if (isset($id)) {
746
-            if ($id = self::getDocumentID($id))
747
-                unset(PhpQuery::$documents[$id]);
760
+            if ($id = self::getDocumentID($id)) {
761
+                            unset(PhpQuery::$documents[$id]);
762
+            }
748 763
         } else {
749 764
             foreach (PhpQuery::$documents as $k => $v) {
750 765
                 unset(PhpQuery::$documents[$k]);
@@ -767,10 +782,12 @@  discard block
 block discarded – undo
767 782
     public static function DOMNodeListToArray($DOMNodeList)
768 783
     {
769 784
         $array = array();
770
-        if (!$DOMNodeList)
771
-            return $array;
772
-        foreach ($DOMNodeList as $node)
773
-            $array[] = $node;
785
+        if (!$DOMNodeList) {
786
+                    return $array;
787
+        }
788
+        foreach ($DOMNodeList as $node) {
789
+                    $array[] = $node;
790
+        }
774 791
         return $array;
775 792
     }
776 793
 
@@ -789,8 +806,9 @@  discard block
 block discarded – undo
789 806
 
790 807
     public static function debug($text)
791 808
     {
792
-        if (self::$debug)
793
-            print var_dump($text);
809
+        if (self::$debug) {
810
+                    print var_dump($text);
811
+        }
794 812
     }
795 813
 
796 814
     /**
@@ -832,16 +850,18 @@  discard block
 block discarded – undo
832 850
             $client = new \Zend_Http_Client();
833 851
             $client->setCookieJar();
834 852
         }
835
-        if (isset($options['timeout']))
836
-            $client->setConfig(
853
+        if (isset($options['timeout'])) {
854
+                    $client->setConfig(
837 855
                 array(
838 856
                     'timeout' => $options['timeout'],
839 857
                 )
840 858
             );
859
+        }
841 860
         //			'maxredirects' => 0,
842
-        foreach (self::$ajaxAllowedHosts as $k => $host)
843
-            if ($host == '.' && isset($_SERVER['HTTP_HOST']))
861
+        foreach (self::$ajaxAllowedHosts as $k => $host) {
862
+                    if ($host == '.' && isset($_SERVER['HTTP_HOST']))
844 863
                 self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST'];
864
+        }
845 865
         $host = parse_url($options['url'], PHP_URL_HOST);
846 866
         if (!in_array($host, self::$ajaxAllowedHosts)) {
847 867
             throw new \Exception("Request not permitted, host '$host' not present in "
@@ -859,8 +879,9 @@  discard block
 block discarded – undo
859 879
             } else if ($options['data']) {
860 880
                 $jsonp = false;
861 881
                 foreach ($options['data'] as $n => $v) {
862
-                    if ($v == '?')
863
-                        $jsonp = true;
882
+                    if ($v == '?') {
883
+                                            $jsonp = true;
884
+                    }
864 885
                 }
865 886
                 if (!$jsonp) {
866 887
                     $options['data'][$jsonpCallbackParam] = '?';
@@ -873,25 +894,30 @@  discard block
 block discarded – undo
873 894
             $jsonpData     = $jsonpUrl = false;
874 895
             if ($options['data']) {
875 896
                 foreach ($options['data'] as $n => $v) {
876
-                    if ($v == '?')
877
-                        $jsonpData = $n;
897
+                    if ($v == '?') {
898
+                                            $jsonpData = $n;
899
+                    }
878 900
                 }
879 901
             }
880
-            if (preg_match($jsre, $options['url']))
881
-                $jsonpUrl = true;
902
+            if (preg_match($jsre, $options['url'])) {
903
+                            $jsonpUrl = true;
904
+            }
882 905
             if ($jsonpData !== false || $jsonpUrl) {
883 906
                 // remember callback name for httpData()
884 907
                 $options['_jsonp'] = $jsonpCallback;
885
-                if ($jsonpData !== false)
886
-                    $options['data'][$jsonpData] = $jsonpCallback;
887
-                if ($jsonpUrl)
888
-                    $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']);
908
+                if ($jsonpData !== false) {
909
+                                    $options['data'][$jsonpData] = $jsonpCallback;
910
+                }
911
+                if ($jsonpUrl) {
912
+                                    $options['url'] = preg_replace($jsre, "=$jsonpCallback\\1", $options['url']);
913
+                }
889 914
             }
890 915
         }
891 916
         $client->setUri($options['url']);
892 917
         $client->setMethod(strtoupper($options['type']));
893
-        if (isset($options['referer']) && $options['referer'])
894
-            $client->setHeaders('Referer', $options['referer']);
918
+        if (isset($options['referer']) && $options['referer']) {
919
+                    $client->setHeaders('Referer', $options['referer']);
920
+        }
895 921
         $client->setHeaders(
896 922
             array(
897 923
                 //			'content-type' => $options['contentType'],
@@ -904,14 +930,16 @@  discard block
 block discarded – undo
904 930
                 'Accept-Language' => 'en-us,en;q=0.5',
905 931
             )
906 932
         );
907
-        if ($options['username'])
908
-            $client->setAuth($options['username'], $options['password']);
909
-        if (isset($options['ifModified']) && $options['ifModified'])
910
-            $client->setHeaders(
933
+        if ($options['username']) {
934
+                    $client->setAuth($options['username'], $options['password']);
935
+        }
936
+        if (isset($options['ifModified']) && $options['ifModified']) {
937
+                    $client->setHeaders(
911 938
                 "If-Modified-Since",
912 939
                 self::$lastModified ? self::$lastModified
913 940
                     : "Thu, 01 Jan 1970 00:00:00 GMT"
914 941
             );
942
+        }
915 943
         $client->setHeaders(
916 944
             "Accept",
917 945
             isset($options['dataType'])
@@ -922,8 +950,9 @@  discard block
 block discarded – undo
922 950
         if ($options['data'] instanceof PhpQueryObject) {
923 951
             $serialized      = $options['data']->serializeArray($options['data']);
924 952
             $options['data'] = array();
925
-            foreach ($serialized as $r)
926
-                $options['data'][$r['name']] = $r['value'];
953
+            foreach ($serialized as $r) {
954
+                            $options['data'][$r['name']] = $r['value'];
955
+            }
927 956
         }
928 957
         if (strtolower($options['type']) == 'get') {
929 958
             $client->setParameterGet($options['data']);
@@ -931,20 +960,22 @@  discard block
 block discarded – undo
931 960
             $client->setEncType($options['contentType']);
932 961
             $client->setParameterPost($options['data']);
933 962
         }
934
-        if (self::$active == 0 && $options['global'])
935
-            PhpQueryEvents::trigger($documentID, 'ajaxStart');
963
+        if (self::$active == 0 && $options['global']) {
964
+                    PhpQueryEvents::trigger($documentID, 'ajaxStart');
965
+        }
936 966
         self::$active++;
937 967
         // beforeSend callback
938
-        if (isset($options['beforeSend']) && $options['beforeSend'])
939
-            PhpQuery::callbackRun(
968
+        if (isset($options['beforeSend']) && $options['beforeSend']) {
969
+                    PhpQuery::callbackRun(
940 970
                 $options['beforeSend'],
941 971
                 array(
942 972
                     $client
943 973
                 )
944 974
             );
975
+        }
945 976
         // ajaxSend event
946
-        if ($options['global'])
947
-            PhpQueryEvents::trigger(
977
+        if ($options['global']) {
978
+                    PhpQueryEvents::trigger(
948 979
                 $documentID,
949 980
                 'ajaxSend',
950 981
                 array(
@@ -952,6 +983,7 @@  discard block
 block discarded – undo
952 983
                     $options
953 984
                 )
954 985
             );
986
+        }
955 987
         if (PhpQuery::$debug) {
956 988
             self::debug("{$options['type']}: {$options['url']}\n");
957 989
             self::debug("Options: <pre>" . var_export($options, true) . "</pre>\n");
@@ -972,8 +1004,8 @@  discard block
 block discarded – undo
972 1004
             // XXX tempolary
973 1005
             self::$lastModified = $response->getHeader('Last-Modified');
974 1006
             $data               = self::httpData($response->getBody(), $options['dataType'], $options);
975
-            if (isset($options['success']) && $options['success'])
976
-                PhpQuery::callbackRun(
1007
+            if (isset($options['success']) && $options['success']) {
1008
+                            PhpQuery::callbackRun(
977 1009
                     $options['success'],
978 1010
                     array(
979 1011
                         $data,
@@ -981,8 +1013,9 @@  discard block
 block discarded – undo
981 1013
                         $options
982 1014
                     )
983 1015
                 );
984
-            if ($options['global'])
985
-                PhpQueryEvents::trigger(
1016
+            }
1017
+            if ($options['global']) {
1018
+                            PhpQueryEvents::trigger(
986 1019
                     $documentID,
987 1020
                     'ajaxSuccess',
988 1021
                     array(
@@ -990,9 +1023,10 @@  discard block
 block discarded – undo
990 1023
                         $options
991 1024
                     )
992 1025
                 );
1026
+            }
993 1027
         } else {
994
-            if (isset($options['error']) && $options['error'])
995
-                PhpQuery::callbackRun(
1028
+            if (isset($options['error']) && $options['error']) {
1029
+                            PhpQuery::callbackRun(
996 1030
                     $options['error'],
997 1031
                     array(
998 1032
                         $client,
@@ -1000,8 +1034,9 @@  discard block
 block discarded – undo
1000 1034
                         $response->getMessage()
1001 1035
                     )
1002 1036
                 );
1003
-            if ($options['global'])
1004
-                PhpQueryEvents::trigger(
1037
+            }
1038
+            if ($options['global']) {
1039
+                            PhpQueryEvents::trigger(
1005 1040
                     $documentID,
1006 1041
                     'ajaxError',
1007 1042
                     array(
@@ -1011,17 +1046,19 @@  discard block
 block discarded – undo
1011 1046
                         $options
1012 1047
                     )
1013 1048
                 );
1049
+            }
1014 1050
         }
1015
-        if (isset($options['complete']) && $options['complete'])
1016
-            PhpQuery::callbackRun(
1051
+        if (isset($options['complete']) && $options['complete']) {
1052
+                    PhpQuery::callbackRun(
1017 1053
                 $options['complete'],
1018 1054
                 array(
1019 1055
                     $client,
1020 1056
                     $response->getStatus()
1021 1057
                 )
1022 1058
             );
1023
-        if ($options['global'])
1024
-            PhpQueryEvents::trigger(
1059
+        }
1060
+        if ($options['global']) {
1061
+                    PhpQueryEvents::trigger(
1025 1062
                 $documentID,
1026 1063
                 'ajaxComplete',
1027 1064
                 array(
@@ -1029,8 +1066,10 @@  discard block
 block discarded – undo
1029 1066
                     $options
1030 1067
                 )
1031 1068
             );
1032
-        if ($options['global'] && !--self::$active)
1033
-            PhpQueryEvents::trigger($documentID, 'ajaxStop');
1069
+        }
1070
+        if ($options['global'] && !--self::$active) {
1071
+                    PhpQueryEvents::trigger($documentID, 'ajaxStop');
1072
+        }
1034 1073
         return $client;
1035 1074
         //		if (is_null($domId))
1036 1075
         //			$domId = self::$defaultDocumentID ? self::$defaultDocumentID : false;
@@ -1039,14 +1078,15 @@  discard block
 block discarded – undo
1039 1078
 
1040 1079
     protected static function httpData($data, $type, $options)
1041 1080
     {
1042
-        if (isset($options['dataFilter']) && $options['dataFilter'])
1043
-            $data = self::callbackRun(
1081
+        if (isset($options['dataFilter']) && $options['dataFilter']) {
1082
+                    $data = self::callbackRun(
1044 1083
                 $options['dataFilter'],
1045 1084
                 array(
1046 1085
                     $data,
1047 1086
                     $type
1048 1087
                 )
1049 1088
             );
1089
+        }
1050 1090
         if (is_string($data)) {
1051 1091
             if ($type == "json") {
1052 1092
                 if (isset($options['_jsonp']) && $options['_jsonp']) {
@@ -1141,8 +1181,9 @@  discard block
 block discarded – undo
1141 1181
     public static function ajaxAllowURL($url1, $url2 = null, $url3 = null)
1142 1182
     {
1143 1183
         $loop = is_array($url1) ? $url1 : func_get_args();
1144
-        foreach ($loop as $url)
1145
-            PhpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST));
1184
+        foreach ($loop as $url) {
1185
+                    PhpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST));
1186
+        }
1146 1187
     }
1147 1188
 
1148 1189
     /**
@@ -1154,8 +1195,9 @@  discard block
 block discarded – undo
1154 1195
      */
1155 1196
     public static function toJSON($data)
1156 1197
     {
1157
-        if (function_exists('json_encode'))
1158
-            return json_encode($data);
1198
+        if (function_exists('json_encode')) {
1199
+                    return json_encode($data);
1200
+        }
1159 1201
         require_once('Zend/Json/Encoder.php');
1160 1202
         return \Zend_Json_Encoder::encode($data);
1161 1203
     }
@@ -1172,8 +1214,9 @@  discard block
 block discarded – undo
1172 1214
         if (function_exists('json_decode')) {
1173 1215
             $return = json_decode(trim($json), true);
1174 1216
             // json_decode and UTF8 issues
1175
-            if (isset($return))
1176
-                return $return;
1217
+            if (isset($return)) {
1218
+                            return $return;
1219
+            }
1177 1220
         }
1178 1221
         require_once('Zend/Json/Decoder.php');
1179 1222
         return \Zend_Json_Decoder::decode($json);
@@ -1189,18 +1232,21 @@  discard block
 block discarded – undo
1189 1232
     {
1190 1233
         if ($source instanceof \DOMDocument) {
1191 1234
             foreach (PhpQuery::$documents as $id => $document) {
1192
-                if ($source->isSameNode($document->document))
1193
-                    return $id;
1235
+                if ($source->isSameNode($document->document)) {
1236
+                                    return $id;
1237
+                }
1194 1238
             }
1195 1239
         } else if ($source instanceof \DOMNode) {
1196 1240
             foreach (PhpQuery::$documents as $id => $document) {
1197
-                if ($source->ownerDocument->isSameNode($document->document))
1198
-                    return $id;
1241
+                if ($source->ownerDocument->isSameNode($document->document)) {
1242
+                                    return $id;
1243
+                }
1199 1244
             }
1200
-        } else if ($source instanceof PhpQueryObject)
1201
-            return $source->getDocumentID();
1202
-        else if (is_string($source) && isset(PhpQuery::$documents[$source]))
1203
-            return $source;
1245
+        } else if ($source instanceof PhpQueryObject) {
1246
+                    return $source->getDocumentID();
1247
+        } else if (is_string($source) && isset(PhpQuery::$documents[$source])) {
1248
+                    return $source;
1249
+        }
1204 1250
     }
1205 1251
 
1206 1252
     /**
@@ -1212,8 +1258,9 @@  discard block
 block discarded – undo
1212 1258
      */
1213 1259
     public static function getDOMDocument($source)
1214 1260
     {
1215
-        if ($source instanceof \DOMDocument)
1216
-            return $source;
1261
+        if ($source instanceof \DOMDocument) {
1262
+                    return $source;
1263
+        }
1217 1264
         $source = self::getDocumentID($source);
1218 1265
         return $source ? self::$documents[$id]['document'] : null;
1219 1266
     }
@@ -1231,14 +1278,17 @@  discard block
 block discarded – undo
1231 1278
     {
1232 1279
         $array = array();
1233 1280
         if (is_object($object) && $object instanceof \DOMNodeList) {
1234
-            foreach ($object as $value)
1235
-                $array[] = $value;
1281
+            foreach ($object as $value) {
1282
+                            $array[] = $value;
1283
+            }
1236 1284
         } else if (is_object($object) && !($object instanceof \Iterator)) {
1237
-            foreach (get_object_vars($object) as $name => $value)
1238
-                $array[0][$name] = $value;
1285
+            foreach (get_object_vars($object) as $name => $value) {
1286
+                            $array[0][$name] = $value;
1287
+            }
1239 1288
         } else {
1240
-            foreach ($object as $name => $value)
1241
-                $array[0][$name] = $value;
1289
+            foreach ($object as $name => $value) {
1290
+                            $array[0][$name] = $value;
1291
+            }
1242 1292
         }
1243 1293
         return $array;
1244 1294
     }
@@ -1265,8 +1315,8 @@  discard block
 block discarded – undo
1265 1315
             $paramStructure = array_slice($paramStructure, 2);
1266 1316
         }
1267 1317
         if (is_object($object) && !($object instanceof \Iterator)) {
1268
-            foreach (get_object_vars($object) as $name => $value)
1269
-                PhpQuery::callbackRun(
1318
+            foreach (get_object_vars($object) as $name => $value) {
1319
+                            PhpQuery::callbackRun(
1270 1320
                     $callback,
1271 1321
                     array(
1272 1322
                         $name,
@@ -1274,9 +1324,10 @@  discard block
 block discarded – undo
1274 1324
                     ),
1275 1325
                     $paramStructure
1276 1326
                 );
1327
+            }
1277 1328
         } else {
1278
-            foreach ($object as $name => $value)
1279
-                PhpQuery::callbackRun(
1329
+            foreach ($object as $name => $value) {
1330
+                            PhpQuery::callbackRun(
1280 1331
                     $callback,
1281 1332
                     array(
1282 1333
                         $name,
@@ -1284,6 +1335,7 @@  discard block
 block discarded – undo
1284 1335
                     ),
1285 1336
                     $paramStructure
1286 1337
                 );
1338
+            }
1287 1339
         }
1288 1340
     }
1289 1341
 
@@ -1315,8 +1367,9 @@  discard block
 block discarded – undo
1315 1367
             //			}
1316 1368
             //			$vv = call_user_func_array($callback, $callbackArgs);
1317 1369
             if (is_array($vv)) {
1318
-                foreach ($vv as $vvv)
1319
-                    $result[] = $vvv;
1370
+                foreach ($vv as $vvv) {
1371
+                                    $result[] = $vvv;
1372
+                }
1320 1373
             } else if ($vv !== null) {
1321 1374
                 $result[] = $vv;
1322 1375
             }
@@ -1333,20 +1386,23 @@  discard block
 block discarded – undo
1333 1386
      */
1334 1387
     public static function callbackRun($callback, $params = array(), $paramStructure = null)
1335 1388
     {
1336
-        if (!$callback)
1337
-            return;
1389
+        if (!$callback) {
1390
+                    return;
1391
+        }
1338 1392
         if ($callback instanceof \CallbackParameterToReference) {
1339 1393
             // TODO support ParamStructure to select which $param push to reference
1340
-            if (isset($params[0]))
1341
-                $callback->callback = $params[0];
1394
+            if (isset($params[0])) {
1395
+                            $callback->callback = $params[0];
1396
+            }
1342 1397
             return true;
1343 1398
         }
1344 1399
         if ($callback instanceof \Callback) {
1345 1400
             $paramStructure = $callback->params;
1346 1401
             $callback       = $callback->callback;
1347 1402
         }
1348
-        if (!$paramStructure)
1349
-            return call_user_func_array($callback, $params);
1403
+        if (!$paramStructure) {
1404
+                    return call_user_func_array($callback, $params);
1405
+        }
1350 1406
         $p = 0;
1351 1407
         foreach ($paramStructure as $i => $v) {
1352 1408
             $paramStructure[$i] = $v instanceof \CallbackParam ? $params[$p++] : $v;
@@ -1368,11 +1424,13 @@  discard block
 block discarded – undo
1368 1424
         foreach ($two->elements as $node) {
1369 1425
             $exists = false;
1370 1426
             foreach ($elements as $node2) {
1371
-                if ($node2->isSameNode($node))
1372
-                    $exists = true;
1427
+                if ($node2->isSameNode($node)) {
1428
+                                    $exists = true;
1429
+                }
1430
+            }
1431
+            if (!$exists) {
1432
+                            $elements[] = $node;
1373 1433
             }
1374
-            if (!$exists)
1375
-                $elements[] = $node;
1376 1434
         }
1377 1435
         return $elements;
1378 1436
         //		$one = $one->newInstance();
@@ -1399,8 +1457,9 @@  discard block
 block discarded – undo
1399 1457
                     $k
1400 1458
                 )
1401 1459
             );
1402
-            if ($r === !(bool) $invert)
1403
-                $result[] = $v;
1460
+            if ($r === !(bool) $invert) {
1461
+                            $result[] = $v;
1462
+            }
1404 1463
         }
1405 1464
         return $result;
1406 1465
     }
@@ -1539,8 +1598,9 @@  discard block
 block discarded – undo
1539 1598
     {
1540 1599
         // search are return if alredy exists
1541 1600
         foreach (PhpQuery::$documents[$documentID]->dataNodes as $dataNode) {
1542
-            if ($node->isSameNode($dataNode))
1543
-                return $dataNode;
1601
+            if ($node->isSameNode($dataNode)) {
1602
+                            return $dataNode;
1603
+            }
1544 1604
         }
1545 1605
         // if doesn't, add it
1546 1606
         PhpQuery::$documents[$documentID]->dataNodes[] = $node;
@@ -1560,41 +1620,51 @@  discard block
 block discarded – undo
1560 1620
 
1561 1621
     public static function data($node, $name, $data, $documentID = null)
1562 1622
     {
1563
-        if (!$documentID)
1564
-            // TODO check if this works
1623
+        if (!$documentID) {
1624
+                    // TODO check if this works
1565 1625
             $documentID = self::getDocumentID($node);
1626
+        }
1566 1627
         $document = PhpQuery::$documents[$documentID];
1567 1628
         $node     = self::dataSetupNode($node, $documentID);
1568
-        if (!isset($node->dataID))
1569
-            $node->dataID = ++PhpQuery::$documents[$documentID]->uuid;
1629
+        if (!isset($node->dataID)) {
1630
+                    $node->dataID = ++PhpQuery::$documents[$documentID]->uuid;
1631
+        }
1570 1632
         $id = $node->dataID;
1571
-        if (!isset($document->data[$id]))
1572
-            $document->data[$id] = array();
1573
-        if (!is_null($data))
1574
-            $document->data[$id][$name] = $data;
1633
+        if (!isset($document->data[$id])) {
1634
+                    $document->data[$id] = array();
1635
+        }
1636
+        if (!is_null($data)) {
1637
+                    $document->data[$id][$name] = $data;
1638
+        }
1575 1639
         if ($name) {
1576
-            if (isset($document->data[$id][$name]))
1577
-                return $document->data[$id][$name];
1578
-        } else
1579
-            return $id;
1640
+            if (isset($document->data[$id][$name])) {
1641
+                            return $document->data[$id][$name];
1642
+            }
1643
+        } else {
1644
+                    return $id;
1645
+        }
1580 1646
     }
1581 1647
 
1582 1648
     public static function removeData($node, $name, $documentID)
1583 1649
     {
1584
-        if (!$documentID)
1585
-            // TODO check if this works
1650
+        if (!$documentID) {
1651
+                    // TODO check if this works
1586 1652
             $documentID = self::getDocumentID($node);
1653
+        }
1587 1654
         $document = PhpQuery::$documents[$documentID];
1588 1655
         $node     = self::dataSetupNode($node, $documentID);
1589 1656
         $id       = $node->dataID;
1590 1657
         if ($name) {
1591
-            if (isset($document->data[$id][$name]))
1592
-                unset($document->data[$id][$name]);
1658
+            if (isset($document->data[$id][$name])) {
1659
+                            unset($document->data[$id][$name]);
1660
+            }
1593 1661
             $name = null;
1594
-            foreach ($document->data[$id] as $name)
1595
-                break;
1596
-            if (!$name)
1597
-                self::removeData($node, $name, $documentID);
1662
+            foreach ($document->data[$id] as $name) {
1663
+                            break;
1664
+            }
1665
+            if (!$name) {
1666
+                            self::removeData($node, $name, $documentID);
1667
+            }
1598 1668
         } else {
1599 1669
             self::dataRemoveNode($node, $documentID);
1600 1670
         }
@@ -1625,8 +1695,9 @@  discard block
 block discarded – undo
1625 1695
                 $args
1626 1696
             );
1627 1697
             return isset($return) ? $return : $this;
1628
-        } else
1629
-            throw new \Exception("Method '{$method}' doesnt exist");
1698
+        } else {
1699
+                    throw new \Exception("Method '{$method}' doesnt exist");
1700
+        }
1630 1701
     }
1631 1702
 }
1632 1703
 
Please login to merge, or discard this patch.
src/PhpQueryEvents.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -107,7 +107,7 @@  discard block
 block discarded – undo
107 107
      * Binds a handler to one or more events (like click) for each matched element.
108 108
      * Can also bind custom events.
109 109
      *
110
-     * @param \DOMNode|PhpQueryObject|string $document
110
+     * @param string $document
111 111
      * @param                                $node
112 112
      * @param string                         $type
113 113
      * @param string                         $data Optional
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
     /**
142 142
      * Enter description here...
143 143
      *
144
-     * @param \DOMNode|PhpQueryObject|string $document
144
+     * @param string $document
145 145
      * @param                                $node
146 146
      * @param string                         $type
147 147
      * @param                                $callback
Please login to merge, or discard this patch.
Indentation   +173 added lines, -173 removed lines patch added patch discarded remove patch
@@ -12,182 +12,182 @@
 block discarded – undo
12 12
  */
13 13
 abstract class PhpQueryEvents
14 14
 {
15
-    /**
16
-     * Trigger a type of event on every matched element.
17
-     *
18
-     *
19
-     * @TODO exclusive events (with !)
20
-     * @TODO global events (test)
21
-     * @TODO support more than event in $type (space-separated)
22
-     * @param       $document
23
-     * @param       $type
24
-     * @param array $data
25
-     * @param null  $node
26
-     */
27
-    public static function trigger($document, $type, $data = array(), $node = null)
28
-    {
29
-        // trigger: function(type, data, elem, donative, extra) {
30
-        $documentID = PhpQuery::getDocumentID($document);
31
-        $namespace  = null;
32
-        if (strpos($type, '.') !== false) {
33
-            list($name, $namespace) = explode('.', $type);
34
-        } else {
35
-            $name = $type;
36
-        }
37
-        if (!$node) {
38
-            if (self::issetGlobal($documentID, $type)) {
39
-                $pq = PhpQuery::getDocument($documentID);
40
-                // TODO check add($pq->document)
41
-                $pq->find('*')->add($pq->document)->trigger($type, $data);
42
-            }
43
-        } else {
44
-            if (isset($data[0]) && $data[0] instanceof DOMEvent) {
45
-                $event                = $data[0];
46
-                $event->relatedTarget = $event->target;
47
-                $event->target        = $node;
48
-                $data                 = array_slice($data, 1);
49
-            } else {
50
-                $event = new DOMEvent(array(
51
-                                          'type'      => $type,
52
-                                          'target'    => $node,
53
-                                          'timeStamp' => time(),
54
-                                      ));
55
-            }
56
-            $i = 0;
57
-            while ($node) {
58
-                // TODO whois
59
-                PhpQuery::debug(
60
-                    "Triggering " . ($i ? "bubbled " : '')
61
-                    . "event '{$type}' on " . "node \n"
62
-                );
63
-                //.PhpQueryObject::whois($node)."\n");
64
-                $event->currentTarget = $node;
65
-                $eventNode            = self::getNode($documentID, $node);
66
-                if (isset($eventNode->eventHandlers)) {
67
-                    foreach ($eventNode->eventHandlers as $eventType => $handlers) {
68
-                        $eventNamespace = null;
69
-                        if (strpos($type, '.') !== false) {
70
-                            list($eventName, $eventNamespace) = explode('.', $eventType);
71
-                        } else {
72
-                            $eventName = $eventType;
73
-                        }
74
-                        if ($name != $eventName) {
75
-                            continue;
76
-                        }
77
-                        if ($namespace && $eventNamespace && $namespace != $eventNamespace) {
78
-                            continue;
79
-                        }
80
-                        foreach ($handlers as $handler) {
81
-                            PhpQuery::debug("Calling event handler\n");
82
-                            $event->data = $handler['data'] ? $handler['data'] : null;
83
-                            $params      = array_merge(
84
-                                array(
85
-                                    $event
86
-                                ),
87
-                                $data
88
-                            );
89
-                            $return      = PhpQuery::callbackRun($handler['callback'], $params);
90
-                            if ($return === false) {
91
-                                $event->bubbles = false;
92
-                            }
93
-                        }
94
-                    }
95
-                }
96
-                // to bubble or not to bubble...
97
-                if (!$event->bubbles) {
98
-                    break;
99
-                }
100
-                $node = $node->parentNode;
101
-                $i++;
102
-            }
103
-        }
104
-    }
15
+	/**
16
+	 * Trigger a type of event on every matched element.
17
+	 *
18
+	 *
19
+	 * @TODO exclusive events (with !)
20
+	 * @TODO global events (test)
21
+	 * @TODO support more than event in $type (space-separated)
22
+	 * @param       $document
23
+	 * @param       $type
24
+	 * @param array $data
25
+	 * @param null  $node
26
+	 */
27
+	public static function trigger($document, $type, $data = array(), $node = null)
28
+	{
29
+		// trigger: function(type, data, elem, donative, extra) {
30
+		$documentID = PhpQuery::getDocumentID($document);
31
+		$namespace  = null;
32
+		if (strpos($type, '.') !== false) {
33
+			list($name, $namespace) = explode('.', $type);
34
+		} else {
35
+			$name = $type;
36
+		}
37
+		if (!$node) {
38
+			if (self::issetGlobal($documentID, $type)) {
39
+				$pq = PhpQuery::getDocument($documentID);
40
+				// TODO check add($pq->document)
41
+				$pq->find('*')->add($pq->document)->trigger($type, $data);
42
+			}
43
+		} else {
44
+			if (isset($data[0]) && $data[0] instanceof DOMEvent) {
45
+				$event                = $data[0];
46
+				$event->relatedTarget = $event->target;
47
+				$event->target        = $node;
48
+				$data                 = array_slice($data, 1);
49
+			} else {
50
+				$event = new DOMEvent(array(
51
+										  'type'      => $type,
52
+										  'target'    => $node,
53
+										  'timeStamp' => time(),
54
+									  ));
55
+			}
56
+			$i = 0;
57
+			while ($node) {
58
+				// TODO whois
59
+				PhpQuery::debug(
60
+					"Triggering " . ($i ? "bubbled " : '')
61
+					. "event '{$type}' on " . "node \n"
62
+				);
63
+				//.PhpQueryObject::whois($node)."\n");
64
+				$event->currentTarget = $node;
65
+				$eventNode            = self::getNode($documentID, $node);
66
+				if (isset($eventNode->eventHandlers)) {
67
+					foreach ($eventNode->eventHandlers as $eventType => $handlers) {
68
+						$eventNamespace = null;
69
+						if (strpos($type, '.') !== false) {
70
+							list($eventName, $eventNamespace) = explode('.', $eventType);
71
+						} else {
72
+							$eventName = $eventType;
73
+						}
74
+						if ($name != $eventName) {
75
+							continue;
76
+						}
77
+						if ($namespace && $eventNamespace && $namespace != $eventNamespace) {
78
+							continue;
79
+						}
80
+						foreach ($handlers as $handler) {
81
+							PhpQuery::debug("Calling event handler\n");
82
+							$event->data = $handler['data'] ? $handler['data'] : null;
83
+							$params      = array_merge(
84
+								array(
85
+									$event
86
+								),
87
+								$data
88
+							);
89
+							$return      = PhpQuery::callbackRun($handler['callback'], $params);
90
+							if ($return === false) {
91
+								$event->bubbles = false;
92
+							}
93
+						}
94
+					}
95
+				}
96
+				// to bubble or not to bubble...
97
+				if (!$event->bubbles) {
98
+					break;
99
+				}
100
+				$node = $node->parentNode;
101
+				$i++;
102
+			}
103
+		}
104
+	}
105 105
 
106
-    /**
107
-     * Binds a handler to one or more events (like click) for each matched element.
108
-     * Can also bind custom events.
109
-     *
110
-     * @param \DOMNode|PhpQueryObject|string $document
111
-     * @param                                $node
112
-     * @param string                         $type
113
-     * @param string                         $data Optional
114
-     * @param                                $callback
115
-     *
116
-     * @TODO support '!' (exclusive) events
117
-     * @TODO support more than event in $type (space-separated)
118
-     * @TODO support binding to global events
119
-     */
120
-    public static function add($document, $node, $type, $data, $callback = null)
121
-    {
122
-        PhpQuery::debug("Binding '$type' event");
123
-        $documentID = PhpQuery::getDocumentID($document);
124
-        //		if (is_null($callback) && is_callable($data)) {
125
-        //			$callback = $data;
126
-        //			$data = null;
127
-        //		}
128
-        $eventNode = self::getNode($documentID, $node);
129
-        if (!$eventNode) {
130
-            $eventNode = self::setNode($documentID, $node);
131
-        }
132
-        if (!isset($eventNode->eventHandlers[$type])) {
133
-            $eventNode->eventHandlers[$type] = array();
134
-        }
135
-        $eventNode->eventHandlers[$type][] = array(
136
-            'callback' => $callback,
137
-            'data'     => $data,
138
-        );
139
-    }
106
+	/**
107
+	 * Binds a handler to one or more events (like click) for each matched element.
108
+	 * Can also bind custom events.
109
+	 *
110
+	 * @param \DOMNode|PhpQueryObject|string $document
111
+	 * @param                                $node
112
+	 * @param string                         $type
113
+	 * @param string                         $data Optional
114
+	 * @param                                $callback
115
+	 *
116
+	 * @TODO support '!' (exclusive) events
117
+	 * @TODO support more than event in $type (space-separated)
118
+	 * @TODO support binding to global events
119
+	 */
120
+	public static function add($document, $node, $type, $data, $callback = null)
121
+	{
122
+		PhpQuery::debug("Binding '$type' event");
123
+		$documentID = PhpQuery::getDocumentID($document);
124
+		//		if (is_null($callback) && is_callable($data)) {
125
+		//			$callback = $data;
126
+		//			$data = null;
127
+		//		}
128
+		$eventNode = self::getNode($documentID, $node);
129
+		if (!$eventNode) {
130
+			$eventNode = self::setNode($documentID, $node);
131
+		}
132
+		if (!isset($eventNode->eventHandlers[$type])) {
133
+			$eventNode->eventHandlers[$type] = array();
134
+		}
135
+		$eventNode->eventHandlers[$type][] = array(
136
+			'callback' => $callback,
137
+			'data'     => $data,
138
+		);
139
+	}
140 140
 
141
-    /**
142
-     * Enter description here...
143
-     *
144
-     * @param \DOMNode|PhpQueryObject|string $document
145
-     * @param                                $node
146
-     * @param string                         $type
147
-     * @param                                $callback
148
-     *
149
-     * @TODO namespace events
150
-     * @TODO support more than event in $type (space-separated)
151
-     */
152
-    public static function remove($document, $node, $type = null, $callback = null)
153
-    {
154
-        $documentID = PhpQuery::getDocumentID($document);
155
-        $eventNode  = self::getNode($documentID, $node);
156
-        if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) {
157
-            if ($callback) {
158
-                foreach ($eventNode->eventHandlers[$type] as $k => $handler) {
159
-                    if ($handler['callback'] == $callback) {
160
-                        unset($eventNode->eventHandlers[$type][$k]);
161
-                    }
162
-                }
163
-            } else {
164
-                unset($eventNode->eventHandlers[$type]);
165
-            }
166
-        }
167
-    }
141
+	/**
142
+	 * Enter description here...
143
+	 *
144
+	 * @param \DOMNode|PhpQueryObject|string $document
145
+	 * @param                                $node
146
+	 * @param string                         $type
147
+	 * @param                                $callback
148
+	 *
149
+	 * @TODO namespace events
150
+	 * @TODO support more than event in $type (space-separated)
151
+	 */
152
+	public static function remove($document, $node, $type = null, $callback = null)
153
+	{
154
+		$documentID = PhpQuery::getDocumentID($document);
155
+		$eventNode  = self::getNode($documentID, $node);
156
+		if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) {
157
+			if ($callback) {
158
+				foreach ($eventNode->eventHandlers[$type] as $k => $handler) {
159
+					if ($handler['callback'] == $callback) {
160
+						unset($eventNode->eventHandlers[$type][$k]);
161
+					}
162
+				}
163
+			} else {
164
+				unset($eventNode->eventHandlers[$type]);
165
+			}
166
+		}
167
+	}
168 168
 
169
-    protected static function getNode($documentID, $node)
170
-    {
171
-        foreach (PhpQuery::$documents[$documentID]->eventsNodes as $eventNode) {
172
-            if ($node->isSameNode($eventNode)) {
173
-                return $eventNode;
174
-            }
175
-        }
176
-    }
169
+	protected static function getNode($documentID, $node)
170
+	{
171
+		foreach (PhpQuery::$documents[$documentID]->eventsNodes as $eventNode) {
172
+			if ($node->isSameNode($eventNode)) {
173
+				return $eventNode;
174
+			}
175
+		}
176
+	}
177 177
 
178
-    protected static function setNode($documentID, $node)
179
-    {
180
-        PhpQuery::$documents[$documentID]->eventsNodes[] = $node;
181
-        return PhpQuery::$documents[$documentID]->eventsNodes[count(PhpQuery::$documents[$documentID]->eventsNodes)
182
-        - 1];
183
-    }
178
+	protected static function setNode($documentID, $node)
179
+	{
180
+		PhpQuery::$documents[$documentID]->eventsNodes[] = $node;
181
+		return PhpQuery::$documents[$documentID]->eventsNodes[count(PhpQuery::$documents[$documentID]->eventsNodes)
182
+		- 1];
183
+	}
184 184
 
185
-    protected static function issetGlobal($documentID, $type)
186
-    {
187
-        return isset(PhpQuery::$documents[$documentID]) ? in_array(
188
-            $type,
189
-            PhpQuery::$documents[$documentID]->eventsGlobal
190
-        )
191
-            : false;
192
-    }
185
+	protected static function issetGlobal($documentID, $type)
186
+	{
187
+		return isset(PhpQuery::$documents[$documentID]) ? in_array(
188
+			$type,
189
+			PhpQuery::$documents[$documentID]->eventsGlobal
190
+		)
191
+			: false;
192
+	}
193 193
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -57,8 +57,8 @@  discard block
 block discarded – undo
57 57
             while ($node) {
58 58
                 // TODO whois
59 59
                 PhpQuery::debug(
60
-                    "Triggering " . ($i ? "bubbled " : '')
61
-                    . "event '{$type}' on " . "node \n"
60
+                    "Triggering ".($i ? "bubbled " : '')
61
+                    . "event '{$type}' on "."node \n"
62 62
                 );
63 63
                 //.PhpQueryObject::whois($node)."\n");
64 64
                 $event->currentTarget = $node;
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
                                 ),
87 87
                                 $data
88 88
                             );
89
-                            $return      = PhpQuery::callbackRun($handler['callback'], $params);
89
+                            $return = PhpQuery::callbackRun($handler['callback'], $params);
90 90
                             if ($return === false) {
91 91
                                 $event->bubbles = false;
92 92
                             }
Please login to merge, or discard this patch.
src/PhpQueryObject.php 4 patches
Doc Comments   +31 added lines, -20 removed lines patch added patch discarded remove patch
@@ -294,6 +294,7 @@  discard block
 block discarded – undo
294 294
      * Enter description here...
295 295
      *
296 296
      * @link http://docs.jquery.com/Ajax/serializeArray
297
+     * @param PhpQueryObject $submit
297 298
      * @return array
298 299
      */
299 300
     public function serializeArray($submit = null)
@@ -371,7 +372,7 @@  discard block
 block discarded – undo
371 372
      * Determines if $char is really a char.
372 373
      *
373 374
      * @param string $char
374
-     * @return bool
375
+     * @return integer
375 376
      * @todo   rewrite me to charcode range ! ;)
376 377
      * @access private
377 378
      */
@@ -719,7 +720,7 @@  discard block
 block discarded – undo
719 720
      * contains(tokenize(@class, '\s'), "something")
720 721
      * @param string $class
721 722
      * @param string $node
722
-     * @return boolean
723
+     * @return boolean|null
723 724
      * @access private
724 725
      */
725 726
     protected function matchClasses($class, $node)
@@ -748,6 +749,8 @@  discard block
 block discarded – undo
748 749
 
749 750
     /**
750 751
      * @access private
752
+     * @param string $XQuery
753
+     * @param string $compare
751 754
      */
752 755
     protected function runQuery($XQuery, $selector = null, $compare = null)
753 756
     {
@@ -1572,7 +1575,7 @@  discard block
 block discarded – undo
1572 1575
      * @param      $url
1573 1576
      * @param null $data
1574 1577
      * @param null $callback
1575
-     * @return PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1578
+     * @return PhpQueryObject
1576 1579
      * @todo Support $selector
1577 1580
      */
1578 1581
     public function load($url, $data = null, $callback = null)
@@ -1639,7 +1642,7 @@  discard block
 block discarded – undo
1639 1642
      * Either sets the CSS property of an object or retrieves the
1640 1643
      * CSS property of a proejct.
1641 1644
      *
1642
-     * @param      $property_name
1645
+     * @param      string $property_name
1643 1646
      * @param bool $value
1644 1647
      * @return string of css property value
1645 1648
      * @todo
@@ -1810,7 +1813,7 @@  discard block
 block discarded – undo
1810 1813
     /**
1811 1814
      * Trigger a type of event on every matched element.
1812 1815
      *
1813
-     * @param                 $type
1816
+     * @param                 string $type
1814 1817
      * @param array|\PhpQuery $data
1815 1818
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1816 1819
      * @TODO support more than event in $type (space-separated)
@@ -1839,7 +1842,7 @@  discard block
 block discarded – undo
1839 1842
      * Binds a handler to one or more events (like click) for each matched element.
1840 1843
      * Can also bind custom events.
1841 1844
      *
1842
-     * @param       $type
1845
+     * @param       string $type
1843 1846
      * @param mixed $data Optional
1844 1847
      * @param       $callback
1845 1848
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
@@ -1863,7 +1866,7 @@  discard block
 block discarded – undo
1863 1866
      *
1864 1867
      * @param string $type
1865 1868
      * @param        $callback
1866
-     * @return unknown
1869
+     * @return PhpQueryObject
1867 1870
      * @TODO namespace events
1868 1871
      * @TODO support more than event in $type (space-separated)
1869 1872
      */
@@ -2097,7 +2100,7 @@  discard block
 block discarded – undo
2097 2100
     /**
2098 2101
      * Enter description here...
2099 2102
      *
2100
-     * @param $num
2103
+     * @param integer $num
2101 2104
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2102 2105
      */
2103 2106
     public function eq($num)
@@ -2113,7 +2116,7 @@  discard block
 block discarded – undo
2113 2116
     /**
2114 2117
      * Enter description here...
2115 2118
      *
2116
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2119
+     * @return integer
2117 2120
      */
2118 2121
     public function size()
2119 2122
     {
@@ -2123,7 +2126,7 @@  discard block
 block discarded – undo
2123 2126
     /**
2124 2127
      * Enter description here...
2125 2128
      *
2126
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2129
+     * @return integer
2127 2130
      * @deprecated Use length as attribute
2128 2131
      */
2129 2132
     public function length()
@@ -2186,7 +2189,7 @@  discard block
 block discarded – undo
2186 2189
     /**
2187 2190
      * Enter description here...
2188 2191
      *
2189
-     * @param String|PhpQuery $content
2192
+     * @param string $content
2190 2193
      * @link http://docs.jquery.com/Manipulation/replaceWith#content
2191 2194
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2192 2195
      */
@@ -2261,7 +2264,7 @@  discard block
 block discarded – undo
2261 2264
     /**
2262 2265
      * jQuey difference
2263 2266
      *
2264
-     * @param      $markup
2267
+     * @param      string $markup
2265 2268
      * @param null $callback1
2266 2269
      * @param null $callback2
2267 2270
      * @param null $callback3
@@ -2639,7 +2642,7 @@  discard block
 block discarded – undo
2639 2642
      * Internal insert method. Don't use it.
2640 2643
      *
2641 2644
      * @param unknown_type $target
2642
-     * @param unknown_type $type
2645
+     * @param string $type
2643 2646
      * @throws \Exception
2644 2647
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2645 2648
      * @access private
@@ -2825,7 +2828,7 @@  discard block
 block discarded – undo
2825 2828
     /**
2826 2829
      * Enter description here...
2827 2830
      *
2828
-     * @param unknown_type $start
2831
+     * @param integer $start
2829 2832
      * @param unknown_type $end
2830 2833
      *
2831 2834
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
@@ -3034,6 +3037,7 @@  discard block
 block discarded – undo
3034 3037
 
3035 3038
     /**
3036 3039
      * @access private
3040
+     * @param string $direction
3037 3041
      */
3038 3042
     protected function getElementSiblings($direction, $selector = null, $limitToOne = false)
3039 3043
     {
@@ -3062,7 +3066,7 @@  discard block
 block discarded – undo
3062 3066
     /**
3063 3067
      * Enter description here...
3064 3068
      *
3065
-     * @param null $selector
3069
+     * @param string $selector
3066 3070
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3067 3071
      */
3068 3072
     public function siblings($selector = null)
@@ -3082,7 +3086,7 @@  discard block
 block discarded – undo
3082 3086
     /**
3083 3087
      * Enter description here...
3084 3088
      *
3085
-     * @param null $selector
3089
+     * @param string $selector
3086 3090
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3087 3091
      */
3088 3092
     public function not($selector = null)
@@ -3312,6 +3316,9 @@  discard block
 block discarded – undo
3312 3316
         }
3313 3317
     }
3314 3318
 
3319
+    /**
3320
+     * @param string $attr
3321
+     */
3315 3322
     public function attr($attr = null, $value = null)
3316 3323
     {
3317 3324
         foreach ($this->stack(1) as $node) {
@@ -3405,7 +3412,7 @@  discard block
 block discarded – undo
3405 3412
     /**
3406 3413
      * Enter description here...
3407 3414
      *
3408
-     * @param $attr
3415
+     * @param string $attr
3409 3416
      * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3410 3417
      */
3411 3418
     public function removeAttr($attr)
@@ -3721,8 +3728,8 @@  discard block
 block discarded – undo
3721 3728
     /**
3722 3729
      * Enter description here...
3723 3730
      *
3724
-     * @param <type> $key
3725
-     * @param <type> $value
3731
+     * @param string $key
3732
+     * @param string $value
3726 3733
      * @return $this
3727 3734
      */
3728 3735
     public function data($key, $value = null)
@@ -3859,7 +3866,7 @@  discard block
 block discarded – undo
3859 3866
      * Returns node's XPath.
3860 3867
      *
3861 3868
      * @param unknown_type $oneNode
3862
-     * @param null         $namespace
3869
+     * @param string         $namespace
3863 3870
      * @return string
3864 3871
      * @TODO   use native getNodePath is avaible
3865 3872
      * @access private
@@ -3898,6 +3905,10 @@  discard block
 block discarded – undo
3898 3905
     }
3899 3906
 
3900 3907
     // HELPERS
3908
+
3909
+    /**
3910
+     * @return integer
3911
+     */
3901 3912
     public function whois($oneNode = null)
3902 3913
     {
3903 3914
         $return = array();
Please login to merge, or discard this patch.
Indentation   +3931 added lines, -3931 removed lines patch added patch discarded remove patch
@@ -14,1050 +14,1050 @@  discard block
 block discarded – undo
14 14
  */
15 15
 class PhpQueryObject implements \Iterator, \Countable, \ArrayAccess
16 16
 {
17
-    public $documentID = null;
18
-    /**
19
-     * \DOMDocument class.
20
-     *
21
-     * @var \DOMDocument
22
-     */
23
-    public $document = null;
24
-    public $charset = null;
25
-    /**
26
-     *
27
-     * @var Dom\DOMDocumentWrapper
28
-     */
29
-    public $documentWrapper = null;
30
-    /**
31
-     * XPath interface.
32
-     *
33
-     * @var \DOMXPath
34
-     */
35
-    public $xpath = null;
36
-    /**
37
-     * Stack of selected elements.
38
-     * @TODO refactor to ->nodes
39
-     * @var array
40
-     */
41
-    public $elements = array();
42
-    /**
43
-     * @access private
44
-     */
45
-    protected $elementsBackup = array();
46
-    /**
47
-     * @access private
48
-     */
49
-    protected $previous = null;
50
-    /**
51
-     * @access private
52
-     * @TODO   deprecate
53
-     */
54
-    protected $root = array();
55
-    /**
56
-     * Indicated if doument is just a fragment (no <html> tag).
57
-     *
58
-     * Every document is realy a full document, so even documentFragments can
59
-     * be queried against <html>, but getDocument(id)->htmlOuter() will return
60
-     * only contents of <body>.
61
-     *
62
-     * @var bool
63
-     */
64
-    public $documentFragment = true;
65
-    /**
66
-     * Iterator interface helper
67
-     * @access private
68
-     */
69
-    protected $elementsInterator = array();
70
-    /**
71
-     * Iterator interface helper
72
-     * @access private
73
-     */
74
-    protected $valid = false;
75
-    /**
76
-     * Iterator interface helper
77
-     * @access private
78
-     */
79
-    protected $current = null;
80
-
81
-    /**
82
-     * Indicates whether CSS has been parsed or not. We only parse CSS if needed.
83
-     * @access private
84
-     */
85
-    protected $cssIsParsed = array();
86
-    /**
87
-     * A collection of complete CSS selector strings.
88
-     * @access private;
89
-     */
90
-    protected $cssString = array();
91
-    /**
92
-     * Enter description here...
93
-     *
94
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
95
-     */
96
-
97
-    protected $attribute_css_mapping = array(
98
-        'bgcolor' => 'background-color',
99
-        'text'    => 'color',
100
-        'width'   => 'width',
101
-        'height'  => 'height'
102
-    );
103
-
104
-    public function __construct($documentID)
105
-    {
106
-        //		if ($documentID instanceof self)
107
-        //			var_dump($documentID->getDocumentID());
108
-        $id = $documentID instanceof self ? $documentID->getDocumentID()
109
-            : $documentID;
110
-        //		var_dump($id);
111
-        if (!isset(PhpQuery::$documents[$id])) {
112
-            //			var_dump(PhpQuery::$documents);
113
-            throw new \Exception("Document with ID '{$id}' isn't loaded. Use PhpQuery::newDocument(\$html) or PhpQuery::newDocumentFile(\$file) first.");
114
-        }
115
-        $this->documentID       = $id;
116
-        $this->documentWrapper  = & PhpQuery::$documents[$id];
117
-        $this->document         = & $this->documentWrapper->document;
118
-        $this->xpath            = & $this->documentWrapper->xpath;
119
-        $this->charset          = & $this->documentWrapper->charset;
120
-        $this->documentFragment = & $this->documentWrapper->isDocumentFragment;
121
-        // TODO check $this->DOM->documentElement;
122
-        //		$this->root = $this->document->documentElement;
123
-        $this->root = & $this->documentWrapper->root;
124
-        //		$this->toRoot();
125
-        $this->elements = array(
126
-            $this->root
127
-        );
128
-    }
129
-
130
-    /**
131
-     *
132
-     * @access private
133
-     * @param $attr
134
-     * @return \PhpQuery\PhpQueryObject|\PhpQuery\QueryTemplatesParse|\PhpQuery\QueryTemplatesSource|\PhpQuery\QueryTemplatesSourceQuery
135
-     */
136
-    public function __get($attr)
137
-    {
138
-        switch ($attr) {
139
-            // FIXME doesnt work at all ?
140
-            case 'length':
141
-                return $this->size();
142
-                break;
143
-            default:
144
-                return $this->$attr;
145
-        }
146
-    }
147
-
148
-    /**
149
-     * Saves actual object to $var by reference.
150
-     * Useful when need to break chain.
151
-     * @param PhpQueryObject $var
152
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
153
-     */
154
-    public function toReference(&$var)
155
-    {
156
-        return $var = $this;
157
-    }
158
-
159
-    public function documentFragment($state = null)
160
-    {
161
-        if ($state) {
162
-            PhpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state;
163
-            return $this;
164
-        }
165
-        return $this->documentFragment;
166
-    }
167
-
168
-    /**
169
-     * @access private
170
-     * @TODO   documentWrapper
171
-     */
172
-    protected function isRoot($node)
173
-    {
174
-        //		return $node instanceof \DOMDocument || $node->tagName == 'html';
175
-        return $node instanceof \DOMDocument
176
-        || ($node instanceof \DOMElement && $node->tagName == 'html')
177
-        || $this->root->isSameNode($node);
178
-    }
179
-
180
-    /**
181
-     * @access private
182
-     */
183
-    protected function stackIsRoot()
184
-    {
185
-        return $this->size() == 1 && $this->isRoot($this->elements[0]);
186
-    }
187
-
188
-    /**
189
-     * Enter description here...
190
-     * NON JQUERY METHOD
191
-     *
192
-     * Watch out, it doesn't creates new instance, can be reverted with end().
193
-     *
194
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
195
-     */
196
-    public function toRoot()
197
-    {
198
-        $this->elements = array(
199
-            $this->root
200
-        );
201
-        return $this;
202
-        //		return $this->newInstance(array($this->root));
203
-    }
204
-
205
-    /**
206
-     * Saves object's DocumentID to $var by reference.
207
-     * <code>
208
-     * $myDocumentId;
209
-     * PhpQuery::newDocument('<div/>')
210
-     *     ->getDocumentIDRef($myDocumentId)
211
-     *     ->find('div')->...
212
-     * </code>
213
-     *
214
-     * @param $documentID
215
-     * @internal param string $domId
216
-     * @see      PhpQuery::newDocument
217
-     * @see      PhpQuery::newDocumentFile
218
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
219
-     */
220
-    public function getDocumentIDRef(&$documentID)
221
-    {
222
-        $documentID = $this->getDocumentID();
223
-        return $this;
224
-    }
225
-
226
-    /**
227
-     * Returns object with stack set to document root.
228
-     *
229
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
230
-     */
231
-    public function getDocument()
232
-    {
233
-        return PhpQuery::getDocument($this->getDocumentID());
234
-    }
235
-
236
-    /**
237
-     *
238
-     * @return \DOMDocument
239
-     */
240
-    public function getDOMDocument()
241
-    {
242
-        return $this->document;
243
-    }
244
-
245
-    /**
246
-     * Get object's Document ID.
247
-     *
248
-     * @return string
249
-     */
250
-    public function getDocumentID()
251
-    {
252
-        return $this->documentID;
253
-    }
254
-
255
-    /**
256
-     * Unloads whole document from memory.
257
-     * CAUTION! None further operations will be possible on this document.
258
-     * All objects refering to it will be useless.
259
-     *
260
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
261
-     */
262
-    public function unloadDocument()
263
-    {
264
-        PhpQuery::unloadDocuments($this->getDocumentID());
265
-    }
266
-
267
-    public function isHTML()
268
-    {
269
-        return $this->documentWrapper->isHTML;
270
-    }
271
-
272
-    public function isXHTML()
273
-    {
274
-        return $this->documentWrapper->isXHTML;
275
-    }
276
-
277
-    public function isXML()
278
-    {
279
-        return $this->documentWrapper->isXML;
280
-    }
281
-
282
-    /**
283
-     * Enter description here...
284
-     *
285
-     * @link http://docs.jquery.com/Ajax/serialize
286
-     * @return string
287
-     */
288
-    public function serialize()
289
-    {
290
-        return PhpQuery::param($this->serializeArray());
291
-    }
292
-
293
-    /**
294
-     * Enter description here...
295
-     *
296
-     * @link http://docs.jquery.com/Ajax/serializeArray
297
-     * @return array
298
-     */
299
-    public function serializeArray($submit = null)
300
-    {
301
-        $source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not(
302
-            'form'
303
-        );
304
-        $return = array();
305
-        //		$source->dumpDie();
306
-        foreach ($source as $input) {
307
-            $input = PhpQuery::pq($input);
308
-            if ($input->is('[disabled]')) {
309
-                continue;
310
-            }
311
-            if (!$input->is('[name]')) {
312
-                continue;
313
-            }
314
-            if ($input->is('[type=checkbox]') && !$input->is('[checked]')) {
315
-                continue;
316
-            }
317
-            // jquery diff
318
-            if ($submit && $input->is('[type=submit]')) {
319
-                if ($submit instanceof \DOMElement
320
-                    && !$input->elements[0]->isSameNode($submit)
321
-                ) {
322
-                    continue;
323
-                } else {
324
-                    if (is_string($submit) && $input->attr('name') != $submit) {
325
-                        continue;
326
-                    }
327
-                }
328
-            }
329
-            $return[] = array(
330
-                'name'  => $input->attr('name'),
331
-                'value' => $input->val(),
332
-            );
333
-        }
334
-        return $return;
335
-    }
336
-
337
-    /**
338
-     * @access private
339
-     */
340
-    protected function debug($in)
341
-    {
342
-        if (!PhpQuery::$debug) {
343
-            return;
344
-        }
345
-        print('<pre>');
346
-        print_r($in);
347
-        // file debug
348
-        //		file_put_contents(dirname(__FILE__).'/PhpQuery.log', print_r($in, true)."\n", FILE_APPEND);
349
-        // quite handy debug trace
350
-        //		if ( is_array($in))
351
-        //			print_r(array_slice(debug_backtrace(), 3));
352
-        print("</pre>\n");
353
-    }
354
-
355
-    /**
356
-     * @access private
357
-     */
358
-    protected function isRegexp($pattern)
359
-    {
360
-        return in_array(
361
-            $pattern[mb_strlen($pattern) - 1],
362
-            array(
363
-                '^',
364
-                '*',
365
-                '$'
366
-            )
367
-        );
368
-    }
369
-
370
-    /**
371
-     * Determines if $char is really a char.
372
-     *
373
-     * @param string $char
374
-     * @return bool
375
-     * @todo   rewrite me to charcode range ! ;)
376
-     * @access private
377
-     */
378
-    protected function isChar($char)
379
-    {
380
-        return extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_eregi('\w', $char)
381
-            : preg_match('@\w@', $char);
382
-    }
383
-
384
-    /**
385
-     * @access private
386
-     */
387
-    protected function parseSelector($query)
388
-    {
389
-        // clean spaces
390
-        // TODO include this inside parsing ?
391
-        $query   = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query)));
392
-        $queries = array(
393
-            array()
394
-        );
395
-        if (!$query) {
396
-            return $queries;
397
-        }
398
-        $return       = & $queries[0];
399
-        $specialChars = array(
400
-            '>',
401
-            ' '
402
-        );
403
-        //		$specialCharsMapping = array('/' => '>');
404
-        $specialCharsMapping = array();
405
-        $strlen              = mb_strlen($query);
406
-        $classChars          = array(
407
-            '.',
408
-            '-'
409
-        );
410
-        $pseudoChars         = array(
411
-            '-'
412
-        );
413
-        $tagChars            = array(
414
-            '*',
415
-            '|',
416
-            '-'
417
-        );
418
-        // split multibyte string
419
-        // http://code.google.com/p/phpquery/issues/detail?id=76
420
-        $_query = array();
421
-        for ($i = 0; $i < $strlen; $i++) {
422
-            $_query[] = mb_substr($query, $i, 1);
423
-        }
424
-        $query = $_query;
425
-        // it works, but i dont like it...
426
-        $i = 0;
427
-        while ($i < $strlen) {
428
-            $c   = $query[$i];
429
-            $tmp = '';
430
-            // TAG
431
-            if ($this->isChar($c) || in_array($c, $tagChars)) {
432
-                while (isset($query[$i])
433
-                    && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) {
434
-                    $tmp .= $query[$i];
435
-                    $i++;
436
-                }
437
-                $return[] = $tmp;
438
-                // IDs
439
-            } else if ($c == '#') {
440
-                $i++;
441
-                while (isset($query[$i])
442
-                    && ($this->isChar($query[$i]) || $query[$i] == '-')) {
443
-                    $tmp .= $query[$i];
444
-                    $i++;
445
-                }
446
-                $return[] = '#' . $tmp;
447
-                // SPECIAL CHARS
448
-            } else if (in_array($c, $specialChars)) {
449
-                $return[] = $c;
450
-                $i++;
451
-                // MAPPED SPECIAL MULTICHARS
452
-                //			} else if ( $c.$query[$i+1] == '//') {
453
-                //				$return[] = ' ';
454
-                //				$i = $i+2;
455
-                // MAPPED SPECIAL CHARS
456
-            } else if (isset($specialCharsMapping[$c])) {
457
-                $return[] = $specialCharsMapping[$c];
458
-                $i++;
459
-                // COMMA
460
-            } else if ($c == ',') {
461
-                $queries[] = array();
462
-                $return    = & $queries[count($queries) - 1];
463
-                $i++;
464
-                while (isset($query[$i]) && $query[$i] == ' ') {
465
-                    $i++;
466
-                }
467
-                // CLASSES
468
-            } else if ($c == '.') {
469
-                while (isset($query[$i])
470
-                    && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) {
471
-                    $tmp .= $query[$i];
472
-                    $i++;
473
-                }
474
-                $return[] = $tmp;
475
-                // ~ General Sibling Selector
476
-            } else if ($c == '~') {
477
-                $spaceAllowed = true;
478
-                $tmp .= $query[$i++];
479
-                while (isset($query[$i])
480
-                    && ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
481
-                        || $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) {
482
-                    if ($query[$i] != ' ') {
483
-                        $spaceAllowed = false;
484
-                    }
485
-                    $tmp .= $query[$i];
486
-                    $i++;
487
-                }
488
-                $return[] = $tmp;
489
-                // + Adjacent sibling selectors
490
-            } else {
491
-                if ($c == '+') {
492
-                    $spaceAllowed = true;
493
-                    $tmp .= $query[$i++];
494
-                    while (isset($query[$i])
495
-                        && ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
496
-                            || $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) {
497
-                        if ($query[$i] != ' ') {
498
-                            $spaceAllowed = false;
499
-                        }
500
-                        $tmp .= $query[$i];
501
-                        $i++;
502
-                    }
503
-                    $return[] = $tmp;
504
-                    // ATTRS
505
-                } else {
506
-                    if ($c == '[') {
507
-                        $stack = 1;
508
-                        $tmp .= $c;
509
-                        while (isset($query[++$i])) {
510
-                            $tmp .= $query[$i];
511
-                            if ($query[$i] == '[') {
512
-                                $stack++;
513
-                            } else {
514
-                                if ($query[$i] == ']') {
515
-                                    $stack--;
516
-                                    if (!$stack) {
517
-                                        break;
518
-                                    }
519
-                                }
520
-                            }
521
-                        }
522
-                        $return[] = $tmp;
523
-                        $i++;
524
-                        // PSEUDO CLASSES
525
-                    } else {
526
-                        if ($c == ':') {
527
-                            $stack = 1;
528
-                            $tmp .= $query[$i++];
529
-                            while (isset($query[$i])
530
-                                && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) {
531
-                                $tmp .= $query[$i];
532
-                                $i++;
533
-                            }
534
-                            // with arguments ?
535
-                            if (isset($query[$i]) && $query[$i] == '(') {
536
-                                $tmp .= $query[$i];
537
-                                $stack = 1;
538
-                                while (isset($query[++$i])) {
539
-                                    $tmp .= $query[$i];
540
-                                    if ($query[$i] == '(') {
541
-                                        $stack++;
542
-                                    } else {
543
-                                        if ($query[$i] == ')') {
544
-                                            $stack--;
545
-                                            if (!$stack) {
546
-                                                break;
547
-                                            }
548
-                                        }
549
-                                    }
550
-                                }
551
-                                $return[] = $tmp;
552
-                                $i++;
553
-                            } else {
554
-                                $return[] = $tmp;
555
-                            }
556
-                        } else {
557
-                            $i++;
558
-                        }
559
-                    }
560
-                }
561
-            }
562
-        }
563
-        foreach ($queries as $k => $q) {
564
-            if (isset($q[0])) {
565
-                if (isset($q[0][0]) && $q[0][0] == ':')
566
-                    array_unshift($queries[$k], '*');
567
-                if ($q[0] != '>')
568
-                    array_unshift($queries[$k], ' ');
569
-            }
570
-        }
571
-        return $queries;
572
-    }
573
-
574
-    /**
575
-     * Return matched DOM nodes.
576
-     *
577
-     * @param int $index
578
-     * @return array|\DOMElement Single \DOMElement or array of \DOMElement.
579
-     */
580
-    public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
581
-    {
582
-        $return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index]
583
-            : null) : $this->elements;
584
-        // pass thou callbacks
585
-        $args = func_get_args();
586
-        $args = array_slice($args, 1);
587
-        foreach ($args as $callback) {
588
-            if (is_array($return))
589
-                foreach ($return as $k => $v)
590
-                    $return[$k] = PhpQuery::callbackRun(
591
-                        $callback,
592
-                        array(
593
-                            $v
594
-                        )
595
-                    );
596
-            else
597
-                $return = PhpQuery::callbackRun(
598
-                    $callback,
599
-                    array(
600
-                        $return
601
-                    )
602
-                );
603
-        }
604
-        return $return;
605
-    }
606
-
607
-    /**
608
-     * Return matched DOM nodes.
609
-     * jQuery difference.
610
-     *
611
-     * @param int  $index
612
-     * @param null $callback1
613
-     * @param null $callback2
614
-     * @param null $callback3
615
-     * @return array|string Returns string if $index != null
616
-     * @todo implement callbacks
617
-     * @todo return only arrays ?
618
-     * @todo maybe other name...
619
-     */
620
-    public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
621
-    {
622
-        if ($index)
623
-            $return = $this->eq($index)->text();
624
-        else {
625
-            $return = array();
626
-            for ($i = 0; $i < $this->size(); $i++) {
627
-                $return[] = $this->eq($i)->text();
628
-            }
629
-        }
630
-        // pass thou callbacks
631
-        $args = func_get_args();
632
-        $args = array_slice($args, 1);
633
-        foreach ($args as $callback) {
634
-            $return = PhpQuery::callbackRun(
635
-                $callback,
636
-                array(
637
-                    $return
638
-                )
639
-            );
640
-        }
641
-        return $return;
642
-    }
643
-
644
-    /**
645
-     * Return matched DOM nodes.
646
-     * jQuery difference.
647
-     *
648
-     * @param int  $index
649
-     * @param null $callback1
650
-     * @param null $callback2
651
-     * @param null $callback3
652
-     * @return array|string Returns string if $index != null
653
-     * @todo implement callbacks
654
-     * @todo return only arrays ?
655
-     * @todo maybe other name...
656
-     */
657
-    public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
658
-    {
659
-        if ($index)
660
-            $return = $this->eq($index)->text();
661
-        else {
662
-            $return = array();
663
-            for ($i = 0; $i < $this->size(); $i++) {
664
-                $return[] = $this->eq($i)->text();
665
-            }
666
-            // pass thou callbacks
667
-            $args = func_get_args();
668
-            $args = array_slice($args, 1);
669
-        }
670
-        foreach ($args as $callback) {
671
-            if (is_array($return))
672
-                foreach ($return as $k => $v)
673
-                    $return[$k] = PhpQuery::callbackRun(
674
-                        $callback,
675
-                        array(
676
-                            $v
677
-                        )
678
-                    );
679
-            else
680
-                $return = PhpQuery::callbackRun(
681
-                    $callback,
682
-                    array(
683
-                        $return
684
-                    )
685
-                );
686
-        }
687
-        return $return;
688
-    }
689
-
690
-    /**
691
-     * Returns new instance of actual class.
692
-     *
693
-     * @param array $newStack Optional. Will replace old stack with new and move old one to history.c
694
-     * @return \PhpQuery\PhpQueryObject
695
-     */
696
-    public function newInstance($newStack = null)
697
-    {
698
-        $class = get_class($this);
699
-        // support inheritance by passing old object to overloaded constructor
700
-        $new           = $class != 'PhpQuery' ? new $class($this, $this->getDocumentID())
701
-            : new PhpQueryObject($this->getDocumentID());
702
-        $new->previous = $this;
703
-        if (is_null($newStack)) {
704
-            $new->elements = $this->elements;
705
-            if ($this->elementsBackup)
706
-                $this->elements = $this->elementsBackup;
707
-        } else if (is_string($newStack)) {
708
-            $new->elements = PhpQuery::pq($newStack, $this->getDocumentID())->stack();
709
-        } else {
710
-            $new->elements = $newStack;
711
-        }
712
-        return $new;
713
-    }
714
-
715
-    /**
716
-     * Enter description here...
717
-     *
718
-     * In the future, when PHP will support XLS 2.0, then we would do that this way:
719
-     * contains(tokenize(@class, '\s'), "something")
720
-     * @param string $class
721
-     * @param string $node
722
-     * @return boolean
723
-     * @access private
724
-     */
725
-    protected function matchClasses($class, $node)
726
-    {
727
-        // multi-class
728
-        if (mb_strpos($class, '.', 1)) {
729
-            $classes          = explode('.', substr($class, 1));
730
-            $classesCount     = count($classes);
731
-            $nodeClasses      = explode(' ', $node->getAttribute('class'));
732
-            $nodeClassesCount = count($nodeClasses);
733
-            if ($classesCount > $nodeClassesCount)
734
-                return false;
735
-            $diff = count(array_diff($classes, $nodeClasses));
736
-            if (!$diff)
737
-                return true;
738
-            // single-class
739
-        } else {
740
-            return in_array(
741
-            // strip leading dot from class name
742
-                substr($class, 1),
743
-                // get classes for element as array
744
-                explode(' ', $node->getAttribute('class'))
745
-            );
746
-        }
747
-    }
748
-
749
-    /**
750
-     * @access private
751
-     */
752
-    protected function runQuery($XQuery, $selector = null, $compare = null)
753
-    {
754
-        if ($compare && !method_exists($this, $compare))
755
-            return false;
756
-        $stack = array();
757
-        if (!$this->elements)
758
-            $this->debug('Stack empty, skipping...');
759
-        //		var_dump($this->elements[0]->nodeType);
760
-        // element, document
761
-        foreach ($this->stack(
762
-                     array(
763
-                         1,
764
-                         9,
765
-                         13
766
-                     )
767
-                 ) as $k => $stackNode) {
768
-            $detachAfter = false;
769
-            // to work on detached nodes we need temporary place them somewhere
770
-            // thats because context xpath queries sucks ;]
771
-            $testNode = $stackNode;
772
-            while ($testNode) {
773
-                if (!$testNode->parentNode && !$this->isRoot($testNode)) {
774
-                    $this->root->appendChild($testNode);
775
-                    $detachAfter = $testNode;
776
-                    break;
777
-                }
778
-                $testNode = isset($testNode->parentNode) ? $testNode->parentNode : null;
779
-            }
780
-            // XXX tmp ?
781
-            $xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html')
782
-                : $this->getNodeXpath($stackNode);
783
-            // FIXME pseudoclasses-only query, support XML
784
-            $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*'
785
-                : $xpath . $XQuery;
786
-            $this->debug("XPATH: {$query}");
787
-            // run query, get elements
788
-            $nodes = $this->xpath->query($query);
789
-            $this->debug("QUERY FETCHED");
790
-            if (!$nodes->length)
791
-                $this->debug('Nothing found');
792
-            $debug = array();
793
-            foreach ($nodes as $node) {
794
-                $matched = false;
795
-                if ($compare) {
796
-                    PhpQuery::$debug ? $this->debug(
797
-                        "Found: " . $this->whois($node)
798
-                        . ", comparing with {$compare}()"
799
-                    ) : null;
800
-                    $PhpQueryDebug   = PhpQuery::$debug;
801
-                    PhpQuery::$debug = false;
802
-                    // TODO ??? use PhpQuery::callbackRun()
803
-                    if (call_user_func_array(
804
-                        array(
805
-                            $this,
806
-                            $compare
807
-                        ),
808
-                        array(
809
-                            $selector,
810
-                            $node
811
-                        )
812
-                    )
813
-                    )
814
-                        $matched = true;
815
-                    PhpQuery::$debug = $PhpQueryDebug;
816
-                } else {
817
-                    $matched = true;
818
-                }
819
-                if ($matched) {
820
-                    if (PhpQuery::$debug)
821
-                        $debug[] = $this->whois($node);
822
-                    $stack[] = $node;
823
-                }
824
-            }
825
-            if (PhpQuery::$debug) {
826
-                $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
827
-            }
828
-            if ($detachAfter)
829
-                $this->root->removeChild($detachAfter);
830
-        }
831
-        $this->elements = $stack;
832
-    }
833
-
834
-    /**
835
-     * Enter description here...
836
-     *
837
-     * @param      $selectors
838
-     * @param null $context
839
-     * @param bool $noHistory
840
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
841
-     */
842
-    public function find($selectors, $context = null, $noHistory = false)
843
-    {
844
-        if (!$noHistory)
845
-            // backup last stack /for end()/
846
-            $this->elementsBackup = $this->elements;
847
-        // allow to define context
848
-        // TODO combine code below with PhpQuery::pq() context guessing code
849
-        //   as generic function
850
-        if (isset($context)) {
851
-            if (!is_array($context) && $context instanceof \DOMElement) {
852
-                $this->elements = array(
853
-                    $context
854
-                );
855
-            } elseif (is_array($context)) {
856
-                $this->elements = array();
857
-                foreach ($context as $c)
858
-                    if ($c instanceof \DOMElement)
859
-                        $this->elements[] = $c;
860
-            } elseif ($context instanceof PhpQueryObject) {
861
-                $this->elements = $context->elements;
862
-            }
863
-        }
864
-
865
-        $queries = $this->parseSelector($selectors);
866
-
867
-        $this->debug(
868
-            array(
869
-                'FIND',
870
-                $selectors,
871
-                $queries
872
-            )
873
-        );
874
-        $XQuery = '';
875
-        // remember stack state because of multi-queries
876
-        $oldStack = $this->elements;
877
-        // here we will be keeping found elements
878
-        $stack = array();
879
-        foreach ($queries as $selector) {
880
-            $this->elements  = $oldStack;
881
-            $delimiterBefore = false;
882
-            foreach ($selector as $s) {
883
-                // TAG
884
-                $isTag = extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s)
885
-                    || $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*';
886
-                if ($isTag) {
887
-                    if ($this->isXML()) {
888
-                        // namespace support
889
-                        if (mb_strpos($s, '|') !== false) {
890
-                            $ns = $tag = null;
891
-                            list($ns, $tag) = explode('|', $s);
892
-                            $XQuery .= "$ns:$tag";
893
-                        } else if ($s == '*') {
894
-                            $XQuery .= "*";
895
-                        } else {
896
-                            $XQuery .= "*[local-name()='$s']";
897
-                        }
898
-                    } else {
899
-                        $XQuery .= $s;
900
-                    }
901
-                    // ID
902
-                } else if ($s[0] == '#') {
903
-                    if ($delimiterBefore)
904
-                        $XQuery .= '*';
905
-                    $XQuery .= "[@id='" . substr($s, 1) . "']";
906
-                    // ATTRIBUTES
907
-                } else if ($s[0] == '[') {
908
-                    if ($delimiterBefore)
909
-                        $XQuery .= '*';
910
-                    // strip side brackets
911
-                    $attr    = trim($s, '][');
912
-                    $execute = false;
913
-                    // attr with specifed value
914
-                    if (mb_strpos($s, '=')) {
915
-                        $value = null;
916
-                        list($attr, $value) = explode('=', $attr);
917
-                        $value = trim($value, "'\"");
918
-                        if ($this->isRegexp($attr)) {
919
-                            // cut regexp character
920
-                            $attr    = substr($attr, 0, -1);
921
-                            $execute = true;
922
-                            $XQuery .= "[@{$attr}]";
923
-                        } else {
924
-                            $XQuery .= "[@{$attr}='{$value}']";
925
-                        }
926
-                        // attr without specified value
927
-                    } else {
928
-                        $XQuery .= "[@{$attr}]";
929
-                    }
930
-                    if ($execute) {
931
-                        $this->runQuery($XQuery, $s, 'is');
932
-                        $XQuery = '';
933
-                        if (!$this->length())
934
-                            break;
935
-                    }
936
-                    // CLASSES
937
-                } else if ($s[0] == '.') {
938
-                    // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
939
-                    // thx wizDom ;)
940
-                    if ($delimiterBefore)
941
-                        $XQuery .= '*';
942
-                    $XQuery .= '[@class]';
943
-                    $this->runQuery($XQuery, $s, 'matchClasses');
944
-                    $XQuery = '';
945
-                    if (!$this->length())
946
-                        break;
947
-                    // ~ General Sibling Selector
948
-                } else if ($s[0] == '~') {
949
-                    $this->runQuery($XQuery);
950
-                    $XQuery         = '';
951
-                    $this->elements = $this->siblings(substr($s, 1))->elements;
952
-                    if (!$this->length())
953
-                        break;
954
-                    // + Adjacent sibling selectors
955
-                } else if ($s[0] == '+') {
956
-                    // TODO /following-sibling::
957
-                    $this->runQuery($XQuery);
958
-                    $XQuery         = '';
959
-                    $subSelector    = substr($s, 1);
960
-                    $subElements    = $this->elements;
961
-                    $this->elements = array();
962
-                    foreach ($subElements as $node) {
963
-                        // search first \DOMElement sibling
964
-                        $test = $node->nextSibling;
965
-                        while ($test && !($test instanceof \DOMElement))
966
-                            $test = $test->nextSibling;
967
-                        if ($test && $this->is($subSelector, $test))
968
-                            $this->elements[] = $test;
969
-                    }
970
-                    if (!$this->length())
971
-                        break;
972
-                    // PSEUDO CLASSES
973
-                } else if ($s[0] == ':') {
974
-                    // TODO optimization for :first :last
975
-                    if ($XQuery) {
976
-                        $this->runQuery($XQuery);
977
-                        $XQuery = '';
978
-                    }
979
-                    if (!$this->length())
980
-                        break;
981
-                    $this->pseudoClasses($s);
982
-                    if (!$this->length())
983
-                        break;
984
-                    // DIRECT DESCENDANDS
985
-                } else if ($s == '>') {
986
-                    $XQuery .= '/';
987
-                    $delimiterBefore = 2;
988
-                    // ALL DESCENDANDS
989
-                } else if ($s == ' ') {
990
-                    $XQuery .= '//';
991
-                    $delimiterBefore = 2;
992
-                    // ERRORS
993
-                } else {
994
-                    PhpQuery::debug("Unrecognized token '$s'");
995
-                }
996
-                $delimiterBefore = $delimiterBefore === 2;
997
-            }
998
-            // run query if any
999
-            if ($XQuery && $XQuery != '//') {
1000
-                $this->runQuery($XQuery);
1001
-                $XQuery = '';
1002
-            }
1003
-            foreach ($this->elements as $node)
1004
-                if (!$this->elementsContainsNode($node, $stack))
1005
-                    $stack[] = $node;
1006
-        }
1007
-        $this->elements = $stack;
1008
-        return $this->newInstance();
1009
-    }
1010
-
1011
-    /**
1012
-     * @todo   create API for classes with pseudoselectors
1013
-     * @access private
1014
-     */
1015
-    protected function pseudoClasses($class)
1016
-    {
1017
-        // TODO clean args parsing ?
1018
-        $class    = ltrim($class, ':');
1019
-        $haveArgs = mb_strpos($class, '(');
1020
-        if ($haveArgs !== false) {
1021
-            $args  = substr($class, $haveArgs + 1, -1);
1022
-            $class = substr($class, 0, $haveArgs);
1023
-        }
1024
-        switch ($class) {
1025
-            case 'even':
1026
-            case 'odd':
1027
-                $stack = array();
1028
-                foreach ($this->elements as $i => $node) {
1029
-                    if ($class == 'even' && ($i % 2) == 0)
1030
-                        $stack[] = $node;
1031
-                    else if ($class == 'odd' && $i % 2)
1032
-                        $stack[] = $node;
1033
-                }
1034
-                $this->elements = $stack;
1035
-                break;
1036
-            case 'eq':
1037
-                $k              = intval($args);
1038
-                $this->elements = isset($this->elements[$k]) ? array(
1039
-                    $this->elements[$k]
1040
-                ) : array();
1041
-                break;
1042
-            case 'gt':
1043
-                $this->elements = array_slice($this->elements, $args + 1);
1044
-                break;
1045
-            case 'lt':
1046
-                $this->elements = array_slice($this->elements, 0, $args + 1);
1047
-                break;
1048
-            case 'first':
1049
-                if (isset($this->elements[0]))
1050
-                    $this->elements = array(
1051
-                        $this->elements[0]
1052
-                    );
1053
-                break;
1054
-            case 'last':
1055
-                if ($this->elements)
1056
-                    $this->elements = array(
1057
-                        $this->elements[count($this->elements) - 1]
1058
-                    );
1059
-                break;
1060
-            /*case 'parent':
17
+	public $documentID = null;
18
+	/**
19
+	 * \DOMDocument class.
20
+	 *
21
+	 * @var \DOMDocument
22
+	 */
23
+	public $document = null;
24
+	public $charset = null;
25
+	/**
26
+	 *
27
+	 * @var Dom\DOMDocumentWrapper
28
+	 */
29
+	public $documentWrapper = null;
30
+	/**
31
+	 * XPath interface.
32
+	 *
33
+	 * @var \DOMXPath
34
+	 */
35
+	public $xpath = null;
36
+	/**
37
+	 * Stack of selected elements.
38
+	 * @TODO refactor to ->nodes
39
+	 * @var array
40
+	 */
41
+	public $elements = array();
42
+	/**
43
+	 * @access private
44
+	 */
45
+	protected $elementsBackup = array();
46
+	/**
47
+	 * @access private
48
+	 */
49
+	protected $previous = null;
50
+	/**
51
+	 * @access private
52
+	 * @TODO   deprecate
53
+	 */
54
+	protected $root = array();
55
+	/**
56
+	 * Indicated if doument is just a fragment (no <html> tag).
57
+	 *
58
+	 * Every document is realy a full document, so even documentFragments can
59
+	 * be queried against <html>, but getDocument(id)->htmlOuter() will return
60
+	 * only contents of <body>.
61
+	 *
62
+	 * @var bool
63
+	 */
64
+	public $documentFragment = true;
65
+	/**
66
+	 * Iterator interface helper
67
+	 * @access private
68
+	 */
69
+	protected $elementsInterator = array();
70
+	/**
71
+	 * Iterator interface helper
72
+	 * @access private
73
+	 */
74
+	protected $valid = false;
75
+	/**
76
+	 * Iterator interface helper
77
+	 * @access private
78
+	 */
79
+	protected $current = null;
80
+
81
+	/**
82
+	 * Indicates whether CSS has been parsed or not. We only parse CSS if needed.
83
+	 * @access private
84
+	 */
85
+	protected $cssIsParsed = array();
86
+	/**
87
+	 * A collection of complete CSS selector strings.
88
+	 * @access private;
89
+	 */
90
+	protected $cssString = array();
91
+	/**
92
+	 * Enter description here...
93
+	 *
94
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
95
+	 */
96
+
97
+	protected $attribute_css_mapping = array(
98
+		'bgcolor' => 'background-color',
99
+		'text'    => 'color',
100
+		'width'   => 'width',
101
+		'height'  => 'height'
102
+	);
103
+
104
+	public function __construct($documentID)
105
+	{
106
+		//		if ($documentID instanceof self)
107
+		//			var_dump($documentID->getDocumentID());
108
+		$id = $documentID instanceof self ? $documentID->getDocumentID()
109
+			: $documentID;
110
+		//		var_dump($id);
111
+		if (!isset(PhpQuery::$documents[$id])) {
112
+			//			var_dump(PhpQuery::$documents);
113
+			throw new \Exception("Document with ID '{$id}' isn't loaded. Use PhpQuery::newDocument(\$html) or PhpQuery::newDocumentFile(\$file) first.");
114
+		}
115
+		$this->documentID       = $id;
116
+		$this->documentWrapper  = & PhpQuery::$documents[$id];
117
+		$this->document         = & $this->documentWrapper->document;
118
+		$this->xpath            = & $this->documentWrapper->xpath;
119
+		$this->charset          = & $this->documentWrapper->charset;
120
+		$this->documentFragment = & $this->documentWrapper->isDocumentFragment;
121
+		// TODO check $this->DOM->documentElement;
122
+		//		$this->root = $this->document->documentElement;
123
+		$this->root = & $this->documentWrapper->root;
124
+		//		$this->toRoot();
125
+		$this->elements = array(
126
+			$this->root
127
+		);
128
+	}
129
+
130
+	/**
131
+	 *
132
+	 * @access private
133
+	 * @param $attr
134
+	 * @return \PhpQuery\PhpQueryObject|\PhpQuery\QueryTemplatesParse|\PhpQuery\QueryTemplatesSource|\PhpQuery\QueryTemplatesSourceQuery
135
+	 */
136
+	public function __get($attr)
137
+	{
138
+		switch ($attr) {
139
+			// FIXME doesnt work at all ?
140
+			case 'length':
141
+				return $this->size();
142
+				break;
143
+			default:
144
+				return $this->$attr;
145
+		}
146
+	}
147
+
148
+	/**
149
+	 * Saves actual object to $var by reference.
150
+	 * Useful when need to break chain.
151
+	 * @param PhpQueryObject $var
152
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
153
+	 */
154
+	public function toReference(&$var)
155
+	{
156
+		return $var = $this;
157
+	}
158
+
159
+	public function documentFragment($state = null)
160
+	{
161
+		if ($state) {
162
+			PhpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state;
163
+			return $this;
164
+		}
165
+		return $this->documentFragment;
166
+	}
167
+
168
+	/**
169
+	 * @access private
170
+	 * @TODO   documentWrapper
171
+	 */
172
+	protected function isRoot($node)
173
+	{
174
+		//		return $node instanceof \DOMDocument || $node->tagName == 'html';
175
+		return $node instanceof \DOMDocument
176
+		|| ($node instanceof \DOMElement && $node->tagName == 'html')
177
+		|| $this->root->isSameNode($node);
178
+	}
179
+
180
+	/**
181
+	 * @access private
182
+	 */
183
+	protected function stackIsRoot()
184
+	{
185
+		return $this->size() == 1 && $this->isRoot($this->elements[0]);
186
+	}
187
+
188
+	/**
189
+	 * Enter description here...
190
+	 * NON JQUERY METHOD
191
+	 *
192
+	 * Watch out, it doesn't creates new instance, can be reverted with end().
193
+	 *
194
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
195
+	 */
196
+	public function toRoot()
197
+	{
198
+		$this->elements = array(
199
+			$this->root
200
+		);
201
+		return $this;
202
+		//		return $this->newInstance(array($this->root));
203
+	}
204
+
205
+	/**
206
+	 * Saves object's DocumentID to $var by reference.
207
+	 * <code>
208
+	 * $myDocumentId;
209
+	 * PhpQuery::newDocument('<div/>')
210
+	 *     ->getDocumentIDRef($myDocumentId)
211
+	 *     ->find('div')->...
212
+	 * </code>
213
+	 *
214
+	 * @param $documentID
215
+	 * @internal param string $domId
216
+	 * @see      PhpQuery::newDocument
217
+	 * @see      PhpQuery::newDocumentFile
218
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
219
+	 */
220
+	public function getDocumentIDRef(&$documentID)
221
+	{
222
+		$documentID = $this->getDocumentID();
223
+		return $this;
224
+	}
225
+
226
+	/**
227
+	 * Returns object with stack set to document root.
228
+	 *
229
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
230
+	 */
231
+	public function getDocument()
232
+	{
233
+		return PhpQuery::getDocument($this->getDocumentID());
234
+	}
235
+
236
+	/**
237
+	 *
238
+	 * @return \DOMDocument
239
+	 */
240
+	public function getDOMDocument()
241
+	{
242
+		return $this->document;
243
+	}
244
+
245
+	/**
246
+	 * Get object's Document ID.
247
+	 *
248
+	 * @return string
249
+	 */
250
+	public function getDocumentID()
251
+	{
252
+		return $this->documentID;
253
+	}
254
+
255
+	/**
256
+	 * Unloads whole document from memory.
257
+	 * CAUTION! None further operations will be possible on this document.
258
+	 * All objects refering to it will be useless.
259
+	 *
260
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
261
+	 */
262
+	public function unloadDocument()
263
+	{
264
+		PhpQuery::unloadDocuments($this->getDocumentID());
265
+	}
266
+
267
+	public function isHTML()
268
+	{
269
+		return $this->documentWrapper->isHTML;
270
+	}
271
+
272
+	public function isXHTML()
273
+	{
274
+		return $this->documentWrapper->isXHTML;
275
+	}
276
+
277
+	public function isXML()
278
+	{
279
+		return $this->documentWrapper->isXML;
280
+	}
281
+
282
+	/**
283
+	 * Enter description here...
284
+	 *
285
+	 * @link http://docs.jquery.com/Ajax/serialize
286
+	 * @return string
287
+	 */
288
+	public function serialize()
289
+	{
290
+		return PhpQuery::param($this->serializeArray());
291
+	}
292
+
293
+	/**
294
+	 * Enter description here...
295
+	 *
296
+	 * @link http://docs.jquery.com/Ajax/serializeArray
297
+	 * @return array
298
+	 */
299
+	public function serializeArray($submit = null)
300
+	{
301
+		$source = $this->filter('form, input, select, textarea')->find('input, select, textarea')->andSelf()->not(
302
+			'form'
303
+		);
304
+		$return = array();
305
+		//		$source->dumpDie();
306
+		foreach ($source as $input) {
307
+			$input = PhpQuery::pq($input);
308
+			if ($input->is('[disabled]')) {
309
+				continue;
310
+			}
311
+			if (!$input->is('[name]')) {
312
+				continue;
313
+			}
314
+			if ($input->is('[type=checkbox]') && !$input->is('[checked]')) {
315
+				continue;
316
+			}
317
+			// jquery diff
318
+			if ($submit && $input->is('[type=submit]')) {
319
+				if ($submit instanceof \DOMElement
320
+					&& !$input->elements[0]->isSameNode($submit)
321
+				) {
322
+					continue;
323
+				} else {
324
+					if (is_string($submit) && $input->attr('name') != $submit) {
325
+						continue;
326
+					}
327
+				}
328
+			}
329
+			$return[] = array(
330
+				'name'  => $input->attr('name'),
331
+				'value' => $input->val(),
332
+			);
333
+		}
334
+		return $return;
335
+	}
336
+
337
+	/**
338
+	 * @access private
339
+	 */
340
+	protected function debug($in)
341
+	{
342
+		if (!PhpQuery::$debug) {
343
+			return;
344
+		}
345
+		print('<pre>');
346
+		print_r($in);
347
+		// file debug
348
+		//		file_put_contents(dirname(__FILE__).'/PhpQuery.log', print_r($in, true)."\n", FILE_APPEND);
349
+		// quite handy debug trace
350
+		//		if ( is_array($in))
351
+		//			print_r(array_slice(debug_backtrace(), 3));
352
+		print("</pre>\n");
353
+	}
354
+
355
+	/**
356
+	 * @access private
357
+	 */
358
+	protected function isRegexp($pattern)
359
+	{
360
+		return in_array(
361
+			$pattern[mb_strlen($pattern) - 1],
362
+			array(
363
+				'^',
364
+				'*',
365
+				'$'
366
+			)
367
+		);
368
+	}
369
+
370
+	/**
371
+	 * Determines if $char is really a char.
372
+	 *
373
+	 * @param string $char
374
+	 * @return bool
375
+	 * @todo   rewrite me to charcode range ! ;)
376
+	 * @access private
377
+	 */
378
+	protected function isChar($char)
379
+	{
380
+		return extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_eregi('\w', $char)
381
+			: preg_match('@\w@', $char);
382
+	}
383
+
384
+	/**
385
+	 * @access private
386
+	 */
387
+	protected function parseSelector($query)
388
+	{
389
+		// clean spaces
390
+		// TODO include this inside parsing ?
391
+		$query   = trim(preg_replace('@\s+@', ' ', preg_replace('@\s*(>|\\+|~)\s*@', '\\1', (string) $query)));
392
+		$queries = array(
393
+			array()
394
+		);
395
+		if (!$query) {
396
+			return $queries;
397
+		}
398
+		$return       = & $queries[0];
399
+		$specialChars = array(
400
+			'>',
401
+			' '
402
+		);
403
+		//		$specialCharsMapping = array('/' => '>');
404
+		$specialCharsMapping = array();
405
+		$strlen              = mb_strlen($query);
406
+		$classChars          = array(
407
+			'.',
408
+			'-'
409
+		);
410
+		$pseudoChars         = array(
411
+			'-'
412
+		);
413
+		$tagChars            = array(
414
+			'*',
415
+			'|',
416
+			'-'
417
+		);
418
+		// split multibyte string
419
+		// http://code.google.com/p/phpquery/issues/detail?id=76
420
+		$_query = array();
421
+		for ($i = 0; $i < $strlen; $i++) {
422
+			$_query[] = mb_substr($query, $i, 1);
423
+		}
424
+		$query = $_query;
425
+		// it works, but i dont like it...
426
+		$i = 0;
427
+		while ($i < $strlen) {
428
+			$c   = $query[$i];
429
+			$tmp = '';
430
+			// TAG
431
+			if ($this->isChar($c) || in_array($c, $tagChars)) {
432
+				while (isset($query[$i])
433
+					&& ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) {
434
+					$tmp .= $query[$i];
435
+					$i++;
436
+				}
437
+				$return[] = $tmp;
438
+				// IDs
439
+			} else if ($c == '#') {
440
+				$i++;
441
+				while (isset($query[$i])
442
+					&& ($this->isChar($query[$i]) || $query[$i] == '-')) {
443
+					$tmp .= $query[$i];
444
+					$i++;
445
+				}
446
+				$return[] = '#' . $tmp;
447
+				// SPECIAL CHARS
448
+			} else if (in_array($c, $specialChars)) {
449
+				$return[] = $c;
450
+				$i++;
451
+				// MAPPED SPECIAL MULTICHARS
452
+				//			} else if ( $c.$query[$i+1] == '//') {
453
+				//				$return[] = ' ';
454
+				//				$i = $i+2;
455
+				// MAPPED SPECIAL CHARS
456
+			} else if (isset($specialCharsMapping[$c])) {
457
+				$return[] = $specialCharsMapping[$c];
458
+				$i++;
459
+				// COMMA
460
+			} else if ($c == ',') {
461
+				$queries[] = array();
462
+				$return    = & $queries[count($queries) - 1];
463
+				$i++;
464
+				while (isset($query[$i]) && $query[$i] == ' ') {
465
+					$i++;
466
+				}
467
+				// CLASSES
468
+			} else if ($c == '.') {
469
+				while (isset($query[$i])
470
+					&& ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) {
471
+					$tmp .= $query[$i];
472
+					$i++;
473
+				}
474
+				$return[] = $tmp;
475
+				// ~ General Sibling Selector
476
+			} else if ($c == '~') {
477
+				$spaceAllowed = true;
478
+				$tmp .= $query[$i++];
479
+				while (isset($query[$i])
480
+					&& ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
481
+						|| $query[$i] == '*' || ($query[$i] == ' ' && $spaceAllowed))) {
482
+					if ($query[$i] != ' ') {
483
+						$spaceAllowed = false;
484
+					}
485
+					$tmp .= $query[$i];
486
+					$i++;
487
+				}
488
+				$return[] = $tmp;
489
+				// + Adjacent sibling selectors
490
+			} else {
491
+				if ($c == '+') {
492
+					$spaceAllowed = true;
493
+					$tmp .= $query[$i++];
494
+					while (isset($query[$i])
495
+						&& ($this->isChar($query[$i]) || in_array($query[$i], $classChars)
496
+							|| $query[$i] == '*' || ($spaceAllowed && $query[$i] == ' '))) {
497
+						if ($query[$i] != ' ') {
498
+							$spaceAllowed = false;
499
+						}
500
+						$tmp .= $query[$i];
501
+						$i++;
502
+					}
503
+					$return[] = $tmp;
504
+					// ATTRS
505
+				} else {
506
+					if ($c == '[') {
507
+						$stack = 1;
508
+						$tmp .= $c;
509
+						while (isset($query[++$i])) {
510
+							$tmp .= $query[$i];
511
+							if ($query[$i] == '[') {
512
+								$stack++;
513
+							} else {
514
+								if ($query[$i] == ']') {
515
+									$stack--;
516
+									if (!$stack) {
517
+										break;
518
+									}
519
+								}
520
+							}
521
+						}
522
+						$return[] = $tmp;
523
+						$i++;
524
+						// PSEUDO CLASSES
525
+					} else {
526
+						if ($c == ':') {
527
+							$stack = 1;
528
+							$tmp .= $query[$i++];
529
+							while (isset($query[$i])
530
+								&& ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) {
531
+								$tmp .= $query[$i];
532
+								$i++;
533
+							}
534
+							// with arguments ?
535
+							if (isset($query[$i]) && $query[$i] == '(') {
536
+								$tmp .= $query[$i];
537
+								$stack = 1;
538
+								while (isset($query[++$i])) {
539
+									$tmp .= $query[$i];
540
+									if ($query[$i] == '(') {
541
+										$stack++;
542
+									} else {
543
+										if ($query[$i] == ')') {
544
+											$stack--;
545
+											if (!$stack) {
546
+												break;
547
+											}
548
+										}
549
+									}
550
+								}
551
+								$return[] = $tmp;
552
+								$i++;
553
+							} else {
554
+								$return[] = $tmp;
555
+							}
556
+						} else {
557
+							$i++;
558
+						}
559
+					}
560
+				}
561
+			}
562
+		}
563
+		foreach ($queries as $k => $q) {
564
+			if (isset($q[0])) {
565
+				if (isset($q[0][0]) && $q[0][0] == ':')
566
+					array_unshift($queries[$k], '*');
567
+				if ($q[0] != '>')
568
+					array_unshift($queries[$k], ' ');
569
+			}
570
+		}
571
+		return $queries;
572
+	}
573
+
574
+	/**
575
+	 * Return matched DOM nodes.
576
+	 *
577
+	 * @param int $index
578
+	 * @return array|\DOMElement Single \DOMElement or array of \DOMElement.
579
+	 */
580
+	public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
581
+	{
582
+		$return = isset($index) ? (isset($this->elements[$index]) ? $this->elements[$index]
583
+			: null) : $this->elements;
584
+		// pass thou callbacks
585
+		$args = func_get_args();
586
+		$args = array_slice($args, 1);
587
+		foreach ($args as $callback) {
588
+			if (is_array($return))
589
+				foreach ($return as $k => $v)
590
+					$return[$k] = PhpQuery::callbackRun(
591
+						$callback,
592
+						array(
593
+							$v
594
+						)
595
+					);
596
+			else
597
+				$return = PhpQuery::callbackRun(
598
+					$callback,
599
+					array(
600
+						$return
601
+					)
602
+				);
603
+		}
604
+		return $return;
605
+	}
606
+
607
+	/**
608
+	 * Return matched DOM nodes.
609
+	 * jQuery difference.
610
+	 *
611
+	 * @param int  $index
612
+	 * @param null $callback1
613
+	 * @param null $callback2
614
+	 * @param null $callback3
615
+	 * @return array|string Returns string if $index != null
616
+	 * @todo implement callbacks
617
+	 * @todo return only arrays ?
618
+	 * @todo maybe other name...
619
+	 */
620
+	public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
621
+	{
622
+		if ($index)
623
+			$return = $this->eq($index)->text();
624
+		else {
625
+			$return = array();
626
+			for ($i = 0; $i < $this->size(); $i++) {
627
+				$return[] = $this->eq($i)->text();
628
+			}
629
+		}
630
+		// pass thou callbacks
631
+		$args = func_get_args();
632
+		$args = array_slice($args, 1);
633
+		foreach ($args as $callback) {
634
+			$return = PhpQuery::callbackRun(
635
+				$callback,
636
+				array(
637
+					$return
638
+				)
639
+			);
640
+		}
641
+		return $return;
642
+	}
643
+
644
+	/**
645
+	 * Return matched DOM nodes.
646
+	 * jQuery difference.
647
+	 *
648
+	 * @param int  $index
649
+	 * @param null $callback1
650
+	 * @param null $callback2
651
+	 * @param null $callback3
652
+	 * @return array|string Returns string if $index != null
653
+	 * @todo implement callbacks
654
+	 * @todo return only arrays ?
655
+	 * @todo maybe other name...
656
+	 */
657
+	public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
658
+	{
659
+		if ($index)
660
+			$return = $this->eq($index)->text();
661
+		else {
662
+			$return = array();
663
+			for ($i = 0; $i < $this->size(); $i++) {
664
+				$return[] = $this->eq($i)->text();
665
+			}
666
+			// pass thou callbacks
667
+			$args = func_get_args();
668
+			$args = array_slice($args, 1);
669
+		}
670
+		foreach ($args as $callback) {
671
+			if (is_array($return))
672
+				foreach ($return as $k => $v)
673
+					$return[$k] = PhpQuery::callbackRun(
674
+						$callback,
675
+						array(
676
+							$v
677
+						)
678
+					);
679
+			else
680
+				$return = PhpQuery::callbackRun(
681
+					$callback,
682
+					array(
683
+						$return
684
+					)
685
+				);
686
+		}
687
+		return $return;
688
+	}
689
+
690
+	/**
691
+	 * Returns new instance of actual class.
692
+	 *
693
+	 * @param array $newStack Optional. Will replace old stack with new and move old one to history.c
694
+	 * @return \PhpQuery\PhpQueryObject
695
+	 */
696
+	public function newInstance($newStack = null)
697
+	{
698
+		$class = get_class($this);
699
+		// support inheritance by passing old object to overloaded constructor
700
+		$new           = $class != 'PhpQuery' ? new $class($this, $this->getDocumentID())
701
+			: new PhpQueryObject($this->getDocumentID());
702
+		$new->previous = $this;
703
+		if (is_null($newStack)) {
704
+			$new->elements = $this->elements;
705
+			if ($this->elementsBackup)
706
+				$this->elements = $this->elementsBackup;
707
+		} else if (is_string($newStack)) {
708
+			$new->elements = PhpQuery::pq($newStack, $this->getDocumentID())->stack();
709
+		} else {
710
+			$new->elements = $newStack;
711
+		}
712
+		return $new;
713
+	}
714
+
715
+	/**
716
+	 * Enter description here...
717
+	 *
718
+	 * In the future, when PHP will support XLS 2.0, then we would do that this way:
719
+	 * contains(tokenize(@class, '\s'), "something")
720
+	 * @param string $class
721
+	 * @param string $node
722
+	 * @return boolean
723
+	 * @access private
724
+	 */
725
+	protected function matchClasses($class, $node)
726
+	{
727
+		// multi-class
728
+		if (mb_strpos($class, '.', 1)) {
729
+			$classes          = explode('.', substr($class, 1));
730
+			$classesCount     = count($classes);
731
+			$nodeClasses      = explode(' ', $node->getAttribute('class'));
732
+			$nodeClassesCount = count($nodeClasses);
733
+			if ($classesCount > $nodeClassesCount)
734
+				return false;
735
+			$diff = count(array_diff($classes, $nodeClasses));
736
+			if (!$diff)
737
+				return true;
738
+			// single-class
739
+		} else {
740
+			return in_array(
741
+			// strip leading dot from class name
742
+				substr($class, 1),
743
+				// get classes for element as array
744
+				explode(' ', $node->getAttribute('class'))
745
+			);
746
+		}
747
+	}
748
+
749
+	/**
750
+	 * @access private
751
+	 */
752
+	protected function runQuery($XQuery, $selector = null, $compare = null)
753
+	{
754
+		if ($compare && !method_exists($this, $compare))
755
+			return false;
756
+		$stack = array();
757
+		if (!$this->elements)
758
+			$this->debug('Stack empty, skipping...');
759
+		//		var_dump($this->elements[0]->nodeType);
760
+		// element, document
761
+		foreach ($this->stack(
762
+					 array(
763
+						 1,
764
+						 9,
765
+						 13
766
+					 )
767
+				 ) as $k => $stackNode) {
768
+			$detachAfter = false;
769
+			// to work on detached nodes we need temporary place them somewhere
770
+			// thats because context xpath queries sucks ;]
771
+			$testNode = $stackNode;
772
+			while ($testNode) {
773
+				if (!$testNode->parentNode && !$this->isRoot($testNode)) {
774
+					$this->root->appendChild($testNode);
775
+					$detachAfter = $testNode;
776
+					break;
777
+				}
778
+				$testNode = isset($testNode->parentNode) ? $testNode->parentNode : null;
779
+			}
780
+			// XXX tmp ?
781
+			$xpath = $this->documentWrapper->isXHTML ? $this->getNodeXpath($stackNode, 'html')
782
+				: $this->getNodeXpath($stackNode);
783
+			// FIXME pseudoclasses-only query, support XML
784
+			$query = $XQuery == '//' && $xpath == '/html[1]' ? '//*'
785
+				: $xpath . $XQuery;
786
+			$this->debug("XPATH: {$query}");
787
+			// run query, get elements
788
+			$nodes = $this->xpath->query($query);
789
+			$this->debug("QUERY FETCHED");
790
+			if (!$nodes->length)
791
+				$this->debug('Nothing found');
792
+			$debug = array();
793
+			foreach ($nodes as $node) {
794
+				$matched = false;
795
+				if ($compare) {
796
+					PhpQuery::$debug ? $this->debug(
797
+						"Found: " . $this->whois($node)
798
+						. ", comparing with {$compare}()"
799
+					) : null;
800
+					$PhpQueryDebug   = PhpQuery::$debug;
801
+					PhpQuery::$debug = false;
802
+					// TODO ??? use PhpQuery::callbackRun()
803
+					if (call_user_func_array(
804
+						array(
805
+							$this,
806
+							$compare
807
+						),
808
+						array(
809
+							$selector,
810
+							$node
811
+						)
812
+					)
813
+					)
814
+						$matched = true;
815
+					PhpQuery::$debug = $PhpQueryDebug;
816
+				} else {
817
+					$matched = true;
818
+				}
819
+				if ($matched) {
820
+					if (PhpQuery::$debug)
821
+						$debug[] = $this->whois($node);
822
+					$stack[] = $node;
823
+				}
824
+			}
825
+			if (PhpQuery::$debug) {
826
+				$this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
827
+			}
828
+			if ($detachAfter)
829
+				$this->root->removeChild($detachAfter);
830
+		}
831
+		$this->elements = $stack;
832
+	}
833
+
834
+	/**
835
+	 * Enter description here...
836
+	 *
837
+	 * @param      $selectors
838
+	 * @param null $context
839
+	 * @param bool $noHistory
840
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
841
+	 */
842
+	public function find($selectors, $context = null, $noHistory = false)
843
+	{
844
+		if (!$noHistory)
845
+			// backup last stack /for end()/
846
+			$this->elementsBackup = $this->elements;
847
+		// allow to define context
848
+		// TODO combine code below with PhpQuery::pq() context guessing code
849
+		//   as generic function
850
+		if (isset($context)) {
851
+			if (!is_array($context) && $context instanceof \DOMElement) {
852
+				$this->elements = array(
853
+					$context
854
+				);
855
+			} elseif (is_array($context)) {
856
+				$this->elements = array();
857
+				foreach ($context as $c)
858
+					if ($c instanceof \DOMElement)
859
+						$this->elements[] = $c;
860
+			} elseif ($context instanceof PhpQueryObject) {
861
+				$this->elements = $context->elements;
862
+			}
863
+		}
864
+
865
+		$queries = $this->parseSelector($selectors);
866
+
867
+		$this->debug(
868
+			array(
869
+				'FIND',
870
+				$selectors,
871
+				$queries
872
+			)
873
+		);
874
+		$XQuery = '';
875
+		// remember stack state because of multi-queries
876
+		$oldStack = $this->elements;
877
+		// here we will be keeping found elements
878
+		$stack = array();
879
+		foreach ($queries as $selector) {
880
+			$this->elements  = $oldStack;
881
+			$delimiterBefore = false;
882
+			foreach ($selector as $s) {
883
+				// TAG
884
+				$isTag = extension_loaded('mbstring') && PhpQuery::$mbstringSupport ? mb_ereg_match('^[\w|\||-]+$', $s)
885
+					|| $s == '*' : preg_match('@^[\w|\||-]+$@', $s) || $s == '*';
886
+				if ($isTag) {
887
+					if ($this->isXML()) {
888
+						// namespace support
889
+						if (mb_strpos($s, '|') !== false) {
890
+							$ns = $tag = null;
891
+							list($ns, $tag) = explode('|', $s);
892
+							$XQuery .= "$ns:$tag";
893
+						} else if ($s == '*') {
894
+							$XQuery .= "*";
895
+						} else {
896
+							$XQuery .= "*[local-name()='$s']";
897
+						}
898
+					} else {
899
+						$XQuery .= $s;
900
+					}
901
+					// ID
902
+				} else if ($s[0] == '#') {
903
+					if ($delimiterBefore)
904
+						$XQuery .= '*';
905
+					$XQuery .= "[@id='" . substr($s, 1) . "']";
906
+					// ATTRIBUTES
907
+				} else if ($s[0] == '[') {
908
+					if ($delimiterBefore)
909
+						$XQuery .= '*';
910
+					// strip side brackets
911
+					$attr    = trim($s, '][');
912
+					$execute = false;
913
+					// attr with specifed value
914
+					if (mb_strpos($s, '=')) {
915
+						$value = null;
916
+						list($attr, $value) = explode('=', $attr);
917
+						$value = trim($value, "'\"");
918
+						if ($this->isRegexp($attr)) {
919
+							// cut regexp character
920
+							$attr    = substr($attr, 0, -1);
921
+							$execute = true;
922
+							$XQuery .= "[@{$attr}]";
923
+						} else {
924
+							$XQuery .= "[@{$attr}='{$value}']";
925
+						}
926
+						// attr without specified value
927
+					} else {
928
+						$XQuery .= "[@{$attr}]";
929
+					}
930
+					if ($execute) {
931
+						$this->runQuery($XQuery, $s, 'is');
932
+						$XQuery = '';
933
+						if (!$this->length())
934
+							break;
935
+					}
936
+					// CLASSES
937
+				} else if ($s[0] == '.') {
938
+					// TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
939
+					// thx wizDom ;)
940
+					if ($delimiterBefore)
941
+						$XQuery .= '*';
942
+					$XQuery .= '[@class]';
943
+					$this->runQuery($XQuery, $s, 'matchClasses');
944
+					$XQuery = '';
945
+					if (!$this->length())
946
+						break;
947
+					// ~ General Sibling Selector
948
+				} else if ($s[0] == '~') {
949
+					$this->runQuery($XQuery);
950
+					$XQuery         = '';
951
+					$this->elements = $this->siblings(substr($s, 1))->elements;
952
+					if (!$this->length())
953
+						break;
954
+					// + Adjacent sibling selectors
955
+				} else if ($s[0] == '+') {
956
+					// TODO /following-sibling::
957
+					$this->runQuery($XQuery);
958
+					$XQuery         = '';
959
+					$subSelector    = substr($s, 1);
960
+					$subElements    = $this->elements;
961
+					$this->elements = array();
962
+					foreach ($subElements as $node) {
963
+						// search first \DOMElement sibling
964
+						$test = $node->nextSibling;
965
+						while ($test && !($test instanceof \DOMElement))
966
+							$test = $test->nextSibling;
967
+						if ($test && $this->is($subSelector, $test))
968
+							$this->elements[] = $test;
969
+					}
970
+					if (!$this->length())
971
+						break;
972
+					// PSEUDO CLASSES
973
+				} else if ($s[0] == ':') {
974
+					// TODO optimization for :first :last
975
+					if ($XQuery) {
976
+						$this->runQuery($XQuery);
977
+						$XQuery = '';
978
+					}
979
+					if (!$this->length())
980
+						break;
981
+					$this->pseudoClasses($s);
982
+					if (!$this->length())
983
+						break;
984
+					// DIRECT DESCENDANDS
985
+				} else if ($s == '>') {
986
+					$XQuery .= '/';
987
+					$delimiterBefore = 2;
988
+					// ALL DESCENDANDS
989
+				} else if ($s == ' ') {
990
+					$XQuery .= '//';
991
+					$delimiterBefore = 2;
992
+					// ERRORS
993
+				} else {
994
+					PhpQuery::debug("Unrecognized token '$s'");
995
+				}
996
+				$delimiterBefore = $delimiterBefore === 2;
997
+			}
998
+			// run query if any
999
+			if ($XQuery && $XQuery != '//') {
1000
+				$this->runQuery($XQuery);
1001
+				$XQuery = '';
1002
+			}
1003
+			foreach ($this->elements as $node)
1004
+				if (!$this->elementsContainsNode($node, $stack))
1005
+					$stack[] = $node;
1006
+		}
1007
+		$this->elements = $stack;
1008
+		return $this->newInstance();
1009
+	}
1010
+
1011
+	/**
1012
+	 * @todo   create API for classes with pseudoselectors
1013
+	 * @access private
1014
+	 */
1015
+	protected function pseudoClasses($class)
1016
+	{
1017
+		// TODO clean args parsing ?
1018
+		$class    = ltrim($class, ':');
1019
+		$haveArgs = mb_strpos($class, '(');
1020
+		if ($haveArgs !== false) {
1021
+			$args  = substr($class, $haveArgs + 1, -1);
1022
+			$class = substr($class, 0, $haveArgs);
1023
+		}
1024
+		switch ($class) {
1025
+			case 'even':
1026
+			case 'odd':
1027
+				$stack = array();
1028
+				foreach ($this->elements as $i => $node) {
1029
+					if ($class == 'even' && ($i % 2) == 0)
1030
+						$stack[] = $node;
1031
+					else if ($class == 'odd' && $i % 2)
1032
+						$stack[] = $node;
1033
+				}
1034
+				$this->elements = $stack;
1035
+				break;
1036
+			case 'eq':
1037
+				$k              = intval($args);
1038
+				$this->elements = isset($this->elements[$k]) ? array(
1039
+					$this->elements[$k]
1040
+				) : array();
1041
+				break;
1042
+			case 'gt':
1043
+				$this->elements = array_slice($this->elements, $args + 1);
1044
+				break;
1045
+			case 'lt':
1046
+				$this->elements = array_slice($this->elements, 0, $args + 1);
1047
+				break;
1048
+			case 'first':
1049
+				if (isset($this->elements[0]))
1050
+					$this->elements = array(
1051
+						$this->elements[0]
1052
+					);
1053
+				break;
1054
+			case 'last':
1055
+				if ($this->elements)
1056
+					$this->elements = array(
1057
+						$this->elements[count($this->elements) - 1]
1058
+					);
1059
+				break;
1060
+			/*case 'parent':
1061 1061
           $stack = array();
1062 1062
           foreach($this->elements as $node) {
1063 1063
               if ( $node->childNodes->length )
@@ -1065,201 +1065,201 @@  discard block
 block discarded – undo
1065 1065
           }
1066 1066
           $this->elements = $stack;
1067 1067
           break;*/
1068
-            case 'contains':
1069
-                $text  = trim($args, "\"'");
1070
-                $stack = array();
1071
-                foreach ($this->elements as $node) {
1072
-                    if (mb_stripos($node->textContent, $text) === false)
1073
-                        continue;
1074
-                    $stack[] = $node;
1075
-                }
1076
-                $this->elements = $stack;
1077
-                break;
1078
-            case 'not':
1079
-                $selector       = self::unQuote($args);
1080
-                $this->elements = $this->not($selector)->stack();
1081
-                break;
1082
-            case 'slice':
1083
-                // TODO jQuery difference ?
1084
-                $args  = explode(',', str_replace(', ', ',', trim($args, "\"'")));
1085
-                $start = $args[0];
1086
-                $end   = isset($args[1]) ? $args[1] : null;
1087
-                if ($end > 0)
1088
-                    $end = $end - $start;
1089
-                $this->elements = array_slice($this->elements, $start, $end);
1090
-                break;
1091
-            case 'has':
1092
-                $selector = trim($args, "\"'");
1093
-                $stack    = array();
1094
-                foreach ($this->stack(1) as $el) {
1095
-                    if ($this->find($selector, $el, true)->length)
1096
-                        $stack[] = $el;
1097
-                }
1098
-                $this->elements = $stack;
1099
-                break;
1100
-            case 'submit':
1101
-            case 'reset':
1102
-                $this->elements = PhpQuery::merge(
1103
-                    $this->map(
1104
-                        array(
1105
-                            $this,
1106
-                            'is'
1107
-                        ),
1108
-                        "input[type=$class]",
1109
-                        new \CallbackParam()
1110
-                    ),
1111
-                    $this->map(
1112
-                        array(
1113
-                            $this,
1114
-                            'is'
1115
-                        ),
1116
-                        "button[type=$class]",
1117
-                        new \CallbackParam()
1118
-                    )
1119
-                );
1120
-                break;
1121
-            //				$stack = array();
1122
-            //				foreach($this->elements as $node)
1123
-            //					if ($node->is('input[type=submit]') || $node->is('button[type=submit]'))
1124
-            //						$stack[] = $el;
1125
-            //				$this->elements = $stack;
1126
-            case 'input':
1127
-                $this->elements = $this->map(
1128
-                    array(
1129
-                        $this,
1130
-                        'is'
1131
-                    ),
1132
-                    'input',
1133
-                    new \CallbackParam()
1134
-                )->elements;
1135
-                break;
1136
-            case 'password':
1137
-            case 'checkbox':
1138
-            case 'radio':
1139
-            case 'hidden':
1140
-            case 'image':
1141
-            case 'file':
1142
-                $this->elements = $this->map(
1143
-                    array(
1144
-                        $this,
1145
-                        'is'
1146
-                    ),
1147
-                    "input[type=$class]",
1148
-                    new \CallbackParam()
1149
-                )->elements;
1150
-                break;
1151
-            case 'parent':
1152
-                $this->elements = $this->map(
1153
-                    create_function(
1154
-                        '$node',
1155
-                        '
1068
+			case 'contains':
1069
+				$text  = trim($args, "\"'");
1070
+				$stack = array();
1071
+				foreach ($this->elements as $node) {
1072
+					if (mb_stripos($node->textContent, $text) === false)
1073
+						continue;
1074
+					$stack[] = $node;
1075
+				}
1076
+				$this->elements = $stack;
1077
+				break;
1078
+			case 'not':
1079
+				$selector       = self::unQuote($args);
1080
+				$this->elements = $this->not($selector)->stack();
1081
+				break;
1082
+			case 'slice':
1083
+				// TODO jQuery difference ?
1084
+				$args  = explode(',', str_replace(', ', ',', trim($args, "\"'")));
1085
+				$start = $args[0];
1086
+				$end   = isset($args[1]) ? $args[1] : null;
1087
+				if ($end > 0)
1088
+					$end = $end - $start;
1089
+				$this->elements = array_slice($this->elements, $start, $end);
1090
+				break;
1091
+			case 'has':
1092
+				$selector = trim($args, "\"'");
1093
+				$stack    = array();
1094
+				foreach ($this->stack(1) as $el) {
1095
+					if ($this->find($selector, $el, true)->length)
1096
+						$stack[] = $el;
1097
+				}
1098
+				$this->elements = $stack;
1099
+				break;
1100
+			case 'submit':
1101
+			case 'reset':
1102
+				$this->elements = PhpQuery::merge(
1103
+					$this->map(
1104
+						array(
1105
+							$this,
1106
+							'is'
1107
+						),
1108
+						"input[type=$class]",
1109
+						new \CallbackParam()
1110
+					),
1111
+					$this->map(
1112
+						array(
1113
+							$this,
1114
+							'is'
1115
+						),
1116
+						"button[type=$class]",
1117
+						new \CallbackParam()
1118
+					)
1119
+				);
1120
+				break;
1121
+			//				$stack = array();
1122
+			//				foreach($this->elements as $node)
1123
+			//					if ($node->is('input[type=submit]') || $node->is('button[type=submit]'))
1124
+			//						$stack[] = $el;
1125
+			//				$this->elements = $stack;
1126
+			case 'input':
1127
+				$this->elements = $this->map(
1128
+					array(
1129
+						$this,
1130
+						'is'
1131
+					),
1132
+					'input',
1133
+					new \CallbackParam()
1134
+				)->elements;
1135
+				break;
1136
+			case 'password':
1137
+			case 'checkbox':
1138
+			case 'radio':
1139
+			case 'hidden':
1140
+			case 'image':
1141
+			case 'file':
1142
+				$this->elements = $this->map(
1143
+					array(
1144
+						$this,
1145
+						'is'
1146
+					),
1147
+					"input[type=$class]",
1148
+					new \CallbackParam()
1149
+				)->elements;
1150
+				break;
1151
+			case 'parent':
1152
+				$this->elements = $this->map(
1153
+					create_function(
1154
+						'$node',
1155
+						'
1156 1156
 						return $node instanceof \DOMElement && $node->childNodes->length
1157 1157
 							? $node : null;'
1158
-                    )
1159
-                )->elements;
1160
-                break;
1161
-            case 'empty':
1162
-                $this->elements = $this->map(
1163
-                    create_function(
1164
-                        '$node',
1165
-                        '
1158
+					)
1159
+				)->elements;
1160
+				break;
1161
+			case 'empty':
1162
+				$this->elements = $this->map(
1163
+					create_function(
1164
+						'$node',
1165
+						'
1166 1166
 						return $node instanceof \DOMElement && $node->childNodes->length
1167 1167
 							? null : $node;'
1168
-                    )
1169
-                )->elements;
1170
-                break;
1171
-            case 'disabled':
1172
-            case 'selected':
1173
-            case 'checked':
1174
-                $this->elements = $this->map(
1175
-                    array(
1176
-                        $this,
1177
-                        'is'
1178
-                    ),
1179
-                    "[$class]",
1180
-                    new \CallbackParam()
1181
-                )->elements;
1182
-                break;
1183
-            case 'enabled':
1184
-                $this->elements = $this->map(
1185
-                    create_function(
1186
-                        '$node',
1187
-                        '
1168
+					)
1169
+				)->elements;
1170
+				break;
1171
+			case 'disabled':
1172
+			case 'selected':
1173
+			case 'checked':
1174
+				$this->elements = $this->map(
1175
+					array(
1176
+						$this,
1177
+						'is'
1178
+					),
1179
+					"[$class]",
1180
+					new \CallbackParam()
1181
+				)->elements;
1182
+				break;
1183
+			case 'enabled':
1184
+				$this->elements = $this->map(
1185
+					create_function(
1186
+						'$node',
1187
+						'
1188 1188
 						return pq($node)->not(":disabled") ? $node : null;'
1189
-                    )
1190
-                )->elements;
1191
-                break;
1192
-            case 'header':
1193
-                $this->elements = $this->map(
1194
-                    create_function(
1195
-                        '$node',
1196
-                        '$isHeader = isset($node->tagName) && in_array($node->tagName, array(
1189
+					)
1190
+				)->elements;
1191
+				break;
1192
+			case 'header':
1193
+				$this->elements = $this->map(
1194
+					create_function(
1195
+						'$node',
1196
+						'$isHeader = isset($node->tagName) && in_array($node->tagName, array(
1197 1197
 							"h1", "h2", "h3", "h4", "h5", "h6", "h7"
1198 1198
 						));
1199 1199
 						return $isHeader
1200 1200
 							? $node
1201 1201
 							: null;'
1202
-                    )
1203
-                )->elements;
1204
-                //				$this->elements = $this->map(
1205
-                //					create_function('$node', '$node = pq($node);
1206
-                //						return $node->is("h1")
1207
-                //							|| $node->is("h2")
1208
-                //							|| $node->is("h3")
1209
-                //							|| $node->is("h4")
1210
-                //							|| $node->is("h5")
1211
-                //							|| $node->is("h6")
1212
-                //							|| $node->is("h7")
1213
-                //							? $node
1214
-                //							: null;')
1215
-                //				)->elements;
1216
-                break;
1217
-            case 'only-child':
1218
-                $this->elements = $this->map(
1219
-                    create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;')
1220
-                )->elements;
1221
-                break;
1222
-            case 'first-child':
1223
-                $this->elements = $this->map(
1224
-                    create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;')
1225
-                )->elements;
1226
-                break;
1227
-            case 'last-child':
1228
-                $this->elements = $this->map(
1229
-                    create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;')
1230
-                )->elements;
1231
-                break;
1232
-            case 'nth-child':
1233
-                $param = trim($args, "\"'");
1234
-                if (!$param)
1235
-                    break;
1236
-                // nth-child(n+b) to nth-child(1n+b)
1237
-                if ($param{0} == 'n')
1238
-                    $param = '1' . $param;
1239
-                // :nth-child(index/even/odd/equation)
1240
-                if ($param == 'even' || $param == 'odd')
1241
-                    $mapped = $this->map(
1242
-                        create_function(
1243
-                            '$node, $param',
1244
-                            '$index = pq($node)->prevAll()->size()+1;
1202
+					)
1203
+				)->elements;
1204
+				//				$this->elements = $this->map(
1205
+				//					create_function('$node', '$node = pq($node);
1206
+				//						return $node->is("h1")
1207
+				//							|| $node->is("h2")
1208
+				//							|| $node->is("h3")
1209
+				//							|| $node->is("h4")
1210
+				//							|| $node->is("h5")
1211
+				//							|| $node->is("h6")
1212
+				//							|| $node->is("h7")
1213
+				//							? $node
1214
+				//							: null;')
1215
+				//				)->elements;
1216
+				break;
1217
+			case 'only-child':
1218
+				$this->elements = $this->map(
1219
+					create_function('$node', 'return pq($node)->siblings()->size() == 0 ? $node : null;')
1220
+				)->elements;
1221
+				break;
1222
+			case 'first-child':
1223
+				$this->elements = $this->map(
1224
+					create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;')
1225
+				)->elements;
1226
+				break;
1227
+			case 'last-child':
1228
+				$this->elements = $this->map(
1229
+					create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;')
1230
+				)->elements;
1231
+				break;
1232
+			case 'nth-child':
1233
+				$param = trim($args, "\"'");
1234
+				if (!$param)
1235
+					break;
1236
+				// nth-child(n+b) to nth-child(1n+b)
1237
+				if ($param{0} == 'n')
1238
+					$param = '1' . $param;
1239
+				// :nth-child(index/even/odd/equation)
1240
+				if ($param == 'even' || $param == 'odd')
1241
+					$mapped = $this->map(
1242
+						create_function(
1243
+							'$node, $param',
1244
+							'$index = pq($node)->prevAll()->size()+1;
1245 1245
 							if ($param == "even" && ($index%2) == 0)
1246 1246
 								return $node;
1247 1247
 							else if ($param == "odd" && $index%2 == 1)
1248 1248
 								return $node;
1249 1249
 							else
1250 1250
 								return null;'
1251
-                        ),
1252
-                        new \CallbackParam(),
1253
-                        $param
1254
-                    );
1255
-                else if (mb_strlen($param) > 1
1256
-                    && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1
1257
-                )
1258
-                    // an+b
1259
-                    $mapped = $this->map(
1260
-                        create_function(
1261
-                            '$node, $param',
1262
-                            '$prevs = pq($node)->prevAll()->size();
1251
+						),
1252
+						new \CallbackParam(),
1253
+						$param
1254
+					);
1255
+				else if (mb_strlen($param) > 1
1256
+					&& preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1
1257
+				)
1258
+					// an+b
1259
+					$mapped = $this->map(
1260
+						create_function(
1261
+							'$node, $param',
1262
+							'$prevs = pq($node)->prevAll()->size();
1263 1263
 							$index = 1+$prevs;
1264 1264
 
1265 1265
 							preg_match("/^(\d*)n([-+]?)(\d*)/", $param, $matches);
@@ -1295,2718 +1295,2718 @@  discard block
 block discarded – undo
1295 1295
 //									? $node
1296 1296
 //									: null;
1297 1297
 							'
1298
-                        ),
1299
-                        new \CallbackParam(),
1300
-                        $param
1301
-                    );
1302
-                else
1303
-                    // index
1304
-                    $mapped = $this->map(
1305
-                        create_function(
1306
-                            '$node, $index',
1307
-                            '$prevs = pq($node)->prevAll()->size();
1298
+						),
1299
+						new \CallbackParam(),
1300
+						$param
1301
+					);
1302
+				else
1303
+					// index
1304
+					$mapped = $this->map(
1305
+						create_function(
1306
+							'$node, $index',
1307
+							'$prevs = pq($node)->prevAll()->size();
1308 1308
 							if ($prevs && $prevs == $index-1)
1309 1309
 								return $node;
1310 1310
 							else if (! $prevs && $index == 1)
1311 1311
 								return $node;
1312 1312
 							else
1313 1313
 								return null;'
1314
-                        ),
1315
-                        new \CallbackParam(),
1316
-                        $param
1317
-                    );
1318
-                $this->elements = $mapped->elements;
1319
-                break;
1320
-            default:
1321
-                $this->debug("Unknown pseudoclass '{$class}', skipping...");
1322
-        }
1323
-    }
1324
-
1325
-    /**
1326
-     * @access private
1327
-     */
1328
-    protected function __pseudoClassParam($paramsString)
1329
-    {
1330
-        // TODO;
1331
-    }
1332
-
1333
-    /**
1334
-     * Enter description here...
1335
-     *
1336
-     * @param      $selector
1337
-     * @param null $nodes
1338
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1339
-     */
1340
-    public function is($selector, $nodes = null)
1341
-    {
1342
-        PhpQuery::debug(
1343
-            array(
1344
-                "Is:",
1345
-                $selector
1346
-            )
1347
-        );
1348
-        if (!$selector)
1349
-            return false;
1350
-        $oldStack    = $this->elements;
1351
-        $returnArray = false;
1352
-        if ($nodes && is_array($nodes)) {
1353
-            $this->elements = $nodes;
1354
-        } else if ($nodes)
1355
-            $this->elements = array(
1356
-                $nodes
1357
-            );
1358
-        $this->filter($selector, true);
1359
-        $stack          = $this->elements;
1360
-        $this->elements = $oldStack;
1361
-        if ($nodes)
1362
-            return $stack ? $stack : null;
1363
-        return (bool) count($stack);
1364
-    }
1365
-
1366
-    /**
1367
-     * Enter description here...
1368
-     * jQuery difference.
1369
-     *
1370
-     * Callback:
1371
-     * - $index int
1372
-     * - $node DOMNode
1373
-     *
1374
-     * @param      $callback
1375
-     * @param bool $_skipHistory
1376
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1377
-     * @link http://docs.jquery.com/Traversing/filter
1378
-     */
1379
-    public function filterCallback($callback, $_skipHistory = false)
1380
-    {
1381
-        if (!$_skipHistory) {
1382
-            $this->elementsBackup = $this->elements;
1383
-            $this->debug("Filtering by callback");
1384
-        }
1385
-        $newStack = array();
1386
-        foreach ($this->elements as $index => $node) {
1387
-            $result = PhpQuery::callbackRun(
1388
-                $callback,
1389
-                array(
1390
-                    $index,
1391
-                    $node
1392
-                )
1393
-            );
1394
-            if (is_null($result) || (!is_null($result) && $result))
1395
-                $newStack[] = $node;
1396
-        }
1397
-        $this->elements = $newStack;
1398
-        return $_skipHistory ? $this : $this->newInstance();
1399
-    }
1400
-
1401
-    /**
1402
-     * Enter description here...
1403
-     *
1404
-     * @param      $selectors
1405
-     * @param bool $_skipHistory
1406
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1407
-     * @link http://docs.jquery.com/Traversing/filter
1408
-     */
1409
-    public function filter($selectors, $_skipHistory = false)
1410
-    {
1411
-        if ($selectors instanceof \Callback OR $selectors instanceof \Closure)
1412
-            return $this->filterCallback($selectors, $_skipHistory);
1413
-        if (!$_skipHistory)
1414
-            $this->elementsBackup = $this->elements;
1415
-        $notSimpleSelector = array(
1416
-            ' ',
1417
-            '>',
1418
-            '~',
1419
-            '+',
1420
-            '/'
1421
-        );
1422
-        if (!is_array($selectors))
1423
-            $selectors = $this->parseSelector($selectors);
1424
-        if (!$_skipHistory)
1425
-            $this->debug(
1426
-                array(
1427
-                    "Filtering:",
1428
-                    $selectors
1429
-                )
1430
-            );
1431
-        $finalStack = array();
1432
-        foreach ($selectors as $selector) {
1433
-            $stack = array();
1434
-            if (!$selector)
1435
-                break;
1436
-            // avoid first space or /
1437
-            if (in_array($selector[0], $notSimpleSelector))
1438
-                $selector = array_slice($selector, 1);
1439
-            // PER NODE selector chunks
1440
-            foreach ($this->stack() as $node) {
1441
-                $break = false;
1442
-                foreach ($selector as $s) {
1443
-                    if (!($node instanceof \DOMElement)) {
1444
-                        // all besides \DOMElement
1445
-                        if ($s[0] == '[') {
1446
-                            $attr = trim($s, '[]');
1447
-                            if (mb_strpos($attr, '=')) {
1448
-                                list($attr, $val) = explode('=', $attr);
1449
-                                if ($attr == 'nodeType' && $node->nodeType != $val)
1450
-                                    $break = true;
1451
-                            }
1452
-                        } else
1453
-                            $break = true;
1454
-                    } else {
1455
-                        // \DOMElement only
1456
-                        // ID
1457
-                        if ($s[0] == '#') {
1458
-                            if ($node->getAttribute('id') != substr($s, 1))
1459
-                                $break = true;
1460
-                            // CLASSES
1461
-                        } else if ($s[0] == '.') {
1462
-                            if (!$this->matchClasses($s, $node))
1463
-                                $break = true;
1464
-                            // ATTRS
1465
-                        } else if ($s[0] == '[') {
1466
-                            // strip side brackets
1467
-                            $attr = trim($s, '[]');
1468
-                            if (mb_strpos($attr, '=')) {
1469
-                                list($attr, $val) = explode('=', $attr);
1470
-                                $val = self::unQuote($val);
1471
-                                if ($attr == 'nodeType') {
1472
-                                    if ($val != $node->nodeType)
1473
-                                        $break = true;
1474
-                                } else if ($this->isRegexp($attr)) {
1475
-                                    $val = extension_loaded('mbstring')
1476
-                                    && PhpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
1477
-                                        : preg_quote(trim($val, '"\''), '@');
1478
-                                    // switch last character
1479
-                                    switch (substr($attr, -1)) {
1480
-                                        // quotemeta used insted of preg_quote
1481
-                                        // http://code.google.com/p/phpquery/issues/detail?id=76
1482
-                                        case '^':
1483
-                                            $pattern = '^' . $val;
1484
-                                            break;
1485
-                                        case '*':
1486
-                                            $pattern = '.*' . $val . '.*';
1487
-                                            break;
1488
-                                        case '$':
1489
-                                            $pattern = '.*' . $val . '$';
1490
-                                            break;
1491
-                                    }
1492
-                                    // cut last character
1493
-                                    $attr    = substr($attr, 0, -1);
1494
-                                    $isMatch = extension_loaded('mbstring')
1495
-                                    && PhpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
1496
-                                        : preg_match("@{$pattern}@", $node->getAttribute($attr));
1497
-                                    if (!$isMatch)
1498
-                                        $break = true;
1499
-                                } else if ($node->getAttribute($attr) != $val)
1500
-                                    $break = true;
1501
-                            } else if (!$node->hasAttribute($attr))
1502
-                                $break = true;
1503
-                            // PSEUDO CLASSES
1504
-                        } else if ($s[0] == ':') {
1505
-                            // skip
1506
-                            // TAG
1507
-                        } else if (trim($s)) {
1508
-                            if ($s != '*') {
1509
-                                // TODO namespaces
1510
-                                if (isset($node->tagName)) {
1511
-                                    if ($node->tagName != $s)
1512
-                                        $break = true;
1513
-                                } else if ($s == 'html' && !$this->isRoot($node))
1514
-                                    $break = true;
1515
-                            }
1516
-                            // AVOID NON-SIMPLE SELECTORS
1517
-                        } else if (in_array($s, $notSimpleSelector)) {
1518
-                            $break = true;
1519
-                            $this->debug(
1520
-                                array(
1521
-                                    'Skipping non simple selector',
1522
-                                    $selector
1523
-                                )
1524
-                            );
1525
-                        }
1526
-                    }
1527
-                    if ($break)
1528
-                        break;
1529
-                }
1530
-                // if element passed all chunks of selector - add it to new stack
1531
-                if (!$break)
1532
-                    $stack[] = $node;
1533
-            }
1534
-            $tmpStack       = $this->elements;
1535
-            $this->elements = $stack;
1536
-            // PER ALL NODES selector chunks
1537
-            foreach ($selector as $s)
1538
-                // PSEUDO CLASSES
1539
-                if ($s[0] == ':')
1540
-                    $this->pseudoClasses($s);
1541
-            foreach ($this->elements as $node)
1542
-                // XXX it should be merged without duplicates
1543
-                // but jQuery doesnt do that
1544
-                $finalStack[] = $node;
1545
-            $this->elements = $tmpStack;
1546
-        }
1547
-        $this->elements = $finalStack;
1548
-        if ($_skipHistory) {
1549
-            return $this;
1550
-        } else {
1551
-            $this->debug("Stack length after filter(): " . count($finalStack));
1552
-            return $this->newInstance();
1553
-        }
1554
-    }
1555
-
1556
-    /**
1557
-     *
1558
-     * @param $value
1559
-     * @return string
1560
-     * @TODO implement in all methods using passed parameters
1561
-     */
1562
-    protected static function unQuote($value)
1563
-    {
1564
-        return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1)
1565
-            : $value;
1566
-    }
1567
-
1568
-    /**
1569
-     * Enter description here...
1570
-     *
1571
-     * @link http://docs.jquery.com/Ajax/load
1572
-     * @param      $url
1573
-     * @param null $data
1574
-     * @param null $callback
1575
-     * @return PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1576
-     * @todo Support $selector
1577
-     */
1578
-    public function load($url, $data = null, $callback = null)
1579
-    {
1580
-        if ($data && !is_array($data)) {
1581
-            $callback = $data;
1582
-            $data     = null;
1583
-        }
1584
-        if (mb_strpos($url, ' ') !== false) {
1585
-            $matches = null;
1586
-            if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport)
1587
-                mb_ereg('^([^ ]+) (.*)$', $url, $matches);
1588
-            else
1589
-                preg_match('@^([^ ]+) (.*)$@', $url, $matches);
1590
-            $url      = $matches[1];
1591
-            $selector = $matches[2];
1592
-            // FIXME this sucks, pass as callback param
1593
-            $this->_loadSelector = $selector;
1594
-        }
1595
-        $ajax = array(
1596
-            'url'      => $url,
1597
-            'type'     => $data ? 'POST' : 'GET',
1598
-            'data'     => $data,
1599
-            'complete' => $callback,
1600
-            'success'  => array(
1601
-                $this,
1602
-                '__loadSuccess'
1603
-            )
1604
-        );
1605
-        PhpQuery::ajax($ajax);
1606
-        return $this;
1607
-    }
1608
-
1609
-    /**
1610
-     * @access private
1611
-     * @param $html
1612
-     */
1613
-    public function __loadSuccess($html)
1614
-    {
1615
-        if ($this->_loadSelector) {
1616
-            $html = PhpQuery::newDocument($html)->find($this->_loadSelector);
1617
-            unset($this->_loadSelector);
1618
-        }
1619
-        foreach ($this->stack(1) as $node) {
1620
-            PhpQuery::pq($node, $this->getDocumentID())->markup($html);
1621
-        }
1622
-    }
1623
-
1624
-    /**
1625
-     * Allows users to enter strings of CSS selectors. Useful
1626
-     * when the CSS is loaded via style or @imports that PhpQuery can't load
1627
-     * because it doesn't know the URL context of the request.
1628
-     */
1629
-    public function addCSS($string)
1630
-    {
1631
-        if (!isset($this->cssString[$this->getDocumentID()])) {
1632
-            $this->cssString[$this->getDocumentID()] = '';
1633
-        }
1634
-        $this->cssString[$this->getDocumentID()] .= $string;
1635
-        $this->parseCSS();
1636
-    }
1637
-
1638
-    /**
1639
-     * Either sets the CSS property of an object or retrieves the
1640
-     * CSS property of a proejct.
1641
-     *
1642
-     * @param      $property_name
1643
-     * @param bool $value
1644
-     * @return string of css property value
1645
-     * @todo
1646
-     */
1647
-    public function css($property_name, $value = false)
1648
-    {
1649
-        if (!isset($this->cssIsParsed[$this->getDocumentID()])
1650
-        || $this->cssIsParsed[$this->getDocumentID()] === false
1651
-        ) {
1652
-            $this->parseCSS();
1653
-        }
1654
-        $data = PhpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID());
1655
-        if (!$value) {
1656
-            if (isset($data[$property_name])) {
1657
-                return $data[$property_name]['value'];
1658
-            }
1659
-            return null;
1660
-        }
1661
-        $specificity          = (isset($data[$property_name])) ? $data[$property_name]['specificity']
1662
-            + 1 : 1000;
1663
-        $data[$property_name] = array(
1664
-            'specificity' => $specificity,
1665
-            'value'       => $value
1666
-        );
1667
-        PhpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID());
1668
-        $this->bubbleCSS(PhpQuery::pq($this->get(0), $this->getDocumentID()));
1669
-
1670
-        if ($specificity >= 1000) {
1671
-            $styles = array();
1672
-            foreach ($this->data('phpquery_css') as $k => $v) {
1673
-                if ($v['specificity'] >= 1000) {
1674
-                    $styles[$k] = trim($k) . ':' . trim($v['value']);
1675
-                }
1676
-            }
1677
-            ksort($styles);
1678
-            if (empty($styles)) {
1679
-                $this->removeAttr('style');
1680
-            } elseif (PhpQuery::$enableCssShorthand) {
1681
-                $parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}');
1682
-                $doc    = $parser->parse();
1683
-                $doc->createShorthands();
1684
-                $style = trim($doc->__toString(), "\n\r\t {}");
1685
-            } else {
1686
-                $style = join(';', $styles);
1687
-            }
1688
-            $this->attr('style', $style);
1689
-        }
1690
-    }
1691
-
1692
-    public function parseCSS()
1693
-    {
1694
-        if (!isset($this->cssString[$this->getDocumentID()])) {
1695
-            $this->cssString[$this->getDocumentID()] = file_get_contents(
1696
-                dirname(__FILE__)
1697
-                . '/Resources/default.css'
1698
-            );
1699
-        }
1700
-        foreach (PhpQuery::pq('style', $this->getDocumentID()) as $style) {
1701
-            $this->cssString[$this->getDocumentID()] .= PhpQuery::pq($style)->text();
1702
-        }
1703
-
1704
-        $CssParser   = new CssParser($this->cssString[$this->getDocumentID()]);
1705
-        $CssDocument = $CssParser->parse();
1706
-        foreach ($CssDocument->getAllRuleSets() as $ruleset) {
1707
-            foreach ($ruleset->getSelector() as $selector) {
1708
-                $specificity = $selector->getSpecificity();
1709
-                foreach (PhpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) {
1710
-                    $existing = pq($el)->data('phpquery_css');
1711
-                    if (PhpQuery::$enableCssShorthand) {
1712
-                        $ruleset->expandShorthands();
1713
-                    }
1714
-                    foreach ($ruleset->getRules() as $value) {
1715
-                        $rule = $value->getRule();
1716
-                        if (!isset($existing[$rule])
1717
-                            || $existing[$rule]['specificity'] <= $specificity
1718
-                        ) {
1719
-                            $value           = $value->getValue();
1720
-                            $value           = (is_object($value)) ? $value->__toString() : $value;
1721
-                            $existing[$rule] = array(
1722
-                                'specificity' => $specificity,
1723
-                                'value'       => $value
1724
-                            );
1725
-                        }
1726
-                    }
1727
-                    PhpQuery::pq($el)->data('phpquery_css', $existing);
1728
-                    $this->bubbleCSS(PhpQuery::pq($el));
1729
-                }
1730
-            }
1731
-        }
1732
-        foreach (PhpQuery::pq('*', $this->getDocumentID()) as $el) {
1733
-            $existing = pq($el)->data('phpquery_css');
1734
-            $style    = pq($el)->attr('style');
1735
-            $style    = strlen($style) ? explode(';', $style) : array();
1736
-            foreach ($this->attribute_css_mapping as $map => $css_equivalent) {
1737
-                if ($el->hasAttribute($map)) {
1738
-                    $style[] = $css_equivalent . ':' . pq($el)->attr($map);
1739
-                }
1740
-            }
1741
-            if (count($style)) {
1742
-                $CssParser   = new CssParser('#ruleset {' . implode(';', $style) . '}');
1743
-                $CssDocument = $CssParser->parse();
1744
-                $ruleset     = $CssDocument->getAllRulesets();
1745
-                $ruleset     = reset($ruleset);
1746
-                if (PhpQuery::$enableCssShorthand) {
1747
-                    $ruleset->expandShorthands();
1748
-                }
1749
-                foreach ($ruleset->getRules() as $value) {
1750
-                    $rule = $value->getRule();
1751
-                    if (!isset($existing[$rule])
1752
-                        || 1000 >= $existing[$rule]['specificity']
1753
-                    ) {
1754
-                        $value           = $value->getValue();
1755
-                        $value           = (is_object($value)) ? $value->__toString() : $value;
1756
-                        $existing[$rule] = array(
1757
-                            'specificity' => 1000,
1758
-                            'value'       => $value
1759
-                        );
1760
-                    }
1761
-                }
1762
-                PhpQuery::pq($el)->data('phpquery_css', $existing);
1763
-                $this->bubbleCSS(PhpQuery::pq($el));
1764
-            }
1765
-        }
1766
-    }
1767
-
1768
-    protected function bubbleCSS($element)
1769
-    {
1770
-        $style = $element->data('phpquery_css');
1771
-        foreach ($element->children() as $element_child) {
1772
-            $existing = PhpQuery::pq($element_child)->data('phpquery_css');
1773
-            foreach ($style as $rule => $value) {
1774
-                if (!isset($existing[$rule])
1775
-                    || $value['specificity'] > $existing[$rule]['specificity']
1776
-                ) {
1777
-                    $existing[$rule] = $value;
1778
-                }
1779
-            }
1780
-            PhpQuery::pq($element_child)->data('phpquery_css', $existing);
1781
-            if (PhpQuery::pq($element_child)->children()->length) {
1782
-                $this->bubbleCSS(PhpQuery::pq($element_child));
1783
-            }
1784
-        }
1785
-    }
1786
-
1787
-    /**
1788
-     * @todo
1789
-     *
1790
-     */
1791
-    public function show()
1792
-    {
1793
-        $display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state')
1794
-            : 'block';
1795
-        $this->css('display', $display);
1796
-        return $this;
1797
-    }
1798
-
1799
-    /**
1800
-     * @todo
1801
-     *
1802
-     */
1803
-    public function hide()
1804
-    {
1805
-        $this->data('phpquery_display_state', $this->css('display'));
1806
-        $this->css('display', 'none');
1807
-        return $this;
1808
-    }
1809
-
1810
-    /**
1811
-     * Trigger a type of event on every matched element.
1812
-     *
1813
-     * @param                 $type
1814
-     * @param array|\PhpQuery $data
1815
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1816
-     * @TODO support more than event in $type (space-separated)
1817
-     */
1818
-    public function trigger($type, $data = array())
1819
-    {
1820
-        foreach ($this->elements as $node)
1821
-            PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
1822
-        return $this;
1823
-    }
1824
-
1825
-    /**
1826
-     * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
1827
-     *
1828
-     * @param  $type
1829
-     * @param  $data
1830
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1831
-     * @TODO
1832
-     */
1833
-    public function triggerHandler($type, $data = array())
1834
-    {
1835
-        // TODO;
1836
-    }
1837
-
1838
-    /**
1839
-     * Binds a handler to one or more events (like click) for each matched element.
1840
-     * Can also bind custom events.
1841
-     *
1842
-     * @param       $type
1843
-     * @param mixed $data Optional
1844
-     * @param       $callback
1845
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1846
-     * @TODO support '!' (exclusive) events
1847
-     * @TODO support more than event in $type (space-separated)
1848
-     */
1849
-    public function bind($type, $data, $callback = null)
1850
-    {
1851
-        // TODO check if $data is callable, not using is_callable
1852
-        if (!isset($callback)) {
1853
-            $callback = $data;
1854
-            $data     = null;
1855
-        }
1856
-        foreach ($this->elements as $node)
1857
-            PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
1858
-        return $this;
1859
-    }
1860
-
1861
-    /**
1862
-     * Enter description here...
1863
-     *
1864
-     * @param string $type
1865
-     * @param        $callback
1866
-     * @return unknown
1867
-     * @TODO namespace events
1868
-     * @TODO support more than event in $type (space-separated)
1869
-     */
1870
-    public function unbind($type = null, $callback = null)
1871
-    {
1872
-        foreach ($this->elements as $node)
1873
-            PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
1874
-        return $this;
1875
-    }
1876
-
1877
-    /**
1878
-     * Enter description here...
1879
-     *
1880
-     * @param null $callback
1881
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1882
-     */
1883
-    public function change($callback = null)
1884
-    {
1885
-        if ($callback)
1886
-            return $this->bind('change', $callback);
1887
-        return $this->trigger('change');
1888
-    }
1889
-
1890
-    /**
1891
-     * Enter description here...
1892
-     *
1893
-     * @param null $callback
1894
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1895
-     */
1896
-    public function submit($callback = null)
1897
-    {
1898
-        if ($callback)
1899
-            return $this->bind('submit', $callback);
1900
-        return $this->trigger('submit');
1901
-    }
1902
-
1903
-    /**
1904
-     * Enter description here...
1905
-     *
1906
-     * @param null $callback
1907
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1908
-     */
1909
-    public function click($callback = null)
1910
-    {
1911
-        if ($callback)
1912
-            return $this->bind('click', $callback);
1913
-        return $this->trigger('click');
1914
-    }
1915
-
1916
-    /**
1917
-     * Enter description here...
1918
-     *
1919
-     * @param String|PhpQuery
1920
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1921
-     */
1922
-    public function wrapAllOld($wrapper)
1923
-    {
1924
-        $wrapper = pq($wrapper)->_clone();
1925
-        if (!$wrapper->length() || !$this->length())
1926
-            return $this;
1927
-        $wrapper->insertBefore($this->elements[0]);
1928
-        $deepest = $wrapper->elements[0];
1929
-        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1930
-            $deepest = $deepest->firstChild;
1931
-        pq($deepest)->append($this);
1932
-        return $this;
1933
-    }
1934
-
1935
-    /**
1936
-     * Enter description here...
1937
-     *
1938
-     * TODO testme...
1939
-     * @param String|PhpQuery
1940
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1941
-     */
1942
-    public function wrapAll($wrapper)
1943
-    {
1944
-        if (!$this->length())
1945
-            return $this;
1946
-        return PhpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
1947
-            array(
1948
-                $this,
1949
-                '___wrapAllCallback'
1950
-            )
1951
-        )->append($this);
1952
-    }
1953
-
1954
-    /**
1955
-     *
1956
-     * @param $node
1957
-     * @return unknown_type
1958
-     * @access private
1959
-     */
1960
-    public function ___wrapAllCallback($node)
1961
-    {
1962
-        $deepest = $node;
1963
-        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1964
-            $deepest = $deepest->firstChild;
1965
-        return $deepest;
1966
-    }
1967
-
1968
-    /**
1969
-     * Enter description here...
1970
-     * NON JQUERY METHOD
1971
-     *
1972
-     * @param $codeBefore
1973
-     * @param $codeAfter
1974
-     * @internal param $ String|PhpQuery
1975
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1976
-     */
1977
-    public function wrapAllPHP($codeBefore, $codeAfter)
1978
-    {
1979
-        return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end();
1980
-    }
1981
-
1982
-    /**
1983
-     * Enter description here...
1984
-     *
1985
-     * @param String|PhpQuery
1986
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1987
-     */
1988
-    public function wrap($wrapper)
1989
-    {
1990
-        foreach ($this->stack() as $node)
1991
-            PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
1992
-        return $this;
1993
-    }
1994
-
1995
-    /**
1996
-     * Enter description here...
1997
-     *
1998
-     * @param $codeBefore
1999
-     * @param $codeAfter
2000
-     * @internal param $ String|PhpQuery
2001
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2002
-     */
2003
-    public function wrapPHP($codeBefore, $codeAfter)
2004
-    {
2005
-        foreach ($this->stack() as $node)
2006
-            PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
2007
-        return $this;
2008
-    }
2009
-
2010
-    /**
2011
-     * Enter description here...
2012
-     *
2013
-     * @param String|PhpQuery
2014
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2015
-     */
2016
-    public function wrapInner($wrapper)
2017
-    {
2018
-        foreach ($this->stack() as $node)
2019
-            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
2020
-        return $this;
2021
-    }
2022
-
2023
-    /**
2024
-     * Enter description here...
2025
-     *
2026
-     * @param $codeBefore
2027
-     * @param $codeAfter
2028
-     * @internal param $ String|PhpQuery
2029
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2030
-     */
2031
-    public function wrapInnerPHP($codeBefore, $codeAfter)
2032
-    {
2033
-        foreach ($this->stack(1) as $node)
2034
-            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
2035
-        return $this;
2036
-    }
2037
-
2038
-    /**
2039
-     * Enter description here...
2040
-     *
2041
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2042
-     * @testme Support for text nodes
2043
-     */
2044
-    public function contents()
2045
-    {
2046
-        $stack = array();
2047
-        foreach ($this->stack(1) as $el) {
2048
-            // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56
2049
-            //			if (! isset($el->childNodes))
2050
-            //				continue;
2051
-            foreach ($el->childNodes as $node) {
2052
-                $stack[] = $node;
2053
-            }
2054
-        }
2055
-        return $this->newInstance($stack);
2056
-    }
2057
-
2058
-    /**
2059
-     * Enter description here...
2060
-     *
2061
-     * jQuery difference.
2062
-     *
2063
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2064
-     */
2065
-    public function contentsUnwrap()
2066
-    {
2067
-        foreach ($this->stack(1) as $node) {
2068
-            if (!$node->parentNode)
2069
-                continue;
2070
-            $childNodes = array();
2071
-            // any modification in DOM tree breaks childNodes iteration, so cache them first
2072
-            foreach ($node->childNodes as $chNode)
2073
-                $childNodes[] = $chNode;
2074
-            foreach ($childNodes as $chNode)
2075
-                //				$node->parentNode->appendChild($chNode);
2076
-                $node->parentNode->insertBefore($chNode, $node);
2077
-            $node->parentNode->removeChild($node);
2078
-        }
2079
-        return $this;
2080
-    }
2081
-
2082
-    /**
2083
-     * Enter description here...
2084
-     *
2085
-     * jQuery difference.
2086
-     */
2087
-    public function switchWith($markup)
2088
-    {
2089
-        $markup  = pq($markup, $this->getDocumentID());
2090
-        $content = null;
2091
-        foreach ($this->stack(1) as $node) {
2092
-            pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content));
2093
-        }
2094
-        return $this;
2095
-    }
2096
-
2097
-    /**
2098
-     * Enter description here...
2099
-     *
2100
-     * @param $num
2101
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2102
-     */
2103
-    public function eq($num)
2104
-    {
2105
-        $oldStack             = $this->elements;
2106
-        $this->elementsBackup = $this->elements;
2107
-        $this->elements       = array();
2108
-        if (isset($oldStack[$num]))
2109
-            $this->elements[] = $oldStack[$num];
2110
-        return $this->newInstance();
2111
-    }
2112
-
2113
-    /**
2114
-     * Enter description here...
2115
-     *
2116
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2117
-     */
2118
-    public function size()
2119
-    {
2120
-        return count($this->elements);
2121
-    }
2122
-
2123
-    /**
2124
-     * Enter description here...
2125
-     *
2126
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2127
-     * @deprecated Use length as attribute
2128
-     */
2129
-    public function length()
2130
-    {
2131
-        return $this->size();
2132
-    }
2133
-
2134
-    public function count()
2135
-    {
2136
-        return $this->size();
2137
-    }
2138
-
2139
-    /**
2140
-     * Enter description here...
2141
-     *
2142
-     * @param int $level
2143
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2144
-     * @todo $level
2145
-     */
2146
-    public function end($level = 1)
2147
-    {
2148
-        //		$this->elements = array_pop( $this->history );
2149
-        //		return $this;
2150
-        //		$this->previous->DOM = $this->DOM;
2151
-        //		$this->previous->XPath = $this->XPath;
2152
-        return $this->previous ? $this->previous : $this;
2153
-    }
2154
-
2155
-    /**
2156
-     * Enter description here...
2157
-     * Normal use ->clone() .
2158
-     *
2159
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2160
-     * @access private
2161
-     */
2162
-    public function _clone()
2163
-    {
2164
-        $newStack = array();
2165
-        //pr(array('copy... ', $this->whois()));
2166
-        //$this->dumpHistory('copy');
2167
-        $this->elementsBackup = $this->elements;
2168
-        foreach ($this->elements as $node) {
2169
-            $newStack[] = $node->cloneNode(true);
2170
-        }
2171
-        $this->elements = $newStack;
2172
-        return $this->newInstance();
2173
-    }
2174
-
2175
-    /**
2176
-     * Enter description here...
2177
-     *
2178
-     * @param $code
2179
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2180
-     */
2181
-    public function replaceWithPHP($code)
2182
-    {
2183
-        return $this->replaceWith(PhpQuery::php($code));
2184
-    }
2185
-
2186
-    /**
2187
-     * Enter description here...
2188
-     *
2189
-     * @param String|PhpQuery $content
2190
-     * @link http://docs.jquery.com/Manipulation/replaceWith#content
2191
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2192
-     */
2193
-    public function replaceWith($content)
2194
-    {
2195
-        return $this->after($content)->remove();
2196
-    }
2197
-
2198
-    /**
2199
-     * Enter description here...
2200
-     *
2201
-     * @param String $selector
2202
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2203
-     * @todo this works ?
2204
-     */
2205
-    public function replaceAll($selector)
2206
-    {
2207
-        foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node)
2208
-            PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
2209
-        return $this;
2210
-    }
2211
-
2212
-    /**
2213
-     * Enter description here...
2214
-     *
2215
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2216
-     */
2217
-    public function remove($selector = null)
2218
-    {
2219
-        $loop = $selector ? $this->filter($selector)->elements : $this->elements;
2220
-        foreach ($loop as $node) {
2221
-            if (!$node->parentNode)
2222
-                continue;
2223
-            if (isset($node->tagName))
2224
-                $this->debug("Removing '{$node->tagName}'");
2225
-            $node->parentNode->removeChild($node);
2226
-            // Mutation event
2227
-            $event = new Dom\DOMEvent(array(
2228
-                                      'target' => $node,
2229
-                                      'type'   => 'DOMNodeRemoved'
2230
-                                  ));
2231
-            PhpQueryEvents::trigger(
2232
-                $this->getDocumentID(),
2233
-                $event->type,
2234
-                array(
2235
-                    $event
2236
-                ),
2237
-                $node
2238
-            );
2239
-        }
2240
-        return $this;
2241
-    }
2242
-
2243
-    protected function markupEvents($newMarkup, $oldMarkup, $node)
2244
-    {
2245
-        if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) {
2246
-            $event = new Dom\DOMEvent(array(
2247
-                                      'target' => $node,
2248
-                                      'type'   => 'change'
2249
-                                  ));
2250
-            PhpQueryEvents::trigger(
2251
-                $this->getDocumentID(),
2252
-                $event->type,
2253
-                array(
2254
-                    $event
2255
-                ),
2256
-                $node
2257
-            );
2258
-        }
2259
-    }
2260
-
2261
-    /**
2262
-     * jQuey difference
2263
-     *
2264
-     * @param      $markup
2265
-     * @param null $callback1
2266
-     * @param null $callback2
2267
-     * @param null $callback3
2268
-     * @return unknown_type
2269
-     * @TODO trigger change event for textarea
2270
-     */
2271
-    public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null)
2272
-    {
2273
-        $args = func_get_args();
2274
-        if ($this->documentWrapper->isXML)
2275
-            return call_user_func_array(
2276
-                array(
2277
-                    $this,
2278
-                    'xml'
2279
-                ),
2280
-                $args
2281
-            );
2282
-        else
2283
-            return call_user_func_array(
2284
-                array(
2285
-                    $this,
2286
-                    'html'
2287
-                ),
2288
-                $args
2289
-            );
2290
-    }
2291
-
2292
-    /**
2293
-     * jQuey difference
2294
-     *
2295
-     * @param null $callback1
2296
-     * @param null $callback2
2297
-     * @param null $callback3
2298
-     * @internal param $markup
2299
-     * @return string
2300
-     */
2301
-    public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
2302
-    {
2303
-        $args = func_get_args();
2304
-        if ($this->documentWrapper->isXML)
2305
-            return call_user_func_array(
2306
-                array(
2307
-                    $this,
2308
-                    'xmlOuter'
2309
-                ),
2310
-                $args
2311
-            );
2312
-        else
2313
-            return call_user_func_array(
2314
-                array(
2315
-                    $this,
2316
-                    'htmlOuter'
2317
-                ),
2318
-                $args
2319
-            );
2320
-    }
2321
-
2322
-    /**
2323
-     * Enter description here...
2324
-     *
2325
-     * @param unknown_type $html
2326
-     * @param null         $callback1
2327
-     * @param null         $callback2
2328
-     * @param null         $callback3
2329
-     * @return string|PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2330
-     * @TODO force html result
2331
-     */
2332
-    public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null)
2333
-    {
2334
-        if (isset($html)) {
2335
-            // INSERT
2336
-            $nodes = $this->documentWrapper->import($html);
2337
-            $this->empty();
2338
-            foreach ($this->stack(1) as $alreadyAdded => $node) {
2339
-                // for now, limit events for textarea
2340
-                if (($this->isXHTML() || $this->isHTML())
2341
-                    && $node->tagName == 'textarea'
2342
-                )
2343
-                    $oldHtml = pq($node, $this->getDocumentID())->markup();
2344
-                foreach ($nodes as $newNode) {
2345
-                    $node->appendChild(
2346
-                        $alreadyAdded ? $newNode->cloneNode(true)
2347
-                            : $newNode
2348
-                    );
2349
-                }
2350
-                // for now, limit events for textarea
2351
-                if (($this->isXHTML() || $this->isHTML())
2352
-                    && $node->tagName == 'textarea'
2353
-                )
2354
-                    $this->markupEvents($html, $oldHtml, $node);
2355
-            }
2356
-            return $this;
2357
-        } else {
2358
-            // FETCH
2359
-            $return = $this->documentWrapper->markup($this->elements, true);
2360
-            $args   = func_get_args();
2361
-            foreach (array_slice($args, 1) as $callback) {
2362
-                $return = PhpQuery::callbackRun(
2363
-                    $callback,
2364
-                    array(
2365
-                        $return
2366
-                    )
2367
-                );
2368
-            }
2369
-            return $return;
2370
-        }
2371
-    }
2372
-
2373
-    /**
2374
-     * @TODO force xml result
2375
-     */
2376
-    public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null)
2377
-    {
2378
-        $args = func_get_args();
2379
-        return call_user_func_array(
2380
-            array(
2381
-                $this,
2382
-                'html'
2383
-            ),
2384
-            $args
2385
-        );
2386
-    }
2387
-
2388
-    /**
2389
-     * Enter description here...
2390
-     * @TODO force html result
2391
-     *
2392
-     * @param null $callback1
2393
-     * @param null $callback2
2394
-     * @param null $callback3
2395
-     * @return String
2396
-     */
2397
-    public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
2398
-    {
2399
-        $markup = $this->documentWrapper->markup($this->elements);
2400
-        // pass thou callbacks
2401
-        $args = func_get_args();
2402
-        foreach ($args as $callback) {
2403
-            $markup = PhpQuery::callbackRun(
2404
-                $callback,
2405
-                array(
2406
-                    $markup
2407
-                )
2408
-            );
2409
-        }
2410
-        return $markup;
2411
-    }
2412
-
2413
-    /**
2414
-     * @TODO force xml result
2415
-     */
2416
-    public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
2417
-    {
2418
-        $args = func_get_args();
2419
-        return call_user_func_array(
2420
-            array(
2421
-                $this,
2422
-                'htmlOuter'
2423
-            ),
2424
-            $args
2425
-        );
2426
-    }
2427
-
2428
-    public function __toString()
2429
-    {
2430
-        return $this->markupOuter();
2431
-    }
2432
-
2433
-    /**
2434
-     * Just like html(), but returns markup with VALID (dangerous) PHP tags.
2435
-     *
2436
-     * @param null $code
2437
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2438
-     * @todo support returning markup with PHP tags when called without param
2439
-     */
2440
-    public function php($code = null)
2441
-    {
2442
-        return $this->markupPHP($code);
2443
-    }
2444
-
2445
-    /**
2446
-     * Enter description here...
2447
-     *
2448
-     * @param $code
2449
-     * @return unknown_type
2450
-     */
2451
-    public function markupPHP($code = null)
2452
-    {
2453
-        return isset($code) ? $this->markup(PhpQuery::php($code))
2454
-            : PhpQuery::markupToPHP($this->markup());
2455
-    }
2456
-
2457
-    /**
2458
-     * Enter description here...
2459
-     *
2460
-     * @internal param $code
2461
-     * @return string PHP code
2462
-     */
2463
-    public function markupOuterPHP()
2464
-    {
2465
-        return PhpQuery::markupToPHP($this->markupOuter());
2466
-    }
2467
-
2468
-    /**
2469
-     * Enter description here...
2470
-     *
2471
-     * @param null $selector
2472
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2473
-     */
2474
-    public function children($selector = null)
2475
-    {
2476
-        $stack = array();
2477
-        foreach ($this->stack(1) as $node) {
2478
-            //			foreach($node->getElementsByTagName('*') as $newNode) {
2479
-            foreach ($node->childNodes as $newNode) {
2480
-                if ($newNode->nodeType != 1)
2481
-                    continue;
2482
-                if ($selector && !$this->is($selector, $newNode))
2483
-                    continue;
2484
-                if ($this->elementsContainsNode($newNode, $stack))
2485
-                    continue;
2486
-                $stack[] = $newNode;
2487
-            }
2488
-        }
2489
-        $this->elementsBackup = $this->elements;
2490
-        $this->elements       = $stack;
2491
-        return $this->newInstance();
2492
-    }
2493
-
2494
-    /**
2495
-     * Enter description here...
2496
-     *
2497
-     * @param null $selector
2498
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2499
-     */
2500
-    public function ancestors($selector = null)
2501
-    {
2502
-        return $this->children($selector);
2503
-    }
2504
-
2505
-    /**
2506
-     * Enter description here...
2507
-     *
2508
-     * @param $content
2509
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2510
-     */
2511
-    public function append($content)
2512
-    {
2513
-        return $this->insert($content, __FUNCTION__);
2514
-    }
2515
-
2516
-    /**
2517
-     * Enter description here...
2518
-     *
2519
-     * @param $content
2520
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2521
-     */
2522
-    public function appendPHP($content)
2523
-    {
2524
-        return $this->insert("<php><!-- {$content} --></php>", 'append');
2525
-    }
2526
-
2527
-    /**
2528
-     * Enter description here...
2529
-     *
2530
-     * @param $seletor
2531
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2532
-     */
2533
-    public function appendTo($seletor)
2534
-    {
2535
-        return $this->insert($seletor, __FUNCTION__);
2536
-    }
2537
-
2538
-    /**
2539
-     * Enter description here...
2540
-     *
2541
-     * @param $content
2542
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2543
-     */
2544
-    public function prepend($content)
2545
-    {
2546
-        return $this->insert($content, __FUNCTION__);
2547
-    }
2548
-
2549
-    /**
2550
-     * Enter description here...
2551
-     *
2552
-     * @todo accept many arguments, which are joined, arrays maybe also
2553
-     * @param $content
2554
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2555
-     */
2556
-    public function prependPHP($content)
2557
-    {
2558
-        return $this->insert("<php><!-- {$content} --></php>", 'prepend');
2559
-    }
2560
-
2561
-    /**
2562
-     * Enter description here...
2563
-     *
2564
-     * @param $seletor
2565
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2566
-     */
2567
-    public function prependTo($seletor)
2568
-    {
2569
-        return $this->insert($seletor, __FUNCTION__);
2570
-    }
2571
-
2572
-    /**
2573
-     * Enter description here...
2574
-     *
2575
-     * @param $content
2576
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2577
-     */
2578
-    public function before($content)
2579
-    {
2580
-        return $this->insert($content, __FUNCTION__);
2581
-    }
2582
-
2583
-    /**
2584
-     * Enter description here...
2585
-     *
2586
-     * @param $content
2587
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2588
-     */
2589
-    public function beforePHP($content)
2590
-    {
2591
-        return $this->insert("<php><!-- {$content} --></php>", 'before');
2592
-    }
2593
-
2594
-    /**
2595
-     * Enter description here...
2596
-     *
2597
-     * @param String|PhpQuery
2598
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2599
-     */
2600
-    public function insertBefore($seletor)
2601
-    {
2602
-        return $this->insert($seletor, __FUNCTION__);
2603
-    }
2604
-
2605
-    /**
2606
-     * Enter description here...
2607
-     *
2608
-     * @param $content
2609
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2610
-     */
2611
-    public function after($content)
2612
-    {
2613
-        return $this->insert($content, __FUNCTION__);
2614
-    }
2615
-
2616
-    /**
2617
-     * Enter description here...
2618
-     *
2619
-     * @param $content
2620
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2621
-     */
2622
-    public function afterPHP($content)
2623
-    {
2624
-        return $this->insert("<php><!-- {$content} --></php>", 'after');
2625
-    }
2626
-
2627
-    /**
2628
-     * Enter description here...
2629
-     *
2630
-     * @param $seletor
2631
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2632
-     */
2633
-    public function insertAfter($seletor)
2634
-    {
2635
-        return $this->insert($seletor, __FUNCTION__);
2636
-    }
2637
-
2638
-    /**
2639
-     * Internal insert method. Don't use it.
2640
-     *
2641
-     * @param unknown_type $target
2642
-     * @param unknown_type $type
2643
-     * @throws \Exception
2644
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2645
-     * @access private
2646
-     */
2647
-    public function insert($target, $type)
2648
-    {
2649
-        $this->debug("Inserting data with '{$type}'");
2650
-        $to = false;
2651
-        switch ($type) {
2652
-            case 'appendTo':
2653
-            case 'prependTo':
2654
-            case 'insertBefore':
2655
-            case 'insertAfter':
2656
-                $to = true;
2657
-        }
2658
-        switch (gettype($target)) {
2659
-            case 'string':
2660
-                $insertFrom = $insertTo = array();
2661
-                if ($to) {
2662
-                    // INSERT TO
2663
-                    $insertFrom = $this->elements;
2664
-                    if (PhpQuery::isMarkup($target)) {
2665
-                        // $target is new markup, import it
2666
-                        $insertTo = $this->documentWrapper->import($target);
2667
-                        // insert into selected element
2668
-                    } else {
2669
-                        // $tagret is a selector
2670
-                        $thisStack = $this->elements;
2671
-                        $this->toRoot();
2672
-                        $insertTo       = $this->find($target)->elements;
2673
-                        $this->elements = $thisStack;
2674
-                    }
2675
-                } else {
2676
-                    // INSERT FROM
2677
-                    $insertTo   = $this->elements;
2678
-                    $insertFrom = $this->documentWrapper->import($target);
2679
-                }
2680
-                break;
2681
-            case 'object':
2682
-                $insertFrom = $insertTo = array();
2683
-                // PhpQuery
2684
-                if ($target instanceof self) {
2685
-                    if ($to) {
2686
-                        $insertTo = $target->elements;
2687
-                        if ($this->documentFragment && $this->stackIsRoot())
2688
-                            // get all body children
2689
-                            //							$loop = $this->find('body > *')->elements;
2690
-                            // TODO test it, test it hard...
2691
-                            //							$loop = $this->newInstance($this->root)->find('> *')->elements;
2692
-                            $loop = $this->root->childNodes;
2693
-                        else
2694
-                            $loop = $this->elements;
2695
-                        // import nodes if needed
2696
-                        $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2697
-                            : $target->documentWrapper->import($loop);
2698
-                    } else {
2699
-                        $insertTo = $this->elements;
2700
-                        if ($target->documentFragment && $target->stackIsRoot())
2701
-                            // get all body children
2702
-                            //							$loop = $target->find('body > *')->elements;
2703
-                            $loop = $target->root->childNodes;
2704
-                        else
2705
-                            $loop = $target->elements;
2706
-                        // import nodes if needed
2707
-                        $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2708
-                            : $this->documentWrapper->import($loop);
2709
-                    }
2710
-                    // DOMNODE
2711
-                } elseif ($target instanceof \DOMNODE) {
2712
-                    // import node if needed
2713
-                    //					if ( $target->ownerDocument != $this->DOM )
2714
-                    //						$target = $this->DOM->importNode($target, true);
2715
-                    if ($to) {
2716
-                        $insertTo = array(
2717
-                            $target
2718
-                        );
2719
-                        if ($this->documentFragment && $this->stackIsRoot())
2720
-                            // get all body children
2721
-                            $loop = $this->root->childNodes;
2722
-                        //							$loop = $this->find('body > *')->elements;
2723
-                        else
2724
-                            $loop = $this->elements;
2725
-                        foreach ($loop as $fromNode)
2726
-                            // import nodes if needed
2727
-                            $insertFrom[] = !$fromNode->ownerDocument->isSameNode(
2728
-                                $target->ownerDocument
2729
-                            ) ? $target->ownerDocument->importNode($fromNode, true)
2730
-                                : $fromNode;
2731
-                    } else {
2732
-                        // import node if needed
2733
-                        if (!$target->ownerDocument->isSameNode($this->document))
2734
-                            $target = $this->document->importNode($target, true);
2735
-                        $insertTo     = $this->elements;
2736
-                        $insertFrom[] = $target;
2737
-                    }
2738
-                }
2739
-                break;
2740
-        }
2741
-        PhpQuery::debug(
2742
-            "From " . count($insertFrom) . "; To " . count($insertTo)
2743
-            . " nodes"
2744
-        );
2745
-        foreach ($insertTo as $insertNumber => $toNode) {
2746
-            // we need static relative elements in some cases
2747
-            switch ($type) {
2748
-                case 'prependTo':
2749
-                case 'prepend':
2750
-                    $firstChild = $toNode->firstChild;
2751
-                    break;
2752
-                case 'insertAfter':
2753
-                case 'after':
2754
-                    $nextSibling = $toNode->nextSibling;
2755
-                    break;
2756
-            }
2757
-            foreach ($insertFrom as $fromNode) {
2758
-                // clone if inserted already before
2759
-                $insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode;
2760
-                switch ($type) {
2761
-                    case 'appendTo':
2762
-                    case 'append':
2763
-                        //						$toNode->insertBefore(
2764
-                        //							$fromNode,
2765
-                        //							$toNode->lastChild->nextSibling
2766
-                        //						);
2767
-                        $toNode->appendChild($insert);
2768
-                        $eventTarget = $insert;
2769
-                        break;
2770
-                    case 'prependTo':
2771
-                    case 'prepend':
2772
-                        $toNode->insertBefore($insert, $firstChild);
2773
-                        break;
2774
-                    case 'insertBefore':
2775
-                    case 'before':
2776
-                        if (!$toNode->parentNode)
2777
-                            throw new \Exception("No parentNode, can't do {$type}()");
2778
-                        else
2779
-                            $toNode->parentNode->insertBefore($insert, $toNode);
2780
-                        break;
2781
-                    case 'insertAfter':
2782
-                    case 'after':
2783
-                        if (!$toNode->parentNode)
2784
-                            throw new \Exception("No parentNode, can't do {$type}()");
2785
-                        else
2786
-                            $toNode->parentNode->insertBefore($insert, $nextSibling);
2787
-                        break;
2788
-                }
2789
-                // Mutation event
2790
-                $event = new Dom\DOMEvent(array(
2791
-                                              'target' => $insert,
2792
-                                              'type'   => 'DOMNodeInserted'
2793
-                                          ));
2794
-                PhpQueryEvents::trigger(
2795
-                    $this->getDocumentID(),
2796
-                    $event->type,
2797
-                    array(
2798
-                        $event
2799
-                    ),
2800
-                    $insert
2801
-                );
2802
-            }
2803
-        }
2804
-        return $this;
2805
-    }
2806
-
2807
-    /**
2808
-     * Enter description here...
2809
-     *
2810
-     * @param $subject
2811
-     * @return Int
2812
-     */
2813
-    public function index($subject)
2814
-    {
2815
-        $index   = -1;
2816
-        $subject = $subject instanceof PhpQueryObject ? $subject->elements[0]
2817
-            : $subject;
2818
-        foreach ($this->newInstance() as $k => $node) {
2819
-            if ($node->isSameNode($subject))
2820
-                $index = $k;
2821
-        }
2822
-        return $index;
2823
-    }
2824
-
2825
-    /**
2826
-     * Enter description here...
2827
-     *
2828
-     * @param unknown_type $start
2829
-     * @param unknown_type $end
2830
-     *
2831
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2832
-     * @testme
2833
-     */
2834
-    public function slice($start, $end = null)
2835
-    {
2836
-        //		$last = count($this->elements)-1;
2837
-        //		$end = $end
2838
-        //			? min($end, $last)
2839
-        //			: $last;
2840
-        //		if ($start < 0)
2841
-        //			$start = $last+$start;
2842
-        //		if ($start > $last)
2843
-        //			return array();
2844
-        if ($end > 0)
2845
-            $end = $end - $start;
2846
-        return $this->newInstance(array_slice($this->elements, $start, $end));
2847
-    }
2848
-
2849
-    /**
2850
-     * Enter description here...
2851
-     *
2852
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2853
-     */
2854
-    public function reverse()
2855
-    {
2856
-        $this->elementsBackup = $this->elements;
2857
-        $this->elements       = array_reverse($this->elements);
2858
-        return $this->newInstance();
2859
-    }
2860
-
2861
-    /**
2862
-     * Return joined text content.
2863
-     * @param null $text
2864
-     * @param null $callback1
2865
-     * @param null $callback2
2866
-     * @param null $callback3
2867
-     * @return String
2868
-     */
2869
-    public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null)
2870
-    {
2871
-        if (isset($text))
2872
-            return $this->html(htmlspecialchars($text));
2873
-        $args   = func_get_args();
2874
-        $args   = array_slice($args, 1);
2875
-        $return = '';
2876
-        foreach ($this->elements as $node) {
2877
-            $text = $node->textContent;
2878
-            if (count($this->elements) > 1 && $text)
2879
-                $text .= "\n";
2880
-            foreach ($args as $callback) {
2881
-                $text = PhpQuery::callbackRun(
2882
-                    $callback,
2883
-                    array(
2884
-                        $text
2885
-                    )
2886
-                );
2887
-            }
2888
-            $return .= $text;
2889
-        }
2890
-        return $return;
2891
-    }
2892
-
2893
-    /**
2894
-     * @param null $attr
2895
-     * @return The text content of each matching element, like
2896
-     * text() but returns an array with one entry per matched element.
2897
-     * Read only.
2898
-     */
2899
-    public function texts($attr = null)
2900
-    {
2901
-        $results = array();
2902
-        foreach ($this->elements as $node) {
2903
-            $results[] = $node->textContent;
2904
-        }
2905
-        return $results;
2906
-    }
2907
-
2908
-    /**
2909
-     * Enter description here...
2910
-     *
2911
-     * @param      $class
2912
-     * @param null $file
2913
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2914
-     */
2915
-    public function plugin($class, $file = null)
2916
-    {
2917
-        PhpQuery::plugin($class, $file);
2918
-        return $this;
2919
-    }
2920
-
2921
-    /**
2922
-     * Deprecated, use $pq->plugin() instead.
2923
-     *
2924
-     * @deprecated
2925
-     * @param $class
2926
-     * @param $file
2927
-     * @return unknown_type
2928
-     */
2929
-    public static function extend($class, $file = null)
2930
-    {
2931
-        return self::plugin($class, $file);
2932
-    }
2933
-
2934
-    /**
2935
-     *
2936
-     * @access private
2937
-     * @param $method
2938
-     * @param $args
2939
-     * @throws \Exception
2940
-     * @return unknown_type
2941
-     */
2942
-    public function __call($method, $args)
2943
-    {
2944
-        $aliasMethods = array(
2945
-            'clone',
2946
-            'empty'
2947
-        );
2948
-        if (isset(PhpQuery::$extendMethods[$method])) {
2949
-            array_unshift($args, $this);
2950
-            return PhpQuery::callbackRun(PhpQuery::$extendMethods[$method], $args);
2951
-        } else if (isset(PhpQuery::$pluginsMethods[$method])) {
2952
-            array_unshift($args, $this);
2953
-            $class     = PhpQuery::$pluginsMethods[$method];
2954
-            $realClass = "\\PhpQuery\\Plugin\\$class";
2955
-            $return    = call_user_func_array(
2956
-                array(
2957
-                    $realClass,
2958
-                    $method
2959
-                ),
2960
-                $args
2961
-            );
2962
-            // XXX deprecate ?
2963
-            return is_null($return) ? $this : $return;
2964
-        } else if (in_array($method, $aliasMethods)) {
2965
-            return call_user_func_array(
2966
-                array(
2967
-                    $this,
2968
-                    '_' . $method
2969
-                ),
2970
-                $args
2971
-            );
2972
-        } else
2973
-            throw new \Exception("Method '{$method}' doesnt exist");
2974
-    }
2975
-
2976
-    /**
2977
-     * Safe rename of next().
2978
-     *
2979
-     * Use it ONLY when need to call next() on an iterated object (in same time).
2980
-     * Normaly there is no need to do such thing ;)
2981
-     *
2982
-     * @param null $selector
2983
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2984
-     * @access private
2985
-     */
2986
-    public function _next($selector = null)
2987
-    {
2988
-        return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true));
2989
-    }
2990
-
2991
-    /**
2992
-     * Use prev() and next().
2993
-     *
2994
-     * @deprecated
2995
-     * @param null $selector
2996
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2997
-     * @access private
2998
-     */
2999
-    public function _prev($selector = null)
3000
-    {
3001
-        return $this->prev($selector);
3002
-    }
3003
-
3004
-    /**
3005
-     * Enter description here...
3006
-     *
3007
-     * @param null $selector
3008
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3009
-     */
3010
-    public function prev($selector = null)
3011
-    {
3012
-        return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true));
3013
-    }
3014
-
3015
-    /**
3016
-     * @param null $selector
3017
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3018
-     * @todo
3019
-     */
3020
-    public function prevAll($selector = null)
3021
-    {
3022
-        return $this->newInstance($this->getElementSiblings('previousSibling', $selector));
3023
-    }
3024
-
3025
-    /**
3026
-     * @param null $selector
3027
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3028
-     * @todo FIXME: returns source elements insted of next siblings
3029
-     */
3030
-    public function nextAll($selector = null)
3031
-    {
3032
-        return $this->newInstance($this->getElementSiblings('nextSibling', $selector));
3033
-    }
3034
-
3035
-    /**
3036
-     * @access private
3037
-     */
3038
-    protected function getElementSiblings($direction, $selector = null, $limitToOne = false)
3039
-    {
3040
-        $stack = array();
3041
-        $count = 0;
3042
-        foreach ($this->stack() as $node) {
3043
-            $test = $node;
3044
-            while (isset($test->{$direction}) && $test->{$direction}) {
3045
-                $test = $test->{$direction};
3046
-                if (!$test instanceof \DOMElement)
3047
-                    continue;
3048
-                $stack[] = $test;
3049
-                if ($limitToOne)
3050
-                    break;
3051
-            }
3052
-        }
3053
-        if ($selector) {
3054
-            $stackOld       = $this->elements;
3055
-            $this->elements = $stack;
3056
-            $stack          = $this->filter($selector, true)->stack();
3057
-            $this->elements = $stackOld;
3058
-        }
3059
-        return $stack;
3060
-    }
3061
-
3062
-    /**
3063
-     * Enter description here...
3064
-     *
3065
-     * @param null $selector
3066
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3067
-     */
3068
-    public function siblings($selector = null)
3069
-    {
3070
-        $stack    = array();
3071
-        $siblings = array_merge(
3072
-            $this->getElementSiblings('previousSibling', $selector),
3073
-            $this->getElementSiblings('nextSibling', $selector)
3074
-        );
3075
-        foreach ($siblings as $node) {
3076
-            if (!$this->elementsContainsNode($node, $stack))
3077
-                $stack[] = $node;
3078
-        }
3079
-        return $this->newInstance($stack);
3080
-    }
3081
-
3082
-    /**
3083
-     * Enter description here...
3084
-     *
3085
-     * @param null $selector
3086
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3087
-     */
3088
-    public function not($selector = null)
3089
-    {
3090
-        if (is_string($selector))
3091
-            PhpQuery::debug(
3092
-                array(
3093
-                    'not',
3094
-                    $selector
3095
-                )
3096
-            );
3097
-        else
3098
-            PhpQuery::debug('not');
3099
-        $stack = array();
3100
-        if ($selector instanceof self || $selector instanceof \DOMNODE) {
3101
-            foreach ($this->stack() as $node) {
3102
-                if ($selector instanceof self) {
3103
-                    $matchFound = false;
3104
-                    foreach ($selector->stack() as $notNode) {
3105
-                        if ($notNode->isSameNode($node))
3106
-                            $matchFound = true;
3107
-                    }
3108
-                    if (!$matchFound)
3109
-                        $stack[] = $node;
3110
-                } else if ($selector instanceof \DOMNODE) {
3111
-                    if (!$selector->isSameNode($node))
3112
-                        $stack[] = $node;
3113
-                } else {
3114
-                    if (!$this->is($selector))
3115
-                        $stack[] = $node;
3116
-                }
3117
-            }
3118
-        } else {
3119
-            $orgStack = $this->stack();
3120
-            $matched  = $this->filter($selector, true)->stack();
3121
-            //			$matched = array();
3122
-            //			// simulate OR in filter() instead of AND 5y
3123
-            //			foreach($this->parseSelector($selector) as $s) {
3124
-            //				$matched = array_merge($matched,
3125
-            //					$this->filter(array($s))->stack()
3126
-            //				);
3127
-            //			}
3128
-            foreach ($orgStack as $node)
3129
-                if (!$this->elementsContainsNode($node, $matched))
3130
-                    $stack[] = $node;
3131
-        }
3132
-        return $this->newInstance($stack);
3133
-    }
3134
-
3135
-    /**
3136
-     * Enter description here...
3137
-     *
3138
-     * @param string|PhpQueryObject
3139
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3140
-     */
3141
-    public function add($selector = null)
3142
-    {
3143
-        if (!$selector)
3144
-            return $this;
3145
-        $stack                = array();
3146
-        $this->elementsBackup = $this->elements;
3147
-        $found                = PhpQuery::pq($selector, $this->getDocumentID());
3148
-        $this->merge($found->elements);
3149
-        return $this->newInstance();
3150
-    }
3151
-
3152
-    /**
3153
-     * @access private
3154
-     */
3155
-    protected function merge()
3156
-    {
3157
-        foreach (func_get_args() as $nodes)
3158
-            foreach ($nodes as $newNode)
3159
-                if (!$this->elementsContainsNode($newNode))
3160
-                    $this->elements[] = $newNode;
3161
-    }
3162
-
3163
-    /**
3164
-     * @access private
3165
-     * TODO refactor to stackContainsNode
3166
-     */
3167
-    protected function elementsContainsNode($nodeToCheck, $elementsStack = null)
3168
-    {
3169
-        $loop = !is_null($elementsStack) ? $elementsStack : $this->elements;
3170
-        foreach ($loop as $node) {
3171
-            if ($node->isSameNode($nodeToCheck))
3172
-                return true;
3173
-        }
3174
-        return false;
3175
-    }
3176
-
3177
-    /**
3178
-     * Enter description here...
3179
-     *
3180
-     * @param null $selector
3181
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3182
-     */
3183
-    public function parent($selector = null)
3184
-    {
3185
-        $stack = array();
3186
-        foreach ($this->elements as $node)
3187
-            if ($node->parentNode
3188
-                && !$this->elementsContainsNode($node->parentNode, $stack)
3189
-            )
3190
-                $stack[] = $node->parentNode;
3191
-        $this->elementsBackup = $this->elements;
3192
-        $this->elements       = $stack;
3193
-        if ($selector)
3194
-            $this->filter($selector, true);
3195
-        return $this->newInstance();
3196
-    }
3197
-
3198
-    /**
3199
-     * Enter description here...
3200
-     *
3201
-     * @param null $selector
3202
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3203
-     */
3204
-    public function parents($selector = null)
3205
-    {
3206
-        $stack = array();
3207
-        if (!$this->elements)
3208
-            $this->debug('parents() - stack empty');
3209
-        foreach ($this->elements as $node) {
3210
-            $test = $node;
3211
-            while ($test->parentNode) {
3212
-                $test = $test->parentNode;
3213
-                if ($this->isRoot($test))
3214
-                    break;
3215
-                if (!$this->elementsContainsNode($test, $stack)) {
3216
-                    $stack[] = $test;
3217
-                    continue;
3218
-                }
3219
-            }
3220
-        }
3221
-        $this->elementsBackup = $this->elements;
3222
-        $this->elements       = $stack;
3223
-        if ($selector)
3224
-            $this->filter($selector, true);
3225
-        return $this->newInstance();
3226
-    }
3227
-
3228
-    /**
3229
-     * Internal stack iterator.
3230
-     *
3231
-     * @access private
3232
-     * @param null $nodeTypes
3233
-     * @return array {Array.<DOMNode>}
3234
-     */
3235
-    public function stack($nodeTypes = null)
3236
-    {
3237
-        if (!isset($nodeTypes))
3238
-            return $this->elements;
3239
-        if (!is_array($nodeTypes))
3240
-            $nodeTypes = array(
3241
-                $nodeTypes
3242
-            );
3243
-        $return = array();
3244
-        foreach ($this->elements as $node) {
3245
-            if (in_array($node->nodeType, $nodeTypes))
3246
-                $return[] = $node;
3247
-        }
3248
-        return $return;
3249
-    }
3250
-
3251
-    // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes
3252
-    protected function attrEvents($attr, $oldAttr, $oldValue, $node)
3253
-    {
3254
-        // skip events for XML documents
3255
-        if (!$this->isXHTML() && !$this->isHTML())
3256
-            return;
3257
-        $event = null;
3258
-        // identify
3259
-        $isInputValue = $node->tagName == 'input'
3260
-            && (in_array(
3261
-                    $node->getAttribute('type'),
3262
-                    array(
3263
-                        'text',
3264
-                        'password',
3265
-                        'hidden'
3266
-                    )
3267
-                ) || !$node->getAttribute('type'));
3268
-        $isRadio      = $node->tagName == 'input'
3269
-            && $node->getAttribute('type') == 'radio';
3270
-        $isCheckbox   = $node->tagName == 'input'
3271
-            && $node->getAttribute('type') == 'checkbox';
3272
-        $isOption     = $node->tagName == 'option';
3273
-        if ($isInputValue && $attr == 'value'
3274
-            && $oldValue != $node->getAttribute($attr)
3275
-        ) {
3276
-            $event = new Dom\DOMEvent(array(
3277
-                                          'target' => $node,
3278
-                                          'type'   => 'change'
3279
-                                      ));
3280
-        } else if (($isRadio || $isCheckbox) && $attr == 'checked'
3281
-            && (
3282
-                // check
3283
-                (!$oldAttr && $node->hasAttribute($attr))
3284
-                // un-check
3285
-                || (!$node->hasAttribute($attr) && $oldAttr))
3286
-        ) {
3287
-            $event = new Dom\DOMEvent(array(
3288
-                                          'target' => $node,
3289
-                                          'type'   => 'change'
3290
-                                      ));
3291
-        } else if ($isOption && $node->parentNode && $attr == 'selected'
3292
-            && (
3293
-                // select
3294
-                (!$oldAttr && $node->hasAttribute($attr))
3295
-                // un-select
3296
-                || (!$node->hasAttribute($attr) && $oldAttr))
3297
-        ) {
3298
-            $event = new Dom\DOMEvent(array(
3299
-                                          'target' => $node->parentNode,
3300
-                                          'type'   => 'change'
3301
-                                      ));
3302
-        }
3303
-        if ($event) {
3304
-            PhpQueryEvents::trigger(
3305
-                $this->getDocumentID(),
3306
-                $event->type,
3307
-                array(
3308
-                    $event
3309
-                ),
3310
-                $node
3311
-            );
3312
-        }
3313
-    }
3314
-
3315
-    public function attr($attr = null, $value = null)
3316
-    {
3317
-        foreach ($this->stack(1) as $node) {
3318
-            if (!is_null($value)) {
3319
-                $loop = $attr == '*' ? $this->getNodeAttrs($node)
3320
-                    : array(
3321
-                        $attr
3322
-                    );
3323
-                foreach ($loop as $a) {
3324
-                    $oldValue = $node->getAttribute($a);
3325
-                    $oldAttr  = $node->hasAttribute($a);
3326
-                    // TODO raises an error when charset other than UTF-8
3327
-                    // while document's charset is also not UTF-8
3328
-                    @$node->setAttribute($a, $value);
3329
-                    $this->attrEvents($a, $oldAttr, $oldValue, $node);
3330
-                }
3331
-            } else if ($attr == '*') {
3332
-                // jQuery difference
3333
-                $return = array();
3334
-                foreach ($node->attributes as $n => $v)
3335
-                    $return[$n] = $v->value;
3336
-                return $return;
3337
-            } else
3338
-                return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null;
3339
-        }
3340
-        return is_null($value) ? '' : $this;
3341
-    }
3342
-
3343
-    /**
3344
-     * @param null $attr
3345
-     * @return The same attribute of each matching element, like
3346
-     * attr() but returns an array with one entry per matched element.
3347
-     * Read only.
3348
-     */
3349
-    public function attrs($attr = null)
3350
-    {
3351
-        $results = array();
3352
-        foreach ($this->stack(1) as $node) {
3353
-            $results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr)
3354
-                : null;
3355
-        }
3356
-        return $results;
3357
-    }
3358
-
3359
-    /**
3360
-     * @access private
3361
-     */
3362
-    protected function getNodeAttrs($node)
3363
-    {
3364
-        $return = array();
3365
-        foreach ($node->attributes as $n => $o)
3366
-            $return[] = $n;
3367
-        return $return;
3368
-    }
3369
-
3370
-    /**
3371
-     * Enter description here...
3372
-     *
3373
-     * @param $attr
3374
-     * @param $code
3375
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3376
-     * @todo check CDATA ???
3377
-     */
3378
-    public function attrPHP($attr, $code)
3379
-    {
3380
-        if (!is_null($code)) {
3381
-            $value = '<' . '?php ' . $code . ' ?' . '>';
3382
-            // TODO tempolary solution
3383
-            // http://code.google.com/p/phpquery/issues/detail?id=17
3384
-            //			if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII')
3385
-            //				$value	= mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES');
3386
-        }
3387
-        foreach ($this->stack(1) as $node) {
3388
-            if (!is_null($code)) {
3389
-                //				$attrNode = $this->DOM->createAttribute($attr);
3390
-                $node->setAttribute($attr, $value);
3391
-                //				$attrNode->value = $value;
3392
-                //				$node->appendChild($attrNode);
3393
-            } else if ($attr == '*') {
3394
-                // jQuery diff
3395
-                $return = array();
3396
-                foreach ($node->attributes as $n => $v)
3397
-                    $return[$n] = $v->value;
3398
-                return $return;
3399
-            } else
3400
-                return $node->getAttribute($attr);
3401
-        }
3402
-        return $this;
3403
-    }
3404
-
3405
-    /**
3406
-     * Enter description here...
3407
-     *
3408
-     * @param $attr
3409
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3410
-     */
3411
-    public function removeAttr($attr)
3412
-    {
3413
-        foreach ($this->stack(1) as $node) {
3414
-            $loop = $attr == '*' ? $this->getNodeAttrs($node)
3415
-                : array(
3416
-                    $attr
3417
-                );
3418
-            foreach ($loop as $a) {
3419
-                $oldValue = $node->getAttribute($a);
3420
-                $node->removeAttribute($a);
3421
-                $this->attrEvents($a, $oldValue, null, $node);
3422
-            }
3423
-        }
3424
-        return $this;
3425
-    }
3426
-
3427
-    /**
3428
-     * Return form element value.
3429
-     *
3430
-     * @param null $val
3431
-     * @return String Fields value.
3432
-     */
3433
-    public function val($val = null)
3434
-    {
3435
-        if (!isset($val)) {
3436
-            if ($this->eq(0)->is('select')) {
3437
-                $selected = $this->eq(0)->find('option[selected=selected]');
3438
-                if ($selected->is('[value]'))
3439
-                    return $selected->attr('value');
3440
-                else
3441
-                    return $selected->text();
3442
-            } else if ($this->eq(0)->is('textarea'))
3443
-                return $this->eq(0)->markup();
3444
-            else
3445
-                return $this->eq(0)->attr('value');
3446
-        } else {
3447
-            $_val = null;
3448
-            foreach ($this->stack(1) as $node) {
3449
-                $node = pq($node, $this->getDocumentID());
3450
-                if (is_array($val)
3451
-                    && in_array(
3452
-                        $node->attr('type'),
3453
-                        array(
3454
-                            'checkbox',
3455
-                            'radio'
3456
-                        )
3457
-                    )
3458
-                ) {
3459
-                    $isChecked = in_array($node->attr('value'), $val)
3460
-                        || in_array($node->attr('name'), $val);
3461
-                    if ($isChecked)
3462
-                        $node->attr('checked', 'checked');
3463
-                    else
3464
-                        $node->removeAttr('checked');
3465
-                } else if ($node->get(0)->tagName == 'select') {
3466
-                    if (!isset($_val)) {
3467
-                        $_val = array();
3468
-                        if (!is_array($val))
3469
-                            $_val = array(
3470
-                                (string) $val
3471
-                            );
3472
-                        else
3473
-                            foreach ($val as $v)
3474
-                                $_val[] = $v;
3475
-                    }
3476
-                    foreach ($node['option']->stack(1) as $option) {
3477
-                        $option   = pq($option, $this->getDocumentID());
3478
-                        $selected = false;
3479
-                        // XXX: workaround for string comparsion, see issue #96
3480
-                        // http://code.google.com/p/phpquery/issues/detail?id=96
3481
-                        $selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val)
3482
-                            : in_array($option->attr('value'), $_val);
3483
-                        //						$optionValue = $option->attr('value');
3484
-                        //						$optionText = $option->text();
3485
-                        //						$optionTextLenght = mb_strlen($optionText);
3486
-                        //						foreach($_val as $v)
3487
-                        //							if ($optionValue == $v)
3488
-                        //								$selected = true;
3489
-                        //							else if ($optionText == $v && $optionTextLenght == mb_strlen($v))
3490
-                        //								$selected = true;
3491
-                        if ($selected)
3492
-                            $option->attr('selected', 'selected');
3493
-                        else
3494
-                            $option->removeAttr('selected');
3495
-                    }
3496
-                } else if ($node->get(0)->tagName == 'textarea')
3497
-                    $node->markup($val);
3498
-                else
3499
-                    $node->attr('value', $val);
3500
-            }
3501
-        }
3502
-        return $this;
3503
-    }
3504
-
3505
-    /**
3506
-     * Enter description here...
3507
-     *
3508
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3509
-     */
3510
-    public function andSelf()
3511
-    {
3512
-        if ($this->previous)
3513
-            $this->elements = array_merge($this->elements, $this->previous->elements);
3514
-        return $this;
3515
-    }
3516
-
3517
-    /**
3518
-     * Enter description here...
3519
-     *
3520
-     * @param $className
3521
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3522
-     */
3523
-    public function addClass($className)
3524
-    {
3525
-        if (!$className)
3526
-            return $this;
3527
-        foreach ($this->stack(1) as $node) {
3528
-            if (!$this->is(".$className", $node))
3529
-                $node->setAttribute(
3530
-                    'class',
3531
-                    trim(
3532
-                        $node->getAttribute('class') . ' '
3533
-                        . $className
3534
-                    )
3535
-                );
3536
-        }
3537
-        return $this;
3538
-    }
3539
-
3540
-    /**
3541
-     * Enter description here...
3542
-     *
3543
-     * @param $className
3544
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3545
-     */
3546
-    public function addClassPHP($className)
3547
-    {
3548
-        foreach ($this->stack(1) as $node) {
3549
-            $classes  = $node->getAttribute('class');
3550
-            $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?'
3551
-                . '>' : '<' . '?php ' . $className . ' ?' . '>';
3552
-            $node->setAttribute('class', $newValue);
3553
-        }
3554
-        return $this;
3555
-    }
3556
-
3557
-    /**
3558
-     * Enter description here...
3559
-     *
3560
-     * @param    string $className
3561
-     * @return    bool
3562
-     */
3563
-    public function hasClass($className)
3564
-    {
3565
-        foreach ($this->stack(1) as $node) {
3566
-            if ($this->is(".$className", $node))
3567
-                return true;
3568
-        }
3569
-        return false;
3570
-    }
3571
-
3572
-    /**
3573
-     * Enter description here...
3574
-     *
3575
-     * @param $className
3576
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3577
-     */
3578
-    public function removeClass($className)
3579
-    {
3580
-        foreach ($this->stack(1) as $node) {
3581
-            $classes = explode(' ', $node->getAttribute('class'));
3582
-            if (in_array($className, $classes)) {
3583
-                $classes = array_diff(
3584
-                    $classes,
3585
-                    array(
3586
-                        $className
3587
-                    )
3588
-                );
3589
-                if ($classes)
3590
-                    $node->setAttribute('class', implode(' ', $classes));
3591
-                else
3592
-                    $node->removeAttribute('class');
3593
-            }
3594
-        }
3595
-        return $this;
3596
-    }
3597
-
3598
-    /**
3599
-     * Enter description here...
3600
-     *
3601
-     * @param $className
3602
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3603
-     */
3604
-    public function toggleClass($className)
3605
-    {
3606
-        foreach ($this->stack(1) as $node) {
3607
-            if ($this->is($node, '.' . $className))
3608
-                $this->removeClass($className);
3609
-            else
3610
-                $this->addClass($className);
3611
-        }
3612
-        return $this;
3613
-    }
3614
-
3615
-    /**
3616
-     * Proper name without underscore (just ->empty()) also works.
3617
-     *
3618
-     * Removes all child nodes from the set of matched elements.
3619
-     *
3620
-     * Example:
3621
-     * pq("p")._empty()
3622
-     *
3623
-     * HTML:
3624
-     * <p>Hello, <span>Person</span> <a href="#">and person</a></p>
3625
-     *
3626
-     * Result:
3627
-     * [ <p></p> ]
3628
-     *
3629
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3630
-     * @access private
3631
-     */
3632
-    public function _empty()
3633
-    {
3634
-        foreach ($this->stack(1) as $node) {
3635
-            // thx to 'dave at dgx dot cz'
3636
-            $node->nodeValue = '';
3637
-        }
3638
-        return $this;
3639
-    }
3640
-
3641
-    /**
3642
-     * Enter description here...
3643
-     *
3644
-     * @param array|string $callback Expects $node as first param, $index as second
3645
-     * @param null         $param1
3646
-     * @param null         $param2
3647
-     * @param null         $param3
3648
-     * @internal param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope)
3649
-     * @internal param array $arg1 Will ba passed as third and futher args to callback.
3650
-     * @internal param array $arg2 Will ba passed as fourth and futher args to callback, and so on...
3651
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3652
-     */
3653
-    public function each($callback, $param1 = null, $param2 = null, $param3 = null)
3654
-    {
3655
-        $paramStructure = null;
3656
-        if (func_num_args() > 1) {
3657
-            $paramStructure = func_get_args();
3658
-            $paramStructure = array_slice($paramStructure, 1);
3659
-        }
3660
-        foreach ($this->elements as $v)
3661
-            PhpQuery::callbackRun(
3662
-                $callback,
3663
-                array(
3664
-                    $v
3665
-                ),
3666
-                $paramStructure
3667
-            );
3668
-        return $this;
3669
-    }
3670
-
3671
-    /**
3672
-     * Run callback on actual object.
3673
-     *
3674
-     * @param      $callback
3675
-     * @param null $param1
3676
-     * @param null $param2
3677
-     * @param null $param3
3678
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3679
-     */
3680
-    public function callback($callback, $param1 = null, $param2 = null, $param3 = null)
3681
-    {
3682
-        $params    = func_get_args();
3683
-        $params[0] = $this;
3684
-        PhpQuery::callbackRun($callback, $params);
3685
-        return $this;
3686
-    }
3687
-
3688
-    /**
3689
-     * Enter description here...
3690
-     *
3691
-     * @param      $callback
3692
-     * @param null $param1
3693
-     * @param null $param2
3694
-     * @param null $param3
3695
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3696
-     * @todo add $scope and $args as in each() ???
3697
-     */
3698
-    public function map($callback, $param1 = null, $param2 = null, $param3 = null)
3699
-    {
3700
-        //		$stack = array();
3701
-        ////		foreach($this->newInstance() as $node) {
3702
-        //		foreach($this->newInstance() as $node) {
3703
-        //			$result = call_user_func($callback, $node);
3704
-        //			if ($result)
3705
-        //				$stack[] = $result;
3706
-        //		}
3707
-        $params = func_get_args();
3708
-        array_unshift($params, $this->elements);
3709
-        return $this->newInstance(
3710
-            call_user_func_array(
3711
-                array(
3712
-                    '\\PhpQuery\\PhpQuery',
3713
-                    'map'
3714
-                ),
3715
-                $params
3716
-            )
3717
-        //			PhpQuery::map($this->elements, $callback)
3718
-        );
3719
-    }
3720
-
3721
-    /**
3722
-     * Enter description here...
3723
-     *
3724
-     * @param <type> $key
3725
-     * @param <type> $value
3726
-     * @return $this
3727
-     */
3728
-    public function data($key, $value = null)
3729
-    {
3730
-        if (!isset($value)) {
3731
-            // TODO? implement specific jQuery behavior od returning parent values
3732
-            // is child which we look up doesn't exist
3733
-            return PhpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
3734
-        } else {
3735
-            foreach ($this as $node)
3736
-                PhpQuery::data($node, $key, $value, $this->getDocumentID());
3737
-            return $this;
3738
-        }
3739
-    }
3740
-
3741
-    /**
3742
-     * Enter description here...
3743
-     *
3744
-     * @param <type> $key
3745
-     * @return $this
3746
-     */
3747
-    public function removeData($key)
3748
-    {
3749
-        foreach ($this as $node)
3750
-            PhpQuery::removeData($node, $key, $this->getDocumentID());
3751
-        return $this;
3752
-    }
3753
-    // INTERFACE IMPLEMENTATIONS
3754
-
3755
-    // ITERATOR INTERFACE
3756
-    /**
3757
-     * @access private
3758
-     */
3759
-    public function rewind()
3760
-    {
3761
-        $this->debug('iterating foreach');
3762
-        //		PhpQuery::selectDocument($this->getDocumentID());
3763
-        $this->elementsBackup    = $this->elements;
3764
-        $this->elementsInterator = $this->elements;
3765
-        $this->valid             = isset($this->elements[0]) ? 1 : 0;
3766
-        // 		$this->elements = $this->valid
3767
-        // 			? array($this->elements[0])
3768
-        // 			: array();
3769
-        $this->current = 0;
3770
-    }
3771
-
3772
-    /**
3773
-     * @access private
3774
-     */
3775
-    public function current()
3776
-    {
3777
-        return $this->elementsInterator[$this->current];
3778
-    }
3779
-
3780
-    /**
3781
-     * @access private
3782
-     */
3783
-    public function key()
3784
-    {
3785
-        return $this->current;
3786
-    }
3787
-
3788
-    /**
3789
-     * Double-function method.
3790
-     *
3791
-     * First: main iterator interface method.
3792
-     * Second: Returning next sibling, alias for _next().
3793
-     *
3794
-     * Proper functionality is choosed automagicaly.
3795
-     *
3796
-     * @see PhpQueryObject::_next()
3797
-     * @param null $cssSelector
3798
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3799
-     */
3800
-    public function next($cssSelector = null)
3801
-    {
3802
-        //		if ($cssSelector || $this->valid)
3803
-        //			return $this->_next($cssSelector);
3804
-        $this->valid = isset($this->elementsInterator[$this->current + 1]) ? true
3805
-            : false;
3806
-        if (!$this->valid && $this->elementsInterator) {
3807
-            $this->elementsInterator = null;
3808
-        } else if ($this->valid) {
3809
-            $this->current++;
3810
-        } else {
3811
-            return $this->_next($cssSelector);
3812
-        }
3813
-    }
3814
-
3815
-    /**
3816
-     * @access private
3817
-     */
3818
-    public function valid()
3819
-    {
3820
-        return $this->valid;
3821
-    }
3822
-    // ITERATOR INTERFACE END
3823
-    // ARRAYACCESS INTERFACE
3824
-    /**
3825
-     * @access private
3826
-     */
3827
-    public function offsetExists($offset)
3828
-    {
3829
-        return $this->find($offset)->size() > 0;
3830
-    }
3831
-
3832
-    /**
3833
-     * @access private
3834
-     */
3835
-    public function offsetGet($offset)
3836
-    {
3837
-        return $this->find($offset);
3838
-    }
3839
-
3840
-    /**
3841
-     * @access private
3842
-     */
3843
-    public function offsetSet($offset, $value)
3844
-    {
3845
-        //		$this->find($offset)->replaceWith($value);
3846
-        $this->find($offset)->html($value);
3847
-    }
3848
-
3849
-    /**
3850
-     * @access private
3851
-     */
3852
-    public function offsetUnset($offset)
3853
-    {
3854
-        // empty
3855
-        throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML.");
3856
-    }
3857
-    // ARRAYACCESS INTERFACE END
3858
-    /**
3859
-     * Returns node's XPath.
3860
-     *
3861
-     * @param unknown_type $oneNode
3862
-     * @param null         $namespace
3863
-     * @return string
3864
-     * @TODO   use native getNodePath is avaible
3865
-     * @access private
3866
-     */
3867
-    protected function getNodeXpath($oneNode = null, $namespace = null)
3868
-    {
3869
-        $return = array();
3870
-        $loop   = $oneNode ? array(
3871
-            $oneNode
3872
-        ) : $this->elements;
3873
-        //		if ($namespace)
3874
-        //			$namespace .= ':';
3875
-        foreach ($loop as $node) {
3876
-            if ($node instanceof \DOMDocument) {
3877
-                $return[] = '';
3878
-                continue;
3879
-            }
3880
-            $xpath = array();
3881
-            while (!($node instanceof \DOMDocument)) {
3882
-                $i       = 1;
3883
-                $sibling = $node;
3884
-                while ($sibling->previousSibling) {
3885
-                    $sibling   = $sibling->previousSibling;
3886
-                    $isElement = $sibling instanceof \DOMElement;
3887
-                    if ($isElement && $sibling->tagName == $node->tagName)
3888
-                        $i++;
3889
-                }
3890
-                $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]"
3891
-                    : "{$node->tagName}[{$i}]";
3892
-                $node    = $node->parentNode;
3893
-            }
3894
-            $xpath    = join('/', array_reverse($xpath));
3895
-            $return[] = '/' . $xpath;
3896
-        }
3897
-        return $oneNode ? $return[0] : $return;
3898
-    }
3899
-
3900
-    // HELPERS
3901
-    public function whois($oneNode = null)
3902
-    {
3903
-        $return = array();
3904
-        $loop   = $oneNode ? array(
3905
-            $oneNode
3906
-        ) : $this->elements;
3907
-        foreach ($loop as $node) {
3908
-            if (isset($node->tagName)) {
3909
-                $tag      = in_array(
3910
-                    $node->tagName,
3911
-                    array(
3912
-                        'php',
3913
-                        'js'
3914
-                    )
3915
-                ) ? strtoupper($node->tagName) : $node->tagName;
3916
-                $return[] = $tag
3917
-                    . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '')
3918
-                    . ($node->getAttribute('class') ? '.'
3919
-                        . join('.', explode(' ', $node->getAttribute('class'))) : '')
3920
-                    . ($node->getAttribute('name') ? '[name="'
3921
-                        . $node->getAttribute('name') . '"]' : '')
3922
-                    . ($node->getAttribute('value')
3923
-                    && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="'
3924
-                        . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15)
3925
-                        . '"]' : '')
3926
-                    . ($node->getAttribute('value')
3927
-                    && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]'
3928
-                        : '') . ($node->getAttribute('selected') ? '[selected]' : '')
3929
-                    . ($node->getAttribute('checked') ? '[checked]' : '');
3930
-            } else if ($node instanceof \DOMTEXT) {
3931
-                if (trim($node->textContent))
3932
-                    $return[] = 'Text:'
3933
-                        . substr(str_replace("\n", ' ', $node->textContent), 0, 15);
3934
-            } else {
3935
-
3936
-            }
3937
-        }
3938
-        return $oneNode && isset($return[0]) ? $return[0] : $return;
3939
-    }
3940
-
3941
-    /**
3942
-     * Dump htmlOuter and preserve chain. Usefull for debugging.
3943
-     *
3944
-     * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3945
-     *
3946
-     */
3947
-    public function dump()
3948
-    {
3949
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3950
-        PhpQuery::$debug = false;
3951
-        //		print __FILE__.':'.__LINE__."\n";
3952
-        var_dump($this->htmlOuter());
3953
-        return $this;
3954
-    }
3955
-
3956
-    public function dumpWhois()
3957
-    {
3958
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3959
-        $debug           = PhpQuery::$debug;
3960
-        PhpQuery::$debug = false;
3961
-        //		print __FILE__.':'.__LINE__."\n";
3962
-        var_dump('whois', $this->whois());
3963
-        PhpQuery::$debug = $debug;
3964
-        return $this;
3965
-    }
3966
-
3967
-    public function dumpLength()
3968
-    {
3969
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3970
-        $debug           = PhpQuery::$debug;
3971
-        PhpQuery::$debug = false;
3972
-        //		print __FILE__.':'.__LINE__."\n";
3973
-        var_dump('length', $this->length());
3974
-        PhpQuery::$debug = $debug;
3975
-        return $this;
3976
-    }
3977
-
3978
-    public function dumpTree($html = true, $title = true)
3979
-    {
3980
-        $output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
3981
-        $debug           = PhpQuery::$debug;
3982
-        PhpQuery::$debug = false;
3983
-        foreach ($this->stack() as $node)
3984
-            $output .= $this->__dumpTree($node);
3985
-        PhpQuery::$debug = $debug;
3986
-        print $html ? nl2br(str_replace(' ', '&nbsp;', $output)) : $output;
3987
-        return $this;
3988
-    }
3989
-
3990
-    private function __dumpTree($node, $intend = 0)
3991
-    {
3992
-        $whois  = $this->whois($node);
3993
-        $return = '';
3994
-        if ($whois)
3995
-            $return .= str_repeat(' - ', $intend) . $whois . "\n";
3996
-        if (isset($node->childNodes))
3997
-            foreach ($node->childNodes as $chNode)
3998
-                $return .= $this->__dumpTree($chNode, $intend + 1);
3999
-        return $return;
4000
-    }
4001
-
4002
-    /**
4003
-     * Dump htmlOuter and stop script execution. Usefull for debugging.
4004
-     *
4005
-     */
4006
-    public function dumpDie()
4007
-    {
4008
-        print __FILE__ . ':' . __LINE__;
4009
-        var_dump($this->htmlOuter());
4010
-        die();
4011
-    }
1314
+						),
1315
+						new \CallbackParam(),
1316
+						$param
1317
+					);
1318
+				$this->elements = $mapped->elements;
1319
+				break;
1320
+			default:
1321
+				$this->debug("Unknown pseudoclass '{$class}', skipping...");
1322
+		}
1323
+	}
1324
+
1325
+	/**
1326
+	 * @access private
1327
+	 */
1328
+	protected function __pseudoClassParam($paramsString)
1329
+	{
1330
+		// TODO;
1331
+	}
1332
+
1333
+	/**
1334
+	 * Enter description here...
1335
+	 *
1336
+	 * @param      $selector
1337
+	 * @param null $nodes
1338
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1339
+	 */
1340
+	public function is($selector, $nodes = null)
1341
+	{
1342
+		PhpQuery::debug(
1343
+			array(
1344
+				"Is:",
1345
+				$selector
1346
+			)
1347
+		);
1348
+		if (!$selector)
1349
+			return false;
1350
+		$oldStack    = $this->elements;
1351
+		$returnArray = false;
1352
+		if ($nodes && is_array($nodes)) {
1353
+			$this->elements = $nodes;
1354
+		} else if ($nodes)
1355
+			$this->elements = array(
1356
+				$nodes
1357
+			);
1358
+		$this->filter($selector, true);
1359
+		$stack          = $this->elements;
1360
+		$this->elements = $oldStack;
1361
+		if ($nodes)
1362
+			return $stack ? $stack : null;
1363
+		return (bool) count($stack);
1364
+	}
1365
+
1366
+	/**
1367
+	 * Enter description here...
1368
+	 * jQuery difference.
1369
+	 *
1370
+	 * Callback:
1371
+	 * - $index int
1372
+	 * - $node DOMNode
1373
+	 *
1374
+	 * @param      $callback
1375
+	 * @param bool $_skipHistory
1376
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1377
+	 * @link http://docs.jquery.com/Traversing/filter
1378
+	 */
1379
+	public function filterCallback($callback, $_skipHistory = false)
1380
+	{
1381
+		if (!$_skipHistory) {
1382
+			$this->elementsBackup = $this->elements;
1383
+			$this->debug("Filtering by callback");
1384
+		}
1385
+		$newStack = array();
1386
+		foreach ($this->elements as $index => $node) {
1387
+			$result = PhpQuery::callbackRun(
1388
+				$callback,
1389
+				array(
1390
+					$index,
1391
+					$node
1392
+				)
1393
+			);
1394
+			if (is_null($result) || (!is_null($result) && $result))
1395
+				$newStack[] = $node;
1396
+		}
1397
+		$this->elements = $newStack;
1398
+		return $_skipHistory ? $this : $this->newInstance();
1399
+	}
1400
+
1401
+	/**
1402
+	 * Enter description here...
1403
+	 *
1404
+	 * @param      $selectors
1405
+	 * @param bool $_skipHistory
1406
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1407
+	 * @link http://docs.jquery.com/Traversing/filter
1408
+	 */
1409
+	public function filter($selectors, $_skipHistory = false)
1410
+	{
1411
+		if ($selectors instanceof \Callback OR $selectors instanceof \Closure)
1412
+			return $this->filterCallback($selectors, $_skipHistory);
1413
+		if (!$_skipHistory)
1414
+			$this->elementsBackup = $this->elements;
1415
+		$notSimpleSelector = array(
1416
+			' ',
1417
+			'>',
1418
+			'~',
1419
+			'+',
1420
+			'/'
1421
+		);
1422
+		if (!is_array($selectors))
1423
+			$selectors = $this->parseSelector($selectors);
1424
+		if (!$_skipHistory)
1425
+			$this->debug(
1426
+				array(
1427
+					"Filtering:",
1428
+					$selectors
1429
+				)
1430
+			);
1431
+		$finalStack = array();
1432
+		foreach ($selectors as $selector) {
1433
+			$stack = array();
1434
+			if (!$selector)
1435
+				break;
1436
+			// avoid first space or /
1437
+			if (in_array($selector[0], $notSimpleSelector))
1438
+				$selector = array_slice($selector, 1);
1439
+			// PER NODE selector chunks
1440
+			foreach ($this->stack() as $node) {
1441
+				$break = false;
1442
+				foreach ($selector as $s) {
1443
+					if (!($node instanceof \DOMElement)) {
1444
+						// all besides \DOMElement
1445
+						if ($s[0] == '[') {
1446
+							$attr = trim($s, '[]');
1447
+							if (mb_strpos($attr, '=')) {
1448
+								list($attr, $val) = explode('=', $attr);
1449
+								if ($attr == 'nodeType' && $node->nodeType != $val)
1450
+									$break = true;
1451
+							}
1452
+						} else
1453
+							$break = true;
1454
+					} else {
1455
+						// \DOMElement only
1456
+						// ID
1457
+						if ($s[0] == '#') {
1458
+							if ($node->getAttribute('id') != substr($s, 1))
1459
+								$break = true;
1460
+							// CLASSES
1461
+						} else if ($s[0] == '.') {
1462
+							if (!$this->matchClasses($s, $node))
1463
+								$break = true;
1464
+							// ATTRS
1465
+						} else if ($s[0] == '[') {
1466
+							// strip side brackets
1467
+							$attr = trim($s, '[]');
1468
+							if (mb_strpos($attr, '=')) {
1469
+								list($attr, $val) = explode('=', $attr);
1470
+								$val = self::unQuote($val);
1471
+								if ($attr == 'nodeType') {
1472
+									if ($val != $node->nodeType)
1473
+										$break = true;
1474
+								} else if ($this->isRegexp($attr)) {
1475
+									$val = extension_loaded('mbstring')
1476
+									&& PhpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
1477
+										: preg_quote(trim($val, '"\''), '@');
1478
+									// switch last character
1479
+									switch (substr($attr, -1)) {
1480
+										// quotemeta used insted of preg_quote
1481
+										// http://code.google.com/p/phpquery/issues/detail?id=76
1482
+										case '^':
1483
+											$pattern = '^' . $val;
1484
+											break;
1485
+										case '*':
1486
+											$pattern = '.*' . $val . '.*';
1487
+											break;
1488
+										case '$':
1489
+											$pattern = '.*' . $val . '$';
1490
+											break;
1491
+									}
1492
+									// cut last character
1493
+									$attr    = substr($attr, 0, -1);
1494
+									$isMatch = extension_loaded('mbstring')
1495
+									&& PhpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
1496
+										: preg_match("@{$pattern}@", $node->getAttribute($attr));
1497
+									if (!$isMatch)
1498
+										$break = true;
1499
+								} else if ($node->getAttribute($attr) != $val)
1500
+									$break = true;
1501
+							} else if (!$node->hasAttribute($attr))
1502
+								$break = true;
1503
+							// PSEUDO CLASSES
1504
+						} else if ($s[0] == ':') {
1505
+							// skip
1506
+							// TAG
1507
+						} else if (trim($s)) {
1508
+							if ($s != '*') {
1509
+								// TODO namespaces
1510
+								if (isset($node->tagName)) {
1511
+									if ($node->tagName != $s)
1512
+										$break = true;
1513
+								} else if ($s == 'html' && !$this->isRoot($node))
1514
+									$break = true;
1515
+							}
1516
+							// AVOID NON-SIMPLE SELECTORS
1517
+						} else if (in_array($s, $notSimpleSelector)) {
1518
+							$break = true;
1519
+							$this->debug(
1520
+								array(
1521
+									'Skipping non simple selector',
1522
+									$selector
1523
+								)
1524
+							);
1525
+						}
1526
+					}
1527
+					if ($break)
1528
+						break;
1529
+				}
1530
+				// if element passed all chunks of selector - add it to new stack
1531
+				if (!$break)
1532
+					$stack[] = $node;
1533
+			}
1534
+			$tmpStack       = $this->elements;
1535
+			$this->elements = $stack;
1536
+			// PER ALL NODES selector chunks
1537
+			foreach ($selector as $s)
1538
+				// PSEUDO CLASSES
1539
+				if ($s[0] == ':')
1540
+					$this->pseudoClasses($s);
1541
+			foreach ($this->elements as $node)
1542
+				// XXX it should be merged without duplicates
1543
+				// but jQuery doesnt do that
1544
+				$finalStack[] = $node;
1545
+			$this->elements = $tmpStack;
1546
+		}
1547
+		$this->elements = $finalStack;
1548
+		if ($_skipHistory) {
1549
+			return $this;
1550
+		} else {
1551
+			$this->debug("Stack length after filter(): " . count($finalStack));
1552
+			return $this->newInstance();
1553
+		}
1554
+	}
1555
+
1556
+	/**
1557
+	 *
1558
+	 * @param $value
1559
+	 * @return string
1560
+	 * @TODO implement in all methods using passed parameters
1561
+	 */
1562
+	protected static function unQuote($value)
1563
+	{
1564
+		return $value[0] == '\'' || $value[0] == '"' ? substr($value, 1, -1)
1565
+			: $value;
1566
+	}
1567
+
1568
+	/**
1569
+	 * Enter description here...
1570
+	 *
1571
+	 * @link http://docs.jquery.com/Ajax/load
1572
+	 * @param      $url
1573
+	 * @param null $data
1574
+	 * @param null $callback
1575
+	 * @return PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1576
+	 * @todo Support $selector
1577
+	 */
1578
+	public function load($url, $data = null, $callback = null)
1579
+	{
1580
+		if ($data && !is_array($data)) {
1581
+			$callback = $data;
1582
+			$data     = null;
1583
+		}
1584
+		if (mb_strpos($url, ' ') !== false) {
1585
+			$matches = null;
1586
+			if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport)
1587
+				mb_ereg('^([^ ]+) (.*)$', $url, $matches);
1588
+			else
1589
+				preg_match('@^([^ ]+) (.*)$@', $url, $matches);
1590
+			$url      = $matches[1];
1591
+			$selector = $matches[2];
1592
+			// FIXME this sucks, pass as callback param
1593
+			$this->_loadSelector = $selector;
1594
+		}
1595
+		$ajax = array(
1596
+			'url'      => $url,
1597
+			'type'     => $data ? 'POST' : 'GET',
1598
+			'data'     => $data,
1599
+			'complete' => $callback,
1600
+			'success'  => array(
1601
+				$this,
1602
+				'__loadSuccess'
1603
+			)
1604
+		);
1605
+		PhpQuery::ajax($ajax);
1606
+		return $this;
1607
+	}
1608
+
1609
+	/**
1610
+	 * @access private
1611
+	 * @param $html
1612
+	 */
1613
+	public function __loadSuccess($html)
1614
+	{
1615
+		if ($this->_loadSelector) {
1616
+			$html = PhpQuery::newDocument($html)->find($this->_loadSelector);
1617
+			unset($this->_loadSelector);
1618
+		}
1619
+		foreach ($this->stack(1) as $node) {
1620
+			PhpQuery::pq($node, $this->getDocumentID())->markup($html);
1621
+		}
1622
+	}
1623
+
1624
+	/**
1625
+	 * Allows users to enter strings of CSS selectors. Useful
1626
+	 * when the CSS is loaded via style or @imports that PhpQuery can't load
1627
+	 * because it doesn't know the URL context of the request.
1628
+	 */
1629
+	public function addCSS($string)
1630
+	{
1631
+		if (!isset($this->cssString[$this->getDocumentID()])) {
1632
+			$this->cssString[$this->getDocumentID()] = '';
1633
+		}
1634
+		$this->cssString[$this->getDocumentID()] .= $string;
1635
+		$this->parseCSS();
1636
+	}
1637
+
1638
+	/**
1639
+	 * Either sets the CSS property of an object or retrieves the
1640
+	 * CSS property of a proejct.
1641
+	 *
1642
+	 * @param      $property_name
1643
+	 * @param bool $value
1644
+	 * @return string of css property value
1645
+	 * @todo
1646
+	 */
1647
+	public function css($property_name, $value = false)
1648
+	{
1649
+		if (!isset($this->cssIsParsed[$this->getDocumentID()])
1650
+		|| $this->cssIsParsed[$this->getDocumentID()] === false
1651
+		) {
1652
+			$this->parseCSS();
1653
+		}
1654
+		$data = PhpQuery::data($this->get(0), 'phpquery_css', null, $this->getDocumentID());
1655
+		if (!$value) {
1656
+			if (isset($data[$property_name])) {
1657
+				return $data[$property_name]['value'];
1658
+			}
1659
+			return null;
1660
+		}
1661
+		$specificity          = (isset($data[$property_name])) ? $data[$property_name]['specificity']
1662
+			+ 1 : 1000;
1663
+		$data[$property_name] = array(
1664
+			'specificity' => $specificity,
1665
+			'value'       => $value
1666
+		);
1667
+		PhpQuery::data($this->get(0), 'phpquery_css', $data, $this->getDocumentID());
1668
+		$this->bubbleCSS(PhpQuery::pq($this->get(0), $this->getDocumentID()));
1669
+
1670
+		if ($specificity >= 1000) {
1671
+			$styles = array();
1672
+			foreach ($this->data('phpquery_css') as $k => $v) {
1673
+				if ($v['specificity'] >= 1000) {
1674
+					$styles[$k] = trim($k) . ':' . trim($v['value']);
1675
+				}
1676
+			}
1677
+			ksort($styles);
1678
+			if (empty($styles)) {
1679
+				$this->removeAttr('style');
1680
+			} elseif (PhpQuery::$enableCssShorthand) {
1681
+				$parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}');
1682
+				$doc    = $parser->parse();
1683
+				$doc->createShorthands();
1684
+				$style = trim($doc->__toString(), "\n\r\t {}");
1685
+			} else {
1686
+				$style = join(';', $styles);
1687
+			}
1688
+			$this->attr('style', $style);
1689
+		}
1690
+	}
1691
+
1692
+	public function parseCSS()
1693
+	{
1694
+		if (!isset($this->cssString[$this->getDocumentID()])) {
1695
+			$this->cssString[$this->getDocumentID()] = file_get_contents(
1696
+				dirname(__FILE__)
1697
+				. '/Resources/default.css'
1698
+			);
1699
+		}
1700
+		foreach (PhpQuery::pq('style', $this->getDocumentID()) as $style) {
1701
+			$this->cssString[$this->getDocumentID()] .= PhpQuery::pq($style)->text();
1702
+		}
1703
+
1704
+		$CssParser   = new CssParser($this->cssString[$this->getDocumentID()]);
1705
+		$CssDocument = $CssParser->parse();
1706
+		foreach ($CssDocument->getAllRuleSets() as $ruleset) {
1707
+			foreach ($ruleset->getSelector() as $selector) {
1708
+				$specificity = $selector->getSpecificity();
1709
+				foreach (PhpQuery::pq($selector->getSelector(), $this->getDocumentID()) as $el) {
1710
+					$existing = pq($el)->data('phpquery_css');
1711
+					if (PhpQuery::$enableCssShorthand) {
1712
+						$ruleset->expandShorthands();
1713
+					}
1714
+					foreach ($ruleset->getRules() as $value) {
1715
+						$rule = $value->getRule();
1716
+						if (!isset($existing[$rule])
1717
+							|| $existing[$rule]['specificity'] <= $specificity
1718
+						) {
1719
+							$value           = $value->getValue();
1720
+							$value           = (is_object($value)) ? $value->__toString() : $value;
1721
+							$existing[$rule] = array(
1722
+								'specificity' => $specificity,
1723
+								'value'       => $value
1724
+							);
1725
+						}
1726
+					}
1727
+					PhpQuery::pq($el)->data('phpquery_css', $existing);
1728
+					$this->bubbleCSS(PhpQuery::pq($el));
1729
+				}
1730
+			}
1731
+		}
1732
+		foreach (PhpQuery::pq('*', $this->getDocumentID()) as $el) {
1733
+			$existing = pq($el)->data('phpquery_css');
1734
+			$style    = pq($el)->attr('style');
1735
+			$style    = strlen($style) ? explode(';', $style) : array();
1736
+			foreach ($this->attribute_css_mapping as $map => $css_equivalent) {
1737
+				if ($el->hasAttribute($map)) {
1738
+					$style[] = $css_equivalent . ':' . pq($el)->attr($map);
1739
+				}
1740
+			}
1741
+			if (count($style)) {
1742
+				$CssParser   = new CssParser('#ruleset {' . implode(';', $style) . '}');
1743
+				$CssDocument = $CssParser->parse();
1744
+				$ruleset     = $CssDocument->getAllRulesets();
1745
+				$ruleset     = reset($ruleset);
1746
+				if (PhpQuery::$enableCssShorthand) {
1747
+					$ruleset->expandShorthands();
1748
+				}
1749
+				foreach ($ruleset->getRules() as $value) {
1750
+					$rule = $value->getRule();
1751
+					if (!isset($existing[$rule])
1752
+						|| 1000 >= $existing[$rule]['specificity']
1753
+					) {
1754
+						$value           = $value->getValue();
1755
+						$value           = (is_object($value)) ? $value->__toString() : $value;
1756
+						$existing[$rule] = array(
1757
+							'specificity' => 1000,
1758
+							'value'       => $value
1759
+						);
1760
+					}
1761
+				}
1762
+				PhpQuery::pq($el)->data('phpquery_css', $existing);
1763
+				$this->bubbleCSS(PhpQuery::pq($el));
1764
+			}
1765
+		}
1766
+	}
1767
+
1768
+	protected function bubbleCSS($element)
1769
+	{
1770
+		$style = $element->data('phpquery_css');
1771
+		foreach ($element->children() as $element_child) {
1772
+			$existing = PhpQuery::pq($element_child)->data('phpquery_css');
1773
+			foreach ($style as $rule => $value) {
1774
+				if (!isset($existing[$rule])
1775
+					|| $value['specificity'] > $existing[$rule]['specificity']
1776
+				) {
1777
+					$existing[$rule] = $value;
1778
+				}
1779
+			}
1780
+			PhpQuery::pq($element_child)->data('phpquery_css', $existing);
1781
+			if (PhpQuery::pq($element_child)->children()->length) {
1782
+				$this->bubbleCSS(PhpQuery::pq($element_child));
1783
+			}
1784
+		}
1785
+	}
1786
+
1787
+	/**
1788
+	 * @todo
1789
+	 *
1790
+	 */
1791
+	public function show()
1792
+	{
1793
+		$display = ($this->data('phpquery_display_state')) ? $this->data('phpquery_display_state')
1794
+			: 'block';
1795
+		$this->css('display', $display);
1796
+		return $this;
1797
+	}
1798
+
1799
+	/**
1800
+	 * @todo
1801
+	 *
1802
+	 */
1803
+	public function hide()
1804
+	{
1805
+		$this->data('phpquery_display_state', $this->css('display'));
1806
+		$this->css('display', 'none');
1807
+		return $this;
1808
+	}
1809
+
1810
+	/**
1811
+	 * Trigger a type of event on every matched element.
1812
+	 *
1813
+	 * @param                 $type
1814
+	 * @param array|\PhpQuery $data
1815
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1816
+	 * @TODO support more than event in $type (space-separated)
1817
+	 */
1818
+	public function trigger($type, $data = array())
1819
+	{
1820
+		foreach ($this->elements as $node)
1821
+			PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
1822
+		return $this;
1823
+	}
1824
+
1825
+	/**
1826
+	 * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
1827
+	 *
1828
+	 * @param  $type
1829
+	 * @param  $data
1830
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1831
+	 * @TODO
1832
+	 */
1833
+	public function triggerHandler($type, $data = array())
1834
+	{
1835
+		// TODO;
1836
+	}
1837
+
1838
+	/**
1839
+	 * Binds a handler to one or more events (like click) for each matched element.
1840
+	 * Can also bind custom events.
1841
+	 *
1842
+	 * @param       $type
1843
+	 * @param mixed $data Optional
1844
+	 * @param       $callback
1845
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1846
+	 * @TODO support '!' (exclusive) events
1847
+	 * @TODO support more than event in $type (space-separated)
1848
+	 */
1849
+	public function bind($type, $data, $callback = null)
1850
+	{
1851
+		// TODO check if $data is callable, not using is_callable
1852
+		if (!isset($callback)) {
1853
+			$callback = $data;
1854
+			$data     = null;
1855
+		}
1856
+		foreach ($this->elements as $node)
1857
+			PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
1858
+		return $this;
1859
+	}
1860
+
1861
+	/**
1862
+	 * Enter description here...
1863
+	 *
1864
+	 * @param string $type
1865
+	 * @param        $callback
1866
+	 * @return unknown
1867
+	 * @TODO namespace events
1868
+	 * @TODO support more than event in $type (space-separated)
1869
+	 */
1870
+	public function unbind($type = null, $callback = null)
1871
+	{
1872
+		foreach ($this->elements as $node)
1873
+			PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
1874
+		return $this;
1875
+	}
1876
+
1877
+	/**
1878
+	 * Enter description here...
1879
+	 *
1880
+	 * @param null $callback
1881
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1882
+	 */
1883
+	public function change($callback = null)
1884
+	{
1885
+		if ($callback)
1886
+			return $this->bind('change', $callback);
1887
+		return $this->trigger('change');
1888
+	}
1889
+
1890
+	/**
1891
+	 * Enter description here...
1892
+	 *
1893
+	 * @param null $callback
1894
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1895
+	 */
1896
+	public function submit($callback = null)
1897
+	{
1898
+		if ($callback)
1899
+			return $this->bind('submit', $callback);
1900
+		return $this->trigger('submit');
1901
+	}
1902
+
1903
+	/**
1904
+	 * Enter description here...
1905
+	 *
1906
+	 * @param null $callback
1907
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1908
+	 */
1909
+	public function click($callback = null)
1910
+	{
1911
+		if ($callback)
1912
+			return $this->bind('click', $callback);
1913
+		return $this->trigger('click');
1914
+	}
1915
+
1916
+	/**
1917
+	 * Enter description here...
1918
+	 *
1919
+	 * @param String|PhpQuery
1920
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1921
+	 */
1922
+	public function wrapAllOld($wrapper)
1923
+	{
1924
+		$wrapper = pq($wrapper)->_clone();
1925
+		if (!$wrapper->length() || !$this->length())
1926
+			return $this;
1927
+		$wrapper->insertBefore($this->elements[0]);
1928
+		$deepest = $wrapper->elements[0];
1929
+		while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1930
+			$deepest = $deepest->firstChild;
1931
+		pq($deepest)->append($this);
1932
+		return $this;
1933
+	}
1934
+
1935
+	/**
1936
+	 * Enter description here...
1937
+	 *
1938
+	 * TODO testme...
1939
+	 * @param String|PhpQuery
1940
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1941
+	 */
1942
+	public function wrapAll($wrapper)
1943
+	{
1944
+		if (!$this->length())
1945
+			return $this;
1946
+		return PhpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
1947
+			array(
1948
+				$this,
1949
+				'___wrapAllCallback'
1950
+			)
1951
+		)->append($this);
1952
+	}
1953
+
1954
+	/**
1955
+	 *
1956
+	 * @param $node
1957
+	 * @return unknown_type
1958
+	 * @access private
1959
+	 */
1960
+	public function ___wrapAllCallback($node)
1961
+	{
1962
+		$deepest = $node;
1963
+		while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1964
+			$deepest = $deepest->firstChild;
1965
+		return $deepest;
1966
+	}
1967
+
1968
+	/**
1969
+	 * Enter description here...
1970
+	 * NON JQUERY METHOD
1971
+	 *
1972
+	 * @param $codeBefore
1973
+	 * @param $codeAfter
1974
+	 * @internal param $ String|PhpQuery
1975
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1976
+	 */
1977
+	public function wrapAllPHP($codeBefore, $codeAfter)
1978
+	{
1979
+		return $this->slice(0, 1)->beforePHP($codeBefore)->end()->slice(-1)->afterPHP($codeAfter)->end();
1980
+	}
1981
+
1982
+	/**
1983
+	 * Enter description here...
1984
+	 *
1985
+	 * @param String|PhpQuery
1986
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
1987
+	 */
1988
+	public function wrap($wrapper)
1989
+	{
1990
+		foreach ($this->stack() as $node)
1991
+			PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
1992
+		return $this;
1993
+	}
1994
+
1995
+	/**
1996
+	 * Enter description here...
1997
+	 *
1998
+	 * @param $codeBefore
1999
+	 * @param $codeAfter
2000
+	 * @internal param $ String|PhpQuery
2001
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2002
+	 */
2003
+	public function wrapPHP($codeBefore, $codeAfter)
2004
+	{
2005
+		foreach ($this->stack() as $node)
2006
+			PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
2007
+		return $this;
2008
+	}
2009
+
2010
+	/**
2011
+	 * Enter description here...
2012
+	 *
2013
+	 * @param String|PhpQuery
2014
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2015
+	 */
2016
+	public function wrapInner($wrapper)
2017
+	{
2018
+		foreach ($this->stack() as $node)
2019
+			PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
2020
+		return $this;
2021
+	}
2022
+
2023
+	/**
2024
+	 * Enter description here...
2025
+	 *
2026
+	 * @param $codeBefore
2027
+	 * @param $codeAfter
2028
+	 * @internal param $ String|PhpQuery
2029
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2030
+	 */
2031
+	public function wrapInnerPHP($codeBefore, $codeAfter)
2032
+	{
2033
+		foreach ($this->stack(1) as $node)
2034
+			PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
2035
+		return $this;
2036
+	}
2037
+
2038
+	/**
2039
+	 * Enter description here...
2040
+	 *
2041
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2042
+	 * @testme Support for text nodes
2043
+	 */
2044
+	public function contents()
2045
+	{
2046
+		$stack = array();
2047
+		foreach ($this->stack(1) as $el) {
2048
+			// FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56
2049
+			//			if (! isset($el->childNodes))
2050
+			//				continue;
2051
+			foreach ($el->childNodes as $node) {
2052
+				$stack[] = $node;
2053
+			}
2054
+		}
2055
+		return $this->newInstance($stack);
2056
+	}
2057
+
2058
+	/**
2059
+	 * Enter description here...
2060
+	 *
2061
+	 * jQuery difference.
2062
+	 *
2063
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2064
+	 */
2065
+	public function contentsUnwrap()
2066
+	{
2067
+		foreach ($this->stack(1) as $node) {
2068
+			if (!$node->parentNode)
2069
+				continue;
2070
+			$childNodes = array();
2071
+			// any modification in DOM tree breaks childNodes iteration, so cache them first
2072
+			foreach ($node->childNodes as $chNode)
2073
+				$childNodes[] = $chNode;
2074
+			foreach ($childNodes as $chNode)
2075
+				//				$node->parentNode->appendChild($chNode);
2076
+				$node->parentNode->insertBefore($chNode, $node);
2077
+			$node->parentNode->removeChild($node);
2078
+		}
2079
+		return $this;
2080
+	}
2081
+
2082
+	/**
2083
+	 * Enter description here...
2084
+	 *
2085
+	 * jQuery difference.
2086
+	 */
2087
+	public function switchWith($markup)
2088
+	{
2089
+		$markup  = pq($markup, $this->getDocumentID());
2090
+		$content = null;
2091
+		foreach ($this->stack(1) as $node) {
2092
+			pq($node)->contents()->toReference($content)->end()->replaceWith($markup->clone()->append($content));
2093
+		}
2094
+		return $this;
2095
+	}
2096
+
2097
+	/**
2098
+	 * Enter description here...
2099
+	 *
2100
+	 * @param $num
2101
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2102
+	 */
2103
+	public function eq($num)
2104
+	{
2105
+		$oldStack             = $this->elements;
2106
+		$this->elementsBackup = $this->elements;
2107
+		$this->elements       = array();
2108
+		if (isset($oldStack[$num]))
2109
+			$this->elements[] = $oldStack[$num];
2110
+		return $this->newInstance();
2111
+	}
2112
+
2113
+	/**
2114
+	 * Enter description here...
2115
+	 *
2116
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2117
+	 */
2118
+	public function size()
2119
+	{
2120
+		return count($this->elements);
2121
+	}
2122
+
2123
+	/**
2124
+	 * Enter description here...
2125
+	 *
2126
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2127
+	 * @deprecated Use length as attribute
2128
+	 */
2129
+	public function length()
2130
+	{
2131
+		return $this->size();
2132
+	}
2133
+
2134
+	public function count()
2135
+	{
2136
+		return $this->size();
2137
+	}
2138
+
2139
+	/**
2140
+	 * Enter description here...
2141
+	 *
2142
+	 * @param int $level
2143
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2144
+	 * @todo $level
2145
+	 */
2146
+	public function end($level = 1)
2147
+	{
2148
+		//		$this->elements = array_pop( $this->history );
2149
+		//		return $this;
2150
+		//		$this->previous->DOM = $this->DOM;
2151
+		//		$this->previous->XPath = $this->XPath;
2152
+		return $this->previous ? $this->previous : $this;
2153
+	}
2154
+
2155
+	/**
2156
+	 * Enter description here...
2157
+	 * Normal use ->clone() .
2158
+	 *
2159
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2160
+	 * @access private
2161
+	 */
2162
+	public function _clone()
2163
+	{
2164
+		$newStack = array();
2165
+		//pr(array('copy... ', $this->whois()));
2166
+		//$this->dumpHistory('copy');
2167
+		$this->elementsBackup = $this->elements;
2168
+		foreach ($this->elements as $node) {
2169
+			$newStack[] = $node->cloneNode(true);
2170
+		}
2171
+		$this->elements = $newStack;
2172
+		return $this->newInstance();
2173
+	}
2174
+
2175
+	/**
2176
+	 * Enter description here...
2177
+	 *
2178
+	 * @param $code
2179
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2180
+	 */
2181
+	public function replaceWithPHP($code)
2182
+	{
2183
+		return $this->replaceWith(PhpQuery::php($code));
2184
+	}
2185
+
2186
+	/**
2187
+	 * Enter description here...
2188
+	 *
2189
+	 * @param String|PhpQuery $content
2190
+	 * @link http://docs.jquery.com/Manipulation/replaceWith#content
2191
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2192
+	 */
2193
+	public function replaceWith($content)
2194
+	{
2195
+		return $this->after($content)->remove();
2196
+	}
2197
+
2198
+	/**
2199
+	 * Enter description here...
2200
+	 *
2201
+	 * @param String $selector
2202
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2203
+	 * @todo this works ?
2204
+	 */
2205
+	public function replaceAll($selector)
2206
+	{
2207
+		foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node)
2208
+			PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
2209
+		return $this;
2210
+	}
2211
+
2212
+	/**
2213
+	 * Enter description here...
2214
+	 *
2215
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2216
+	 */
2217
+	public function remove($selector = null)
2218
+	{
2219
+		$loop = $selector ? $this->filter($selector)->elements : $this->elements;
2220
+		foreach ($loop as $node) {
2221
+			if (!$node->parentNode)
2222
+				continue;
2223
+			if (isset($node->tagName))
2224
+				$this->debug("Removing '{$node->tagName}'");
2225
+			$node->parentNode->removeChild($node);
2226
+			// Mutation event
2227
+			$event = new Dom\DOMEvent(array(
2228
+									  'target' => $node,
2229
+									  'type'   => 'DOMNodeRemoved'
2230
+								  ));
2231
+			PhpQueryEvents::trigger(
2232
+				$this->getDocumentID(),
2233
+				$event->type,
2234
+				array(
2235
+					$event
2236
+				),
2237
+				$node
2238
+			);
2239
+		}
2240
+		return $this;
2241
+	}
2242
+
2243
+	protected function markupEvents($newMarkup, $oldMarkup, $node)
2244
+	{
2245
+		if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) {
2246
+			$event = new Dom\DOMEvent(array(
2247
+									  'target' => $node,
2248
+									  'type'   => 'change'
2249
+								  ));
2250
+			PhpQueryEvents::trigger(
2251
+				$this->getDocumentID(),
2252
+				$event->type,
2253
+				array(
2254
+					$event
2255
+				),
2256
+				$node
2257
+			);
2258
+		}
2259
+	}
2260
+
2261
+	/**
2262
+	 * jQuey difference
2263
+	 *
2264
+	 * @param      $markup
2265
+	 * @param null $callback1
2266
+	 * @param null $callback2
2267
+	 * @param null $callback3
2268
+	 * @return unknown_type
2269
+	 * @TODO trigger change event for textarea
2270
+	 */
2271
+	public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null)
2272
+	{
2273
+		$args = func_get_args();
2274
+		if ($this->documentWrapper->isXML)
2275
+			return call_user_func_array(
2276
+				array(
2277
+					$this,
2278
+					'xml'
2279
+				),
2280
+				$args
2281
+			);
2282
+		else
2283
+			return call_user_func_array(
2284
+				array(
2285
+					$this,
2286
+					'html'
2287
+				),
2288
+				$args
2289
+			);
2290
+	}
2291
+
2292
+	/**
2293
+	 * jQuey difference
2294
+	 *
2295
+	 * @param null $callback1
2296
+	 * @param null $callback2
2297
+	 * @param null $callback3
2298
+	 * @internal param $markup
2299
+	 * @return string
2300
+	 */
2301
+	public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
2302
+	{
2303
+		$args = func_get_args();
2304
+		if ($this->documentWrapper->isXML)
2305
+			return call_user_func_array(
2306
+				array(
2307
+					$this,
2308
+					'xmlOuter'
2309
+				),
2310
+				$args
2311
+			);
2312
+		else
2313
+			return call_user_func_array(
2314
+				array(
2315
+					$this,
2316
+					'htmlOuter'
2317
+				),
2318
+				$args
2319
+			);
2320
+	}
2321
+
2322
+	/**
2323
+	 * Enter description here...
2324
+	 *
2325
+	 * @param unknown_type $html
2326
+	 * @param null         $callback1
2327
+	 * @param null         $callback2
2328
+	 * @param null         $callback3
2329
+	 * @return string|PhpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2330
+	 * @TODO force html result
2331
+	 */
2332
+	public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null)
2333
+	{
2334
+		if (isset($html)) {
2335
+			// INSERT
2336
+			$nodes = $this->documentWrapper->import($html);
2337
+			$this->empty();
2338
+			foreach ($this->stack(1) as $alreadyAdded => $node) {
2339
+				// for now, limit events for textarea
2340
+				if (($this->isXHTML() || $this->isHTML())
2341
+					&& $node->tagName == 'textarea'
2342
+				)
2343
+					$oldHtml = pq($node, $this->getDocumentID())->markup();
2344
+				foreach ($nodes as $newNode) {
2345
+					$node->appendChild(
2346
+						$alreadyAdded ? $newNode->cloneNode(true)
2347
+							: $newNode
2348
+					);
2349
+				}
2350
+				// for now, limit events for textarea
2351
+				if (($this->isXHTML() || $this->isHTML())
2352
+					&& $node->tagName == 'textarea'
2353
+				)
2354
+					$this->markupEvents($html, $oldHtml, $node);
2355
+			}
2356
+			return $this;
2357
+		} else {
2358
+			// FETCH
2359
+			$return = $this->documentWrapper->markup($this->elements, true);
2360
+			$args   = func_get_args();
2361
+			foreach (array_slice($args, 1) as $callback) {
2362
+				$return = PhpQuery::callbackRun(
2363
+					$callback,
2364
+					array(
2365
+						$return
2366
+					)
2367
+				);
2368
+			}
2369
+			return $return;
2370
+		}
2371
+	}
2372
+
2373
+	/**
2374
+	 * @TODO force xml result
2375
+	 */
2376
+	public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null)
2377
+	{
2378
+		$args = func_get_args();
2379
+		return call_user_func_array(
2380
+			array(
2381
+				$this,
2382
+				'html'
2383
+			),
2384
+			$args
2385
+		);
2386
+	}
2387
+
2388
+	/**
2389
+	 * Enter description here...
2390
+	 * @TODO force html result
2391
+	 *
2392
+	 * @param null $callback1
2393
+	 * @param null $callback2
2394
+	 * @param null $callback3
2395
+	 * @return String
2396
+	 */
2397
+	public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
2398
+	{
2399
+		$markup = $this->documentWrapper->markup($this->elements);
2400
+		// pass thou callbacks
2401
+		$args = func_get_args();
2402
+		foreach ($args as $callback) {
2403
+			$markup = PhpQuery::callbackRun(
2404
+				$callback,
2405
+				array(
2406
+					$markup
2407
+				)
2408
+			);
2409
+		}
2410
+		return $markup;
2411
+	}
2412
+
2413
+	/**
2414
+	 * @TODO force xml result
2415
+	 */
2416
+	public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null)
2417
+	{
2418
+		$args = func_get_args();
2419
+		return call_user_func_array(
2420
+			array(
2421
+				$this,
2422
+				'htmlOuter'
2423
+			),
2424
+			$args
2425
+		);
2426
+	}
2427
+
2428
+	public function __toString()
2429
+	{
2430
+		return $this->markupOuter();
2431
+	}
2432
+
2433
+	/**
2434
+	 * Just like html(), but returns markup with VALID (dangerous) PHP tags.
2435
+	 *
2436
+	 * @param null $code
2437
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2438
+	 * @todo support returning markup with PHP tags when called without param
2439
+	 */
2440
+	public function php($code = null)
2441
+	{
2442
+		return $this->markupPHP($code);
2443
+	}
2444
+
2445
+	/**
2446
+	 * Enter description here...
2447
+	 *
2448
+	 * @param $code
2449
+	 * @return unknown_type
2450
+	 */
2451
+	public function markupPHP($code = null)
2452
+	{
2453
+		return isset($code) ? $this->markup(PhpQuery::php($code))
2454
+			: PhpQuery::markupToPHP($this->markup());
2455
+	}
2456
+
2457
+	/**
2458
+	 * Enter description here...
2459
+	 *
2460
+	 * @internal param $code
2461
+	 * @return string PHP code
2462
+	 */
2463
+	public function markupOuterPHP()
2464
+	{
2465
+		return PhpQuery::markupToPHP($this->markupOuter());
2466
+	}
2467
+
2468
+	/**
2469
+	 * Enter description here...
2470
+	 *
2471
+	 * @param null $selector
2472
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2473
+	 */
2474
+	public function children($selector = null)
2475
+	{
2476
+		$stack = array();
2477
+		foreach ($this->stack(1) as $node) {
2478
+			//			foreach($node->getElementsByTagName('*') as $newNode) {
2479
+			foreach ($node->childNodes as $newNode) {
2480
+				if ($newNode->nodeType != 1)
2481
+					continue;
2482
+				if ($selector && !$this->is($selector, $newNode))
2483
+					continue;
2484
+				if ($this->elementsContainsNode($newNode, $stack))
2485
+					continue;
2486
+				$stack[] = $newNode;
2487
+			}
2488
+		}
2489
+		$this->elementsBackup = $this->elements;
2490
+		$this->elements       = $stack;
2491
+		return $this->newInstance();
2492
+	}
2493
+
2494
+	/**
2495
+	 * Enter description here...
2496
+	 *
2497
+	 * @param null $selector
2498
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2499
+	 */
2500
+	public function ancestors($selector = null)
2501
+	{
2502
+		return $this->children($selector);
2503
+	}
2504
+
2505
+	/**
2506
+	 * Enter description here...
2507
+	 *
2508
+	 * @param $content
2509
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2510
+	 */
2511
+	public function append($content)
2512
+	{
2513
+		return $this->insert($content, __FUNCTION__);
2514
+	}
2515
+
2516
+	/**
2517
+	 * Enter description here...
2518
+	 *
2519
+	 * @param $content
2520
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2521
+	 */
2522
+	public function appendPHP($content)
2523
+	{
2524
+		return $this->insert("<php><!-- {$content} --></php>", 'append');
2525
+	}
2526
+
2527
+	/**
2528
+	 * Enter description here...
2529
+	 *
2530
+	 * @param $seletor
2531
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2532
+	 */
2533
+	public function appendTo($seletor)
2534
+	{
2535
+		return $this->insert($seletor, __FUNCTION__);
2536
+	}
2537
+
2538
+	/**
2539
+	 * Enter description here...
2540
+	 *
2541
+	 * @param $content
2542
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2543
+	 */
2544
+	public function prepend($content)
2545
+	{
2546
+		return $this->insert($content, __FUNCTION__);
2547
+	}
2548
+
2549
+	/**
2550
+	 * Enter description here...
2551
+	 *
2552
+	 * @todo accept many arguments, which are joined, arrays maybe also
2553
+	 * @param $content
2554
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2555
+	 */
2556
+	public function prependPHP($content)
2557
+	{
2558
+		return $this->insert("<php><!-- {$content} --></php>", 'prepend');
2559
+	}
2560
+
2561
+	/**
2562
+	 * Enter description here...
2563
+	 *
2564
+	 * @param $seletor
2565
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2566
+	 */
2567
+	public function prependTo($seletor)
2568
+	{
2569
+		return $this->insert($seletor, __FUNCTION__);
2570
+	}
2571
+
2572
+	/**
2573
+	 * Enter description here...
2574
+	 *
2575
+	 * @param $content
2576
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2577
+	 */
2578
+	public function before($content)
2579
+	{
2580
+		return $this->insert($content, __FUNCTION__);
2581
+	}
2582
+
2583
+	/**
2584
+	 * Enter description here...
2585
+	 *
2586
+	 * @param $content
2587
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2588
+	 */
2589
+	public function beforePHP($content)
2590
+	{
2591
+		return $this->insert("<php><!-- {$content} --></php>", 'before');
2592
+	}
2593
+
2594
+	/**
2595
+	 * Enter description here...
2596
+	 *
2597
+	 * @param String|PhpQuery
2598
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2599
+	 */
2600
+	public function insertBefore($seletor)
2601
+	{
2602
+		return $this->insert($seletor, __FUNCTION__);
2603
+	}
2604
+
2605
+	/**
2606
+	 * Enter description here...
2607
+	 *
2608
+	 * @param $content
2609
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2610
+	 */
2611
+	public function after($content)
2612
+	{
2613
+		return $this->insert($content, __FUNCTION__);
2614
+	}
2615
+
2616
+	/**
2617
+	 * Enter description here...
2618
+	 *
2619
+	 * @param $content
2620
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2621
+	 */
2622
+	public function afterPHP($content)
2623
+	{
2624
+		return $this->insert("<php><!-- {$content} --></php>", 'after');
2625
+	}
2626
+
2627
+	/**
2628
+	 * Enter description here...
2629
+	 *
2630
+	 * @param $seletor
2631
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2632
+	 */
2633
+	public function insertAfter($seletor)
2634
+	{
2635
+		return $this->insert($seletor, __FUNCTION__);
2636
+	}
2637
+
2638
+	/**
2639
+	 * Internal insert method. Don't use it.
2640
+	 *
2641
+	 * @param unknown_type $target
2642
+	 * @param unknown_type $type
2643
+	 * @throws \Exception
2644
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2645
+	 * @access private
2646
+	 */
2647
+	public function insert($target, $type)
2648
+	{
2649
+		$this->debug("Inserting data with '{$type}'");
2650
+		$to = false;
2651
+		switch ($type) {
2652
+			case 'appendTo':
2653
+			case 'prependTo':
2654
+			case 'insertBefore':
2655
+			case 'insertAfter':
2656
+				$to = true;
2657
+		}
2658
+		switch (gettype($target)) {
2659
+			case 'string':
2660
+				$insertFrom = $insertTo = array();
2661
+				if ($to) {
2662
+					// INSERT TO
2663
+					$insertFrom = $this->elements;
2664
+					if (PhpQuery::isMarkup($target)) {
2665
+						// $target is new markup, import it
2666
+						$insertTo = $this->documentWrapper->import($target);
2667
+						// insert into selected element
2668
+					} else {
2669
+						// $tagret is a selector
2670
+						$thisStack = $this->elements;
2671
+						$this->toRoot();
2672
+						$insertTo       = $this->find($target)->elements;
2673
+						$this->elements = $thisStack;
2674
+					}
2675
+				} else {
2676
+					// INSERT FROM
2677
+					$insertTo   = $this->elements;
2678
+					$insertFrom = $this->documentWrapper->import($target);
2679
+				}
2680
+				break;
2681
+			case 'object':
2682
+				$insertFrom = $insertTo = array();
2683
+				// PhpQuery
2684
+				if ($target instanceof self) {
2685
+					if ($to) {
2686
+						$insertTo = $target->elements;
2687
+						if ($this->documentFragment && $this->stackIsRoot())
2688
+							// get all body children
2689
+							//							$loop = $this->find('body > *')->elements;
2690
+							// TODO test it, test it hard...
2691
+							//							$loop = $this->newInstance($this->root)->find('> *')->elements;
2692
+							$loop = $this->root->childNodes;
2693
+						else
2694
+							$loop = $this->elements;
2695
+						// import nodes if needed
2696
+						$insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2697
+							: $target->documentWrapper->import($loop);
2698
+					} else {
2699
+						$insertTo = $this->elements;
2700
+						if ($target->documentFragment && $target->stackIsRoot())
2701
+							// get all body children
2702
+							//							$loop = $target->find('body > *')->elements;
2703
+							$loop = $target->root->childNodes;
2704
+						else
2705
+							$loop = $target->elements;
2706
+						// import nodes if needed
2707
+						$insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2708
+							: $this->documentWrapper->import($loop);
2709
+					}
2710
+					// DOMNODE
2711
+				} elseif ($target instanceof \DOMNODE) {
2712
+					// import node if needed
2713
+					//					if ( $target->ownerDocument != $this->DOM )
2714
+					//						$target = $this->DOM->importNode($target, true);
2715
+					if ($to) {
2716
+						$insertTo = array(
2717
+							$target
2718
+						);
2719
+						if ($this->documentFragment && $this->stackIsRoot())
2720
+							// get all body children
2721
+							$loop = $this->root->childNodes;
2722
+						//							$loop = $this->find('body > *')->elements;
2723
+						else
2724
+							$loop = $this->elements;
2725
+						foreach ($loop as $fromNode)
2726
+							// import nodes if needed
2727
+							$insertFrom[] = !$fromNode->ownerDocument->isSameNode(
2728
+								$target->ownerDocument
2729
+							) ? $target->ownerDocument->importNode($fromNode, true)
2730
+								: $fromNode;
2731
+					} else {
2732
+						// import node if needed
2733
+						if (!$target->ownerDocument->isSameNode($this->document))
2734
+							$target = $this->document->importNode($target, true);
2735
+						$insertTo     = $this->elements;
2736
+						$insertFrom[] = $target;
2737
+					}
2738
+				}
2739
+				break;
2740
+		}
2741
+		PhpQuery::debug(
2742
+			"From " . count($insertFrom) . "; To " . count($insertTo)
2743
+			. " nodes"
2744
+		);
2745
+		foreach ($insertTo as $insertNumber => $toNode) {
2746
+			// we need static relative elements in some cases
2747
+			switch ($type) {
2748
+				case 'prependTo':
2749
+				case 'prepend':
2750
+					$firstChild = $toNode->firstChild;
2751
+					break;
2752
+				case 'insertAfter':
2753
+				case 'after':
2754
+					$nextSibling = $toNode->nextSibling;
2755
+					break;
2756
+			}
2757
+			foreach ($insertFrom as $fromNode) {
2758
+				// clone if inserted already before
2759
+				$insert = $insertNumber ? $fromNode->cloneNode(true) : $fromNode;
2760
+				switch ($type) {
2761
+					case 'appendTo':
2762
+					case 'append':
2763
+						//						$toNode->insertBefore(
2764
+						//							$fromNode,
2765
+						//							$toNode->lastChild->nextSibling
2766
+						//						);
2767
+						$toNode->appendChild($insert);
2768
+						$eventTarget = $insert;
2769
+						break;
2770
+					case 'prependTo':
2771
+					case 'prepend':
2772
+						$toNode->insertBefore($insert, $firstChild);
2773
+						break;
2774
+					case 'insertBefore':
2775
+					case 'before':
2776
+						if (!$toNode->parentNode)
2777
+							throw new \Exception("No parentNode, can't do {$type}()");
2778
+						else
2779
+							$toNode->parentNode->insertBefore($insert, $toNode);
2780
+						break;
2781
+					case 'insertAfter':
2782
+					case 'after':
2783
+						if (!$toNode->parentNode)
2784
+							throw new \Exception("No parentNode, can't do {$type}()");
2785
+						else
2786
+							$toNode->parentNode->insertBefore($insert, $nextSibling);
2787
+						break;
2788
+				}
2789
+				// Mutation event
2790
+				$event = new Dom\DOMEvent(array(
2791
+											  'target' => $insert,
2792
+											  'type'   => 'DOMNodeInserted'
2793
+										  ));
2794
+				PhpQueryEvents::trigger(
2795
+					$this->getDocumentID(),
2796
+					$event->type,
2797
+					array(
2798
+						$event
2799
+					),
2800
+					$insert
2801
+				);
2802
+			}
2803
+		}
2804
+		return $this;
2805
+	}
2806
+
2807
+	/**
2808
+	 * Enter description here...
2809
+	 *
2810
+	 * @param $subject
2811
+	 * @return Int
2812
+	 */
2813
+	public function index($subject)
2814
+	{
2815
+		$index   = -1;
2816
+		$subject = $subject instanceof PhpQueryObject ? $subject->elements[0]
2817
+			: $subject;
2818
+		foreach ($this->newInstance() as $k => $node) {
2819
+			if ($node->isSameNode($subject))
2820
+				$index = $k;
2821
+		}
2822
+		return $index;
2823
+	}
2824
+
2825
+	/**
2826
+	 * Enter description here...
2827
+	 *
2828
+	 * @param unknown_type $start
2829
+	 * @param unknown_type $end
2830
+	 *
2831
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2832
+	 * @testme
2833
+	 */
2834
+	public function slice($start, $end = null)
2835
+	{
2836
+		//		$last = count($this->elements)-1;
2837
+		//		$end = $end
2838
+		//			? min($end, $last)
2839
+		//			: $last;
2840
+		//		if ($start < 0)
2841
+		//			$start = $last+$start;
2842
+		//		if ($start > $last)
2843
+		//			return array();
2844
+		if ($end > 0)
2845
+			$end = $end - $start;
2846
+		return $this->newInstance(array_slice($this->elements, $start, $end));
2847
+	}
2848
+
2849
+	/**
2850
+	 * Enter description here...
2851
+	 *
2852
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2853
+	 */
2854
+	public function reverse()
2855
+	{
2856
+		$this->elementsBackup = $this->elements;
2857
+		$this->elements       = array_reverse($this->elements);
2858
+		return $this->newInstance();
2859
+	}
2860
+
2861
+	/**
2862
+	 * Return joined text content.
2863
+	 * @param null $text
2864
+	 * @param null $callback1
2865
+	 * @param null $callback2
2866
+	 * @param null $callback3
2867
+	 * @return String
2868
+	 */
2869
+	public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null)
2870
+	{
2871
+		if (isset($text))
2872
+			return $this->html(htmlspecialchars($text));
2873
+		$args   = func_get_args();
2874
+		$args   = array_slice($args, 1);
2875
+		$return = '';
2876
+		foreach ($this->elements as $node) {
2877
+			$text = $node->textContent;
2878
+			if (count($this->elements) > 1 && $text)
2879
+				$text .= "\n";
2880
+			foreach ($args as $callback) {
2881
+				$text = PhpQuery::callbackRun(
2882
+					$callback,
2883
+					array(
2884
+						$text
2885
+					)
2886
+				);
2887
+			}
2888
+			$return .= $text;
2889
+		}
2890
+		return $return;
2891
+	}
2892
+
2893
+	/**
2894
+	 * @param null $attr
2895
+	 * @return The text content of each matching element, like
2896
+	 * text() but returns an array with one entry per matched element.
2897
+	 * Read only.
2898
+	 */
2899
+	public function texts($attr = null)
2900
+	{
2901
+		$results = array();
2902
+		foreach ($this->elements as $node) {
2903
+			$results[] = $node->textContent;
2904
+		}
2905
+		return $results;
2906
+	}
2907
+
2908
+	/**
2909
+	 * Enter description here...
2910
+	 *
2911
+	 * @param      $class
2912
+	 * @param null $file
2913
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2914
+	 */
2915
+	public function plugin($class, $file = null)
2916
+	{
2917
+		PhpQuery::plugin($class, $file);
2918
+		return $this;
2919
+	}
2920
+
2921
+	/**
2922
+	 * Deprecated, use $pq->plugin() instead.
2923
+	 *
2924
+	 * @deprecated
2925
+	 * @param $class
2926
+	 * @param $file
2927
+	 * @return unknown_type
2928
+	 */
2929
+	public static function extend($class, $file = null)
2930
+	{
2931
+		return self::plugin($class, $file);
2932
+	}
2933
+
2934
+	/**
2935
+	 *
2936
+	 * @access private
2937
+	 * @param $method
2938
+	 * @param $args
2939
+	 * @throws \Exception
2940
+	 * @return unknown_type
2941
+	 */
2942
+	public function __call($method, $args)
2943
+	{
2944
+		$aliasMethods = array(
2945
+			'clone',
2946
+			'empty'
2947
+		);
2948
+		if (isset(PhpQuery::$extendMethods[$method])) {
2949
+			array_unshift($args, $this);
2950
+			return PhpQuery::callbackRun(PhpQuery::$extendMethods[$method], $args);
2951
+		} else if (isset(PhpQuery::$pluginsMethods[$method])) {
2952
+			array_unshift($args, $this);
2953
+			$class     = PhpQuery::$pluginsMethods[$method];
2954
+			$realClass = "\\PhpQuery\\Plugin\\$class";
2955
+			$return    = call_user_func_array(
2956
+				array(
2957
+					$realClass,
2958
+					$method
2959
+				),
2960
+				$args
2961
+			);
2962
+			// XXX deprecate ?
2963
+			return is_null($return) ? $this : $return;
2964
+		} else if (in_array($method, $aliasMethods)) {
2965
+			return call_user_func_array(
2966
+				array(
2967
+					$this,
2968
+					'_' . $method
2969
+				),
2970
+				$args
2971
+			);
2972
+		} else
2973
+			throw new \Exception("Method '{$method}' doesnt exist");
2974
+	}
2975
+
2976
+	/**
2977
+	 * Safe rename of next().
2978
+	 *
2979
+	 * Use it ONLY when need to call next() on an iterated object (in same time).
2980
+	 * Normaly there is no need to do such thing ;)
2981
+	 *
2982
+	 * @param null $selector
2983
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2984
+	 * @access private
2985
+	 */
2986
+	public function _next($selector = null)
2987
+	{
2988
+		return $this->newInstance($this->getElementSiblings('nextSibling', $selector, true));
2989
+	}
2990
+
2991
+	/**
2992
+	 * Use prev() and next().
2993
+	 *
2994
+	 * @deprecated
2995
+	 * @param null $selector
2996
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
2997
+	 * @access private
2998
+	 */
2999
+	public function _prev($selector = null)
3000
+	{
3001
+		return $this->prev($selector);
3002
+	}
3003
+
3004
+	/**
3005
+	 * Enter description here...
3006
+	 *
3007
+	 * @param null $selector
3008
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3009
+	 */
3010
+	public function prev($selector = null)
3011
+	{
3012
+		return $this->newInstance($this->getElementSiblings('previousSibling', $selector, true));
3013
+	}
3014
+
3015
+	/**
3016
+	 * @param null $selector
3017
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3018
+	 * @todo
3019
+	 */
3020
+	public function prevAll($selector = null)
3021
+	{
3022
+		return $this->newInstance($this->getElementSiblings('previousSibling', $selector));
3023
+	}
3024
+
3025
+	/**
3026
+	 * @param null $selector
3027
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3028
+	 * @todo FIXME: returns source elements insted of next siblings
3029
+	 */
3030
+	public function nextAll($selector = null)
3031
+	{
3032
+		return $this->newInstance($this->getElementSiblings('nextSibling', $selector));
3033
+	}
3034
+
3035
+	/**
3036
+	 * @access private
3037
+	 */
3038
+	protected function getElementSiblings($direction, $selector = null, $limitToOne = false)
3039
+	{
3040
+		$stack = array();
3041
+		$count = 0;
3042
+		foreach ($this->stack() as $node) {
3043
+			$test = $node;
3044
+			while (isset($test->{$direction}) && $test->{$direction}) {
3045
+				$test = $test->{$direction};
3046
+				if (!$test instanceof \DOMElement)
3047
+					continue;
3048
+				$stack[] = $test;
3049
+				if ($limitToOne)
3050
+					break;
3051
+			}
3052
+		}
3053
+		if ($selector) {
3054
+			$stackOld       = $this->elements;
3055
+			$this->elements = $stack;
3056
+			$stack          = $this->filter($selector, true)->stack();
3057
+			$this->elements = $stackOld;
3058
+		}
3059
+		return $stack;
3060
+	}
3061
+
3062
+	/**
3063
+	 * Enter description here...
3064
+	 *
3065
+	 * @param null $selector
3066
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3067
+	 */
3068
+	public function siblings($selector = null)
3069
+	{
3070
+		$stack    = array();
3071
+		$siblings = array_merge(
3072
+			$this->getElementSiblings('previousSibling', $selector),
3073
+			$this->getElementSiblings('nextSibling', $selector)
3074
+		);
3075
+		foreach ($siblings as $node) {
3076
+			if (!$this->elementsContainsNode($node, $stack))
3077
+				$stack[] = $node;
3078
+		}
3079
+		return $this->newInstance($stack);
3080
+	}
3081
+
3082
+	/**
3083
+	 * Enter description here...
3084
+	 *
3085
+	 * @param null $selector
3086
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3087
+	 */
3088
+	public function not($selector = null)
3089
+	{
3090
+		if (is_string($selector))
3091
+			PhpQuery::debug(
3092
+				array(
3093
+					'not',
3094
+					$selector
3095
+				)
3096
+			);
3097
+		else
3098
+			PhpQuery::debug('not');
3099
+		$stack = array();
3100
+		if ($selector instanceof self || $selector instanceof \DOMNODE) {
3101
+			foreach ($this->stack() as $node) {
3102
+				if ($selector instanceof self) {
3103
+					$matchFound = false;
3104
+					foreach ($selector->stack() as $notNode) {
3105
+						if ($notNode->isSameNode($node))
3106
+							$matchFound = true;
3107
+					}
3108
+					if (!$matchFound)
3109
+						$stack[] = $node;
3110
+				} else if ($selector instanceof \DOMNODE) {
3111
+					if (!$selector->isSameNode($node))
3112
+						$stack[] = $node;
3113
+				} else {
3114
+					if (!$this->is($selector))
3115
+						$stack[] = $node;
3116
+				}
3117
+			}
3118
+		} else {
3119
+			$orgStack = $this->stack();
3120
+			$matched  = $this->filter($selector, true)->stack();
3121
+			//			$matched = array();
3122
+			//			// simulate OR in filter() instead of AND 5y
3123
+			//			foreach($this->parseSelector($selector) as $s) {
3124
+			//				$matched = array_merge($matched,
3125
+			//					$this->filter(array($s))->stack()
3126
+			//				);
3127
+			//			}
3128
+			foreach ($orgStack as $node)
3129
+				if (!$this->elementsContainsNode($node, $matched))
3130
+					$stack[] = $node;
3131
+		}
3132
+		return $this->newInstance($stack);
3133
+	}
3134
+
3135
+	/**
3136
+	 * Enter description here...
3137
+	 *
3138
+	 * @param string|PhpQueryObject
3139
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3140
+	 */
3141
+	public function add($selector = null)
3142
+	{
3143
+		if (!$selector)
3144
+			return $this;
3145
+		$stack                = array();
3146
+		$this->elementsBackup = $this->elements;
3147
+		$found                = PhpQuery::pq($selector, $this->getDocumentID());
3148
+		$this->merge($found->elements);
3149
+		return $this->newInstance();
3150
+	}
3151
+
3152
+	/**
3153
+	 * @access private
3154
+	 */
3155
+	protected function merge()
3156
+	{
3157
+		foreach (func_get_args() as $nodes)
3158
+			foreach ($nodes as $newNode)
3159
+				if (!$this->elementsContainsNode($newNode))
3160
+					$this->elements[] = $newNode;
3161
+	}
3162
+
3163
+	/**
3164
+	 * @access private
3165
+	 * TODO refactor to stackContainsNode
3166
+	 */
3167
+	protected function elementsContainsNode($nodeToCheck, $elementsStack = null)
3168
+	{
3169
+		$loop = !is_null($elementsStack) ? $elementsStack : $this->elements;
3170
+		foreach ($loop as $node) {
3171
+			if ($node->isSameNode($nodeToCheck))
3172
+				return true;
3173
+		}
3174
+		return false;
3175
+	}
3176
+
3177
+	/**
3178
+	 * Enter description here...
3179
+	 *
3180
+	 * @param null $selector
3181
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3182
+	 */
3183
+	public function parent($selector = null)
3184
+	{
3185
+		$stack = array();
3186
+		foreach ($this->elements as $node)
3187
+			if ($node->parentNode
3188
+				&& !$this->elementsContainsNode($node->parentNode, $stack)
3189
+			)
3190
+				$stack[] = $node->parentNode;
3191
+		$this->elementsBackup = $this->elements;
3192
+		$this->elements       = $stack;
3193
+		if ($selector)
3194
+			$this->filter($selector, true);
3195
+		return $this->newInstance();
3196
+	}
3197
+
3198
+	/**
3199
+	 * Enter description here...
3200
+	 *
3201
+	 * @param null $selector
3202
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3203
+	 */
3204
+	public function parents($selector = null)
3205
+	{
3206
+		$stack = array();
3207
+		if (!$this->elements)
3208
+			$this->debug('parents() - stack empty');
3209
+		foreach ($this->elements as $node) {
3210
+			$test = $node;
3211
+			while ($test->parentNode) {
3212
+				$test = $test->parentNode;
3213
+				if ($this->isRoot($test))
3214
+					break;
3215
+				if (!$this->elementsContainsNode($test, $stack)) {
3216
+					$stack[] = $test;
3217
+					continue;
3218
+				}
3219
+			}
3220
+		}
3221
+		$this->elementsBackup = $this->elements;
3222
+		$this->elements       = $stack;
3223
+		if ($selector)
3224
+			$this->filter($selector, true);
3225
+		return $this->newInstance();
3226
+	}
3227
+
3228
+	/**
3229
+	 * Internal stack iterator.
3230
+	 *
3231
+	 * @access private
3232
+	 * @param null $nodeTypes
3233
+	 * @return array {Array.<DOMNode>}
3234
+	 */
3235
+	public function stack($nodeTypes = null)
3236
+	{
3237
+		if (!isset($nodeTypes))
3238
+			return $this->elements;
3239
+		if (!is_array($nodeTypes))
3240
+			$nodeTypes = array(
3241
+				$nodeTypes
3242
+			);
3243
+		$return = array();
3244
+		foreach ($this->elements as $node) {
3245
+			if (in_array($node->nodeType, $nodeTypes))
3246
+				$return[] = $node;
3247
+		}
3248
+		return $return;
3249
+	}
3250
+
3251
+	// TODO phpdoc; $oldAttr is result of hasAttribute, before any changes
3252
+	protected function attrEvents($attr, $oldAttr, $oldValue, $node)
3253
+	{
3254
+		// skip events for XML documents
3255
+		if (!$this->isXHTML() && !$this->isHTML())
3256
+			return;
3257
+		$event = null;
3258
+		// identify
3259
+		$isInputValue = $node->tagName == 'input'
3260
+			&& (in_array(
3261
+					$node->getAttribute('type'),
3262
+					array(
3263
+						'text',
3264
+						'password',
3265
+						'hidden'
3266
+					)
3267
+				) || !$node->getAttribute('type'));
3268
+		$isRadio      = $node->tagName == 'input'
3269
+			&& $node->getAttribute('type') == 'radio';
3270
+		$isCheckbox   = $node->tagName == 'input'
3271
+			&& $node->getAttribute('type') == 'checkbox';
3272
+		$isOption     = $node->tagName == 'option';
3273
+		if ($isInputValue && $attr == 'value'
3274
+			&& $oldValue != $node->getAttribute($attr)
3275
+		) {
3276
+			$event = new Dom\DOMEvent(array(
3277
+										  'target' => $node,
3278
+										  'type'   => 'change'
3279
+									  ));
3280
+		} else if (($isRadio || $isCheckbox) && $attr == 'checked'
3281
+			&& (
3282
+				// check
3283
+				(!$oldAttr && $node->hasAttribute($attr))
3284
+				// un-check
3285
+				|| (!$node->hasAttribute($attr) && $oldAttr))
3286
+		) {
3287
+			$event = new Dom\DOMEvent(array(
3288
+										  'target' => $node,
3289
+										  'type'   => 'change'
3290
+									  ));
3291
+		} else if ($isOption && $node->parentNode && $attr == 'selected'
3292
+			&& (
3293
+				// select
3294
+				(!$oldAttr && $node->hasAttribute($attr))
3295
+				// un-select
3296
+				|| (!$node->hasAttribute($attr) && $oldAttr))
3297
+		) {
3298
+			$event = new Dom\DOMEvent(array(
3299
+										  'target' => $node->parentNode,
3300
+										  'type'   => 'change'
3301
+									  ));
3302
+		}
3303
+		if ($event) {
3304
+			PhpQueryEvents::trigger(
3305
+				$this->getDocumentID(),
3306
+				$event->type,
3307
+				array(
3308
+					$event
3309
+				),
3310
+				$node
3311
+			);
3312
+		}
3313
+	}
3314
+
3315
+	public function attr($attr = null, $value = null)
3316
+	{
3317
+		foreach ($this->stack(1) as $node) {
3318
+			if (!is_null($value)) {
3319
+				$loop = $attr == '*' ? $this->getNodeAttrs($node)
3320
+					: array(
3321
+						$attr
3322
+					);
3323
+				foreach ($loop as $a) {
3324
+					$oldValue = $node->getAttribute($a);
3325
+					$oldAttr  = $node->hasAttribute($a);
3326
+					// TODO raises an error when charset other than UTF-8
3327
+					// while document's charset is also not UTF-8
3328
+					@$node->setAttribute($a, $value);
3329
+					$this->attrEvents($a, $oldAttr, $oldValue, $node);
3330
+				}
3331
+			} else if ($attr == '*') {
3332
+				// jQuery difference
3333
+				$return = array();
3334
+				foreach ($node->attributes as $n => $v)
3335
+					$return[$n] = $v->value;
3336
+				return $return;
3337
+			} else
3338
+				return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null;
3339
+		}
3340
+		return is_null($value) ? '' : $this;
3341
+	}
3342
+
3343
+	/**
3344
+	 * @param null $attr
3345
+	 * @return The same attribute of each matching element, like
3346
+	 * attr() but returns an array with one entry per matched element.
3347
+	 * Read only.
3348
+	 */
3349
+	public function attrs($attr = null)
3350
+	{
3351
+		$results = array();
3352
+		foreach ($this->stack(1) as $node) {
3353
+			$results[] = $node->hasAttribute($attr) ? $node->getAttribute($attr)
3354
+				: null;
3355
+		}
3356
+		return $results;
3357
+	}
3358
+
3359
+	/**
3360
+	 * @access private
3361
+	 */
3362
+	protected function getNodeAttrs($node)
3363
+	{
3364
+		$return = array();
3365
+		foreach ($node->attributes as $n => $o)
3366
+			$return[] = $n;
3367
+		return $return;
3368
+	}
3369
+
3370
+	/**
3371
+	 * Enter description here...
3372
+	 *
3373
+	 * @param $attr
3374
+	 * @param $code
3375
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3376
+	 * @todo check CDATA ???
3377
+	 */
3378
+	public function attrPHP($attr, $code)
3379
+	{
3380
+		if (!is_null($code)) {
3381
+			$value = '<' . '?php ' . $code . ' ?' . '>';
3382
+			// TODO tempolary solution
3383
+			// http://code.google.com/p/phpquery/issues/detail?id=17
3384
+			//			if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII')
3385
+			//				$value	= mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES');
3386
+		}
3387
+		foreach ($this->stack(1) as $node) {
3388
+			if (!is_null($code)) {
3389
+				//				$attrNode = $this->DOM->createAttribute($attr);
3390
+				$node->setAttribute($attr, $value);
3391
+				//				$attrNode->value = $value;
3392
+				//				$node->appendChild($attrNode);
3393
+			} else if ($attr == '*') {
3394
+				// jQuery diff
3395
+				$return = array();
3396
+				foreach ($node->attributes as $n => $v)
3397
+					$return[$n] = $v->value;
3398
+				return $return;
3399
+			} else
3400
+				return $node->getAttribute($attr);
3401
+		}
3402
+		return $this;
3403
+	}
3404
+
3405
+	/**
3406
+	 * Enter description here...
3407
+	 *
3408
+	 * @param $attr
3409
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3410
+	 */
3411
+	public function removeAttr($attr)
3412
+	{
3413
+		foreach ($this->stack(1) as $node) {
3414
+			$loop = $attr == '*' ? $this->getNodeAttrs($node)
3415
+				: array(
3416
+					$attr
3417
+				);
3418
+			foreach ($loop as $a) {
3419
+				$oldValue = $node->getAttribute($a);
3420
+				$node->removeAttribute($a);
3421
+				$this->attrEvents($a, $oldValue, null, $node);
3422
+			}
3423
+		}
3424
+		return $this;
3425
+	}
3426
+
3427
+	/**
3428
+	 * Return form element value.
3429
+	 *
3430
+	 * @param null $val
3431
+	 * @return String Fields value.
3432
+	 */
3433
+	public function val($val = null)
3434
+	{
3435
+		if (!isset($val)) {
3436
+			if ($this->eq(0)->is('select')) {
3437
+				$selected = $this->eq(0)->find('option[selected=selected]');
3438
+				if ($selected->is('[value]'))
3439
+					return $selected->attr('value');
3440
+				else
3441
+					return $selected->text();
3442
+			} else if ($this->eq(0)->is('textarea'))
3443
+				return $this->eq(0)->markup();
3444
+			else
3445
+				return $this->eq(0)->attr('value');
3446
+		} else {
3447
+			$_val = null;
3448
+			foreach ($this->stack(1) as $node) {
3449
+				$node = pq($node, $this->getDocumentID());
3450
+				if (is_array($val)
3451
+					&& in_array(
3452
+						$node->attr('type'),
3453
+						array(
3454
+							'checkbox',
3455
+							'radio'
3456
+						)
3457
+					)
3458
+				) {
3459
+					$isChecked = in_array($node->attr('value'), $val)
3460
+						|| in_array($node->attr('name'), $val);
3461
+					if ($isChecked)
3462
+						$node->attr('checked', 'checked');
3463
+					else
3464
+						$node->removeAttr('checked');
3465
+				} else if ($node->get(0)->tagName == 'select') {
3466
+					if (!isset($_val)) {
3467
+						$_val = array();
3468
+						if (!is_array($val))
3469
+							$_val = array(
3470
+								(string) $val
3471
+							);
3472
+						else
3473
+							foreach ($val as $v)
3474
+								$_val[] = $v;
3475
+					}
3476
+					foreach ($node['option']->stack(1) as $option) {
3477
+						$option   = pq($option, $this->getDocumentID());
3478
+						$selected = false;
3479
+						// XXX: workaround for string comparsion, see issue #96
3480
+						// http://code.google.com/p/phpquery/issues/detail?id=96
3481
+						$selected = is_null($option->attr('value')) ? in_array($option->markup(), $_val)
3482
+							: in_array($option->attr('value'), $_val);
3483
+						//						$optionValue = $option->attr('value');
3484
+						//						$optionText = $option->text();
3485
+						//						$optionTextLenght = mb_strlen($optionText);
3486
+						//						foreach($_val as $v)
3487
+						//							if ($optionValue == $v)
3488
+						//								$selected = true;
3489
+						//							else if ($optionText == $v && $optionTextLenght == mb_strlen($v))
3490
+						//								$selected = true;
3491
+						if ($selected)
3492
+							$option->attr('selected', 'selected');
3493
+						else
3494
+							$option->removeAttr('selected');
3495
+					}
3496
+				} else if ($node->get(0)->tagName == 'textarea')
3497
+					$node->markup($val);
3498
+				else
3499
+					$node->attr('value', $val);
3500
+			}
3501
+		}
3502
+		return $this;
3503
+	}
3504
+
3505
+	/**
3506
+	 * Enter description here...
3507
+	 *
3508
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3509
+	 */
3510
+	public function andSelf()
3511
+	{
3512
+		if ($this->previous)
3513
+			$this->elements = array_merge($this->elements, $this->previous->elements);
3514
+		return $this;
3515
+	}
3516
+
3517
+	/**
3518
+	 * Enter description here...
3519
+	 *
3520
+	 * @param $className
3521
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3522
+	 */
3523
+	public function addClass($className)
3524
+	{
3525
+		if (!$className)
3526
+			return $this;
3527
+		foreach ($this->stack(1) as $node) {
3528
+			if (!$this->is(".$className", $node))
3529
+				$node->setAttribute(
3530
+					'class',
3531
+					trim(
3532
+						$node->getAttribute('class') . ' '
3533
+						. $className
3534
+					)
3535
+				);
3536
+		}
3537
+		return $this;
3538
+	}
3539
+
3540
+	/**
3541
+	 * Enter description here...
3542
+	 *
3543
+	 * @param $className
3544
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3545
+	 */
3546
+	public function addClassPHP($className)
3547
+	{
3548
+		foreach ($this->stack(1) as $node) {
3549
+			$classes  = $node->getAttribute('class');
3550
+			$newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?'
3551
+				. '>' : '<' . '?php ' . $className . ' ?' . '>';
3552
+			$node->setAttribute('class', $newValue);
3553
+		}
3554
+		return $this;
3555
+	}
3556
+
3557
+	/**
3558
+	 * Enter description here...
3559
+	 *
3560
+	 * @param    string $className
3561
+	 * @return    bool
3562
+	 */
3563
+	public function hasClass($className)
3564
+	{
3565
+		foreach ($this->stack(1) as $node) {
3566
+			if ($this->is(".$className", $node))
3567
+				return true;
3568
+		}
3569
+		return false;
3570
+	}
3571
+
3572
+	/**
3573
+	 * Enter description here...
3574
+	 *
3575
+	 * @param $className
3576
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3577
+	 */
3578
+	public function removeClass($className)
3579
+	{
3580
+		foreach ($this->stack(1) as $node) {
3581
+			$classes = explode(' ', $node->getAttribute('class'));
3582
+			if (in_array($className, $classes)) {
3583
+				$classes = array_diff(
3584
+					$classes,
3585
+					array(
3586
+						$className
3587
+					)
3588
+				);
3589
+				if ($classes)
3590
+					$node->setAttribute('class', implode(' ', $classes));
3591
+				else
3592
+					$node->removeAttribute('class');
3593
+			}
3594
+		}
3595
+		return $this;
3596
+	}
3597
+
3598
+	/**
3599
+	 * Enter description here...
3600
+	 *
3601
+	 * @param $className
3602
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3603
+	 */
3604
+	public function toggleClass($className)
3605
+	{
3606
+		foreach ($this->stack(1) as $node) {
3607
+			if ($this->is($node, '.' . $className))
3608
+				$this->removeClass($className);
3609
+			else
3610
+				$this->addClass($className);
3611
+		}
3612
+		return $this;
3613
+	}
3614
+
3615
+	/**
3616
+	 * Proper name without underscore (just ->empty()) also works.
3617
+	 *
3618
+	 * Removes all child nodes from the set of matched elements.
3619
+	 *
3620
+	 * Example:
3621
+	 * pq("p")._empty()
3622
+	 *
3623
+	 * HTML:
3624
+	 * <p>Hello, <span>Person</span> <a href="#">and person</a></p>
3625
+	 *
3626
+	 * Result:
3627
+	 * [ <p></p> ]
3628
+	 *
3629
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3630
+	 * @access private
3631
+	 */
3632
+	public function _empty()
3633
+	{
3634
+		foreach ($this->stack(1) as $node) {
3635
+			// thx to 'dave at dgx dot cz'
3636
+			$node->nodeValue = '';
3637
+		}
3638
+		return $this;
3639
+	}
3640
+
3641
+	/**
3642
+	 * Enter description here...
3643
+	 *
3644
+	 * @param array|string $callback Expects $node as first param, $index as second
3645
+	 * @param null         $param1
3646
+	 * @param null         $param2
3647
+	 * @param null         $param3
3648
+	 * @internal param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope)
3649
+	 * @internal param array $arg1 Will ba passed as third and futher args to callback.
3650
+	 * @internal param array $arg2 Will ba passed as fourth and futher args to callback, and so on...
3651
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3652
+	 */
3653
+	public function each($callback, $param1 = null, $param2 = null, $param3 = null)
3654
+	{
3655
+		$paramStructure = null;
3656
+		if (func_num_args() > 1) {
3657
+			$paramStructure = func_get_args();
3658
+			$paramStructure = array_slice($paramStructure, 1);
3659
+		}
3660
+		foreach ($this->elements as $v)
3661
+			PhpQuery::callbackRun(
3662
+				$callback,
3663
+				array(
3664
+					$v
3665
+				),
3666
+				$paramStructure
3667
+			);
3668
+		return $this;
3669
+	}
3670
+
3671
+	/**
3672
+	 * Run callback on actual object.
3673
+	 *
3674
+	 * @param      $callback
3675
+	 * @param null $param1
3676
+	 * @param null $param2
3677
+	 * @param null $param3
3678
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3679
+	 */
3680
+	public function callback($callback, $param1 = null, $param2 = null, $param3 = null)
3681
+	{
3682
+		$params    = func_get_args();
3683
+		$params[0] = $this;
3684
+		PhpQuery::callbackRun($callback, $params);
3685
+		return $this;
3686
+	}
3687
+
3688
+	/**
3689
+	 * Enter description here...
3690
+	 *
3691
+	 * @param      $callback
3692
+	 * @param null $param1
3693
+	 * @param null $param2
3694
+	 * @param null $param3
3695
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3696
+	 * @todo add $scope and $args as in each() ???
3697
+	 */
3698
+	public function map($callback, $param1 = null, $param2 = null, $param3 = null)
3699
+	{
3700
+		//		$stack = array();
3701
+		////		foreach($this->newInstance() as $node) {
3702
+		//		foreach($this->newInstance() as $node) {
3703
+		//			$result = call_user_func($callback, $node);
3704
+		//			if ($result)
3705
+		//				$stack[] = $result;
3706
+		//		}
3707
+		$params = func_get_args();
3708
+		array_unshift($params, $this->elements);
3709
+		return $this->newInstance(
3710
+			call_user_func_array(
3711
+				array(
3712
+					'\\PhpQuery\\PhpQuery',
3713
+					'map'
3714
+				),
3715
+				$params
3716
+			)
3717
+		//			PhpQuery::map($this->elements, $callback)
3718
+		);
3719
+	}
3720
+
3721
+	/**
3722
+	 * Enter description here...
3723
+	 *
3724
+	 * @param <type> $key
3725
+	 * @param <type> $value
3726
+	 * @return $this
3727
+	 */
3728
+	public function data($key, $value = null)
3729
+	{
3730
+		if (!isset($value)) {
3731
+			// TODO? implement specific jQuery behavior od returning parent values
3732
+			// is child which we look up doesn't exist
3733
+			return PhpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
3734
+		} else {
3735
+			foreach ($this as $node)
3736
+				PhpQuery::data($node, $key, $value, $this->getDocumentID());
3737
+			return $this;
3738
+		}
3739
+	}
3740
+
3741
+	/**
3742
+	 * Enter description here...
3743
+	 *
3744
+	 * @param <type> $key
3745
+	 * @return $this
3746
+	 */
3747
+	public function removeData($key)
3748
+	{
3749
+		foreach ($this as $node)
3750
+			PhpQuery::removeData($node, $key, $this->getDocumentID());
3751
+		return $this;
3752
+	}
3753
+	// INTERFACE IMPLEMENTATIONS
3754
+
3755
+	// ITERATOR INTERFACE
3756
+	/**
3757
+	 * @access private
3758
+	 */
3759
+	public function rewind()
3760
+	{
3761
+		$this->debug('iterating foreach');
3762
+		//		PhpQuery::selectDocument($this->getDocumentID());
3763
+		$this->elementsBackup    = $this->elements;
3764
+		$this->elementsInterator = $this->elements;
3765
+		$this->valid             = isset($this->elements[0]) ? 1 : 0;
3766
+		// 		$this->elements = $this->valid
3767
+		// 			? array($this->elements[0])
3768
+		// 			: array();
3769
+		$this->current = 0;
3770
+	}
3771
+
3772
+	/**
3773
+	 * @access private
3774
+	 */
3775
+	public function current()
3776
+	{
3777
+		return $this->elementsInterator[$this->current];
3778
+	}
3779
+
3780
+	/**
3781
+	 * @access private
3782
+	 */
3783
+	public function key()
3784
+	{
3785
+		return $this->current;
3786
+	}
3787
+
3788
+	/**
3789
+	 * Double-function method.
3790
+	 *
3791
+	 * First: main iterator interface method.
3792
+	 * Second: Returning next sibling, alias for _next().
3793
+	 *
3794
+	 * Proper functionality is choosed automagicaly.
3795
+	 *
3796
+	 * @see PhpQueryObject::_next()
3797
+	 * @param null $cssSelector
3798
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3799
+	 */
3800
+	public function next($cssSelector = null)
3801
+	{
3802
+		//		if ($cssSelector || $this->valid)
3803
+		//			return $this->_next($cssSelector);
3804
+		$this->valid = isset($this->elementsInterator[$this->current + 1]) ? true
3805
+			: false;
3806
+		if (!$this->valid && $this->elementsInterator) {
3807
+			$this->elementsInterator = null;
3808
+		} else if ($this->valid) {
3809
+			$this->current++;
3810
+		} else {
3811
+			return $this->_next($cssSelector);
3812
+		}
3813
+	}
3814
+
3815
+	/**
3816
+	 * @access private
3817
+	 */
3818
+	public function valid()
3819
+	{
3820
+		return $this->valid;
3821
+	}
3822
+	// ITERATOR INTERFACE END
3823
+	// ARRAYACCESS INTERFACE
3824
+	/**
3825
+	 * @access private
3826
+	 */
3827
+	public function offsetExists($offset)
3828
+	{
3829
+		return $this->find($offset)->size() > 0;
3830
+	}
3831
+
3832
+	/**
3833
+	 * @access private
3834
+	 */
3835
+	public function offsetGet($offset)
3836
+	{
3837
+		return $this->find($offset);
3838
+	}
3839
+
3840
+	/**
3841
+	 * @access private
3842
+	 */
3843
+	public function offsetSet($offset, $value)
3844
+	{
3845
+		//		$this->find($offset)->replaceWith($value);
3846
+		$this->find($offset)->html($value);
3847
+	}
3848
+
3849
+	/**
3850
+	 * @access private
3851
+	 */
3852
+	public function offsetUnset($offset)
3853
+	{
3854
+		// empty
3855
+		throw new \Exception("Can't do unset, use array interface only for calling queries and replacing HTML.");
3856
+	}
3857
+	// ARRAYACCESS INTERFACE END
3858
+	/**
3859
+	 * Returns node's XPath.
3860
+	 *
3861
+	 * @param unknown_type $oneNode
3862
+	 * @param null         $namespace
3863
+	 * @return string
3864
+	 * @TODO   use native getNodePath is avaible
3865
+	 * @access private
3866
+	 */
3867
+	protected function getNodeXpath($oneNode = null, $namespace = null)
3868
+	{
3869
+		$return = array();
3870
+		$loop   = $oneNode ? array(
3871
+			$oneNode
3872
+		) : $this->elements;
3873
+		//		if ($namespace)
3874
+		//			$namespace .= ':';
3875
+		foreach ($loop as $node) {
3876
+			if ($node instanceof \DOMDocument) {
3877
+				$return[] = '';
3878
+				continue;
3879
+			}
3880
+			$xpath = array();
3881
+			while (!($node instanceof \DOMDocument)) {
3882
+				$i       = 1;
3883
+				$sibling = $node;
3884
+				while ($sibling->previousSibling) {
3885
+					$sibling   = $sibling->previousSibling;
3886
+					$isElement = $sibling instanceof \DOMElement;
3887
+					if ($isElement && $sibling->tagName == $node->tagName)
3888
+						$i++;
3889
+				}
3890
+				$xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]"
3891
+					: "{$node->tagName}[{$i}]";
3892
+				$node    = $node->parentNode;
3893
+			}
3894
+			$xpath    = join('/', array_reverse($xpath));
3895
+			$return[] = '/' . $xpath;
3896
+		}
3897
+		return $oneNode ? $return[0] : $return;
3898
+	}
3899
+
3900
+	// HELPERS
3901
+	public function whois($oneNode = null)
3902
+	{
3903
+		$return = array();
3904
+		$loop   = $oneNode ? array(
3905
+			$oneNode
3906
+		) : $this->elements;
3907
+		foreach ($loop as $node) {
3908
+			if (isset($node->tagName)) {
3909
+				$tag      = in_array(
3910
+					$node->tagName,
3911
+					array(
3912
+						'php',
3913
+						'js'
3914
+					)
3915
+				) ? strtoupper($node->tagName) : $node->tagName;
3916
+				$return[] = $tag
3917
+					. ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '')
3918
+					. ($node->getAttribute('class') ? '.'
3919
+						. join('.', explode(' ', $node->getAttribute('class'))) : '')
3920
+					. ($node->getAttribute('name') ? '[name="'
3921
+						. $node->getAttribute('name') . '"]' : '')
3922
+					. ($node->getAttribute('value')
3923
+					&& strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="'
3924
+						. substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15)
3925
+						. '"]' : '')
3926
+					. ($node->getAttribute('value')
3927
+					&& strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]'
3928
+						: '') . ($node->getAttribute('selected') ? '[selected]' : '')
3929
+					. ($node->getAttribute('checked') ? '[checked]' : '');
3930
+			} else if ($node instanceof \DOMTEXT) {
3931
+				if (trim($node->textContent))
3932
+					$return[] = 'Text:'
3933
+						. substr(str_replace("\n", ' ', $node->textContent), 0, 15);
3934
+			} else {
3935
+
3936
+			}
3937
+		}
3938
+		return $oneNode && isset($return[0]) ? $return[0] : $return;
3939
+	}
3940
+
3941
+	/**
3942
+	 * Dump htmlOuter and preserve chain. Usefull for debugging.
3943
+	 *
3944
+	 * @return PhpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery
3945
+	 *
3946
+	 */
3947
+	public function dump()
3948
+	{
3949
+		print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3950
+		PhpQuery::$debug = false;
3951
+		//		print __FILE__.':'.__LINE__."\n";
3952
+		var_dump($this->htmlOuter());
3953
+		return $this;
3954
+	}
3955
+
3956
+	public function dumpWhois()
3957
+	{
3958
+		print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3959
+		$debug           = PhpQuery::$debug;
3960
+		PhpQuery::$debug = false;
3961
+		//		print __FILE__.':'.__LINE__."\n";
3962
+		var_dump('whois', $this->whois());
3963
+		PhpQuery::$debug = $debug;
3964
+		return $this;
3965
+	}
3966
+
3967
+	public function dumpLength()
3968
+	{
3969
+		print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3970
+		$debug           = PhpQuery::$debug;
3971
+		PhpQuery::$debug = false;
3972
+		//		print __FILE__.':'.__LINE__."\n";
3973
+		var_dump('length', $this->length());
3974
+		PhpQuery::$debug = $debug;
3975
+		return $this;
3976
+	}
3977
+
3978
+	public function dumpTree($html = true, $title = true)
3979
+	{
3980
+		$output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
3981
+		$debug           = PhpQuery::$debug;
3982
+		PhpQuery::$debug = false;
3983
+		foreach ($this->stack() as $node)
3984
+			$output .= $this->__dumpTree($node);
3985
+		PhpQuery::$debug = $debug;
3986
+		print $html ? nl2br(str_replace(' ', '&nbsp;', $output)) : $output;
3987
+		return $this;
3988
+	}
3989
+
3990
+	private function __dumpTree($node, $intend = 0)
3991
+	{
3992
+		$whois  = $this->whois($node);
3993
+		$return = '';
3994
+		if ($whois)
3995
+			$return .= str_repeat(' - ', $intend) . $whois . "\n";
3996
+		if (isset($node->childNodes))
3997
+			foreach ($node->childNodes as $chNode)
3998
+				$return .= $this->__dumpTree($chNode, $intend + 1);
3999
+		return $return;
4000
+	}
4001
+
4002
+	/**
4003
+	 * Dump htmlOuter and stop script execution. Usefull for debugging.
4004
+	 *
4005
+	 */
4006
+	public function dumpDie()
4007
+	{
4008
+		print __FILE__ . ':' . __LINE__;
4009
+		var_dump($this->htmlOuter());
4010
+		die();
4011
+	}
4012 4012
 }
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -443,7 +443,7 @@  discard block
 block discarded – undo
443 443
                     $tmp .= $query[$i];
444 444
                     $i++;
445 445
                 }
446
-                $return[] = '#' . $tmp;
446
+                $return[] = '#'.$tmp;
447 447
                 // SPECIAL CHARS
448 448
             } else if (in_array($c, $specialChars)) {
449 449
                 $return[] = $c;
@@ -782,7 +782,7 @@  discard block
 block discarded – undo
782 782
                 : $this->getNodeXpath($stackNode);
783 783
             // FIXME pseudoclasses-only query, support XML
784 784
             $query = $XQuery == '//' && $xpath == '/html[1]' ? '//*'
785
-                : $xpath . $XQuery;
785
+                : $xpath.$XQuery;
786 786
             $this->debug("XPATH: {$query}");
787 787
             // run query, get elements
788 788
             $nodes = $this->xpath->query($query);
@@ -794,7 +794,7 @@  discard block
 block discarded – undo
794 794
                 $matched = false;
795 795
                 if ($compare) {
796 796
                     PhpQuery::$debug ? $this->debug(
797
-                        "Found: " . $this->whois($node)
797
+                        "Found: ".$this->whois($node)
798 798
                         . ", comparing with {$compare}()"
799 799
                     ) : null;
800 800
                     $PhpQueryDebug   = PhpQuery::$debug;
@@ -823,7 +823,7 @@  discard block
 block discarded – undo
823 823
                 }
824 824
             }
825 825
             if (PhpQuery::$debug) {
826
-                $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
826
+                $this->debug("Matched ".count($debug).": ".implode(', ', $debug));
827 827
             }
828 828
             if ($detachAfter)
829 829
                 $this->root->removeChild($detachAfter);
@@ -902,7 +902,7 @@  discard block
 block discarded – undo
902 902
                 } else if ($s[0] == '#') {
903 903
                     if ($delimiterBefore)
904 904
                         $XQuery .= '*';
905
-                    $XQuery .= "[@id='" . substr($s, 1) . "']";
905
+                    $XQuery .= "[@id='".substr($s, 1)."']";
906 906
                     // ATTRIBUTES
907 907
                 } else if ($s[0] == '[') {
908 908
                     if ($delimiterBefore)
@@ -1026,9 +1026,9 @@  discard block
 block discarded – undo
1026 1026
             case 'odd':
1027 1027
                 $stack = array();
1028 1028
                 foreach ($this->elements as $i => $node) {
1029
-                    if ($class == 'even' && ($i % 2) == 0)
1029
+                    if ($class == 'even' && ($i%2) == 0)
1030 1030
                         $stack[] = $node;
1031
-                    else if ($class == 'odd' && $i % 2)
1031
+                    else if ($class == 'odd' && $i%2)
1032 1032
                         $stack[] = $node;
1033 1033
                 }
1034 1034
                 $this->elements = $stack;
@@ -1235,7 +1235,7 @@  discard block
 block discarded – undo
1235 1235
                     break;
1236 1236
                 // nth-child(n+b) to nth-child(1n+b)
1237 1237
                 if ($param{0} == 'n')
1238
-                    $param = '1' . $param;
1238
+                    $param = '1'.$param;
1239 1239
                 // :nth-child(index/even/odd/equation)
1240 1240
                 if ($param == 'even' || $param == 'odd')
1241 1241
                     $mapped = $this->map(
@@ -1480,13 +1480,13 @@  discard block
 block discarded – undo
1480 1480
                                         // quotemeta used insted of preg_quote
1481 1481
                                         // http://code.google.com/p/phpquery/issues/detail?id=76
1482 1482
                                         case '^':
1483
-                                            $pattern = '^' . $val;
1483
+                                            $pattern = '^'.$val;
1484 1484
                                             break;
1485 1485
                                         case '*':
1486
-                                            $pattern = '.*' . $val . '.*';
1486
+                                            $pattern = '.*'.$val.'.*';
1487 1487
                                             break;
1488 1488
                                         case '$':
1489
-                                            $pattern = '.*' . $val . '$';
1489
+                                            $pattern = '.*'.$val.'$';
1490 1490
                                             break;
1491 1491
                                     }
1492 1492
                                     // cut last character
@@ -1548,7 +1548,7 @@  discard block
 block discarded – undo
1548 1548
         if ($_skipHistory) {
1549 1549
             return $this;
1550 1550
         } else {
1551
-            $this->debug("Stack length after filter(): " . count($finalStack));
1551
+            $this->debug("Stack length after filter(): ".count($finalStack));
1552 1552
             return $this->newInstance();
1553 1553
         }
1554 1554
     }
@@ -1671,14 +1671,14 @@  discard block
 block discarded – undo
1671 1671
             $styles = array();
1672 1672
             foreach ($this->data('phpquery_css') as $k => $v) {
1673 1673
                 if ($v['specificity'] >= 1000) {
1674
-                    $styles[$k] = trim($k) . ':' . trim($v['value']);
1674
+                    $styles[$k] = trim($k).':'.trim($v['value']);
1675 1675
                 }
1676 1676
             }
1677 1677
             ksort($styles);
1678 1678
             if (empty($styles)) {
1679 1679
                 $this->removeAttr('style');
1680 1680
             } elseif (PhpQuery::$enableCssShorthand) {
1681
-                $parser = new \Sabberworm\CSS\Parser('{' . join(';', $styles) . '}');
1681
+                $parser = new \Sabberworm\CSS\Parser('{'.join(';', $styles).'}');
1682 1682
                 $doc    = $parser->parse();
1683 1683
                 $doc->createShorthands();
1684 1684
                 $style = trim($doc->__toString(), "\n\r\t {}");
@@ -1735,11 +1735,11 @@  discard block
 block discarded – undo
1735 1735
             $style    = strlen($style) ? explode(';', $style) : array();
1736 1736
             foreach ($this->attribute_css_mapping as $map => $css_equivalent) {
1737 1737
                 if ($el->hasAttribute($map)) {
1738
-                    $style[] = $css_equivalent . ':' . pq($el)->attr($map);
1738
+                    $style[] = $css_equivalent.':'.pq($el)->attr($map);
1739 1739
                 }
1740 1740
             }
1741 1741
             if (count($style)) {
1742
-                $CssParser   = new CssParser('#ruleset {' . implode(';', $style) . '}');
1742
+                $CssParser   = new CssParser('#ruleset {'.implode(';', $style).'}');
1743 1743
                 $CssDocument = $CssParser->parse();
1744 1744
                 $ruleset     = $CssDocument->getAllRulesets();
1745 1745
                 $ruleset     = reset($ruleset);
@@ -2739,7 +2739,7 @@  discard block
 block discarded – undo
2739 2739
                 break;
2740 2740
         }
2741 2741
         PhpQuery::debug(
2742
-            "From " . count($insertFrom) . "; To " . count($insertTo)
2742
+            "From ".count($insertFrom)."; To ".count($insertTo)
2743 2743
             . " nodes"
2744 2744
         );
2745 2745
         foreach ($insertTo as $insertNumber => $toNode) {
@@ -2965,7 +2965,7 @@  discard block
 block discarded – undo
2965 2965
             return call_user_func_array(
2966 2966
                 array(
2967 2967
                     $this,
2968
-                    '_' . $method
2968
+                    '_'.$method
2969 2969
                 ),
2970 2970
                 $args
2971 2971
             );
@@ -3378,7 +3378,7 @@  discard block
 block discarded – undo
3378 3378
     public function attrPHP($attr, $code)
3379 3379
     {
3380 3380
         if (!is_null($code)) {
3381
-            $value = '<' . '?php ' . $code . ' ?' . '>';
3381
+            $value = '<'.'?php '.$code.' ?'.'>';
3382 3382
             // TODO tempolary solution
3383 3383
             // http://code.google.com/p/phpquery/issues/detail?id=17
3384 3384
             //			if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII')
@@ -3529,7 +3529,7 @@  discard block
 block discarded – undo
3529 3529
                 $node->setAttribute(
3530 3530
                     'class',
3531 3531
                     trim(
3532
-                        $node->getAttribute('class') . ' '
3532
+                        $node->getAttribute('class').' '
3533 3533
                         . $className
3534 3534
                     )
3535 3535
                 );
@@ -3547,8 +3547,8 @@  discard block
 block discarded – undo
3547 3547
     {
3548 3548
         foreach ($this->stack(1) as $node) {
3549 3549
             $classes  = $node->getAttribute('class');
3550
-            $newValue = $classes ? $classes . ' <' . '?php ' . $className . ' ?'
3551
-                . '>' : '<' . '?php ' . $className . ' ?' . '>';
3550
+            $newValue = $classes ? $classes.' <'.'?php '.$className.' ?'
3551
+                . '>' : '<'.'?php '.$className.' ?'.'>';
3552 3552
             $node->setAttribute('class', $newValue);
3553 3553
         }
3554 3554
         return $this;
@@ -3604,7 +3604,7 @@  discard block
 block discarded – undo
3604 3604
     public function toggleClass($className)
3605 3605
     {
3606 3606
         foreach ($this->stack(1) as $node) {
3607
-            if ($this->is($node, '.' . $className))
3607
+            if ($this->is($node, '.'.$className))
3608 3608
                 $this->removeClass($className);
3609 3609
             else
3610 3610
                 $this->addClass($className);
@@ -3892,7 +3892,7 @@  discard block
 block discarded – undo
3892 3892
                 $node    = $node->parentNode;
3893 3893
             }
3894 3894
             $xpath    = join('/', array_reverse($xpath));
3895
-            $return[] = '/' . $xpath;
3895
+            $return[] = '/'.$xpath;
3896 3896
         }
3897 3897
         return $oneNode ? $return[0] : $return;
3898 3898
     }
@@ -3906,7 +3906,7 @@  discard block
 block discarded – undo
3906 3906
         ) : $this->elements;
3907 3907
         foreach ($loop as $node) {
3908 3908
             if (isset($node->tagName)) {
3909
-                $tag      = in_array(
3909
+                $tag = in_array(
3910 3910
                     $node->tagName,
3911 3911
                     array(
3912 3912
                         'php',
@@ -3914,18 +3914,18 @@  discard block
 block discarded – undo
3914 3914
                     )
3915 3915
                 ) ? strtoupper($node->tagName) : $node->tagName;
3916 3916
                 $return[] = $tag
3917
-                    . ($node->getAttribute('id') ? '#' . $node->getAttribute('id') : '')
3917
+                    . ($node->getAttribute('id') ? '#'.$node->getAttribute('id') : '')
3918 3918
                     . ($node->getAttribute('class') ? '.'
3919 3919
                         . join('.', explode(' ', $node->getAttribute('class'))) : '')
3920 3920
                     . ($node->getAttribute('name') ? '[name="'
3921
-                        . $node->getAttribute('name') . '"]' : '')
3921
+                        . $node->getAttribute('name').'"]' : '')
3922 3922
                     . ($node->getAttribute('value')
3923
-                    && strpos($node->getAttribute('value'), '<' . '?php') === false ? '[value="'
3923
+                    && strpos($node->getAttribute('value'), '<'.'?php') === false ? '[value="'
3924 3924
                         . substr(str_replace("\n", '', $node->getAttribute('value')), 0, 15)
3925 3925
                         . '"]' : '')
3926 3926
                     . ($node->getAttribute('value')
3927
-                    && strpos($node->getAttribute('value'), '<' . '?php') !== false ? '[value=PHP]'
3928
-                        : '') . ($node->getAttribute('selected') ? '[selected]' : '')
3927
+                    && strpos($node->getAttribute('value'), '<'.'?php') !== false ? '[value=PHP]'
3928
+                        : '').($node->getAttribute('selected') ? '[selected]' : '')
3929 3929
                     . ($node->getAttribute('checked') ? '[checked]' : '');
3930 3930
             } else if ($node instanceof \DOMTEXT) {
3931 3931
                 if (trim($node->textContent))
@@ -3946,7 +3946,7 @@  discard block
 block discarded – undo
3946 3946
      */
3947 3947
     public function dump()
3948 3948
     {
3949
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3949
+        print 'DUMP #'.(PhpQuery::$dumpCount++).' ';
3950 3950
         PhpQuery::$debug = false;
3951 3951
         //		print __FILE__.':'.__LINE__."\n";
3952 3952
         var_dump($this->htmlOuter());
@@ -3955,7 +3955,7 @@  discard block
 block discarded – undo
3955 3955
 
3956 3956
     public function dumpWhois()
3957 3957
     {
3958
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3958
+        print 'DUMP #'.(PhpQuery::$dumpCount++).' ';
3959 3959
         $debug           = PhpQuery::$debug;
3960 3960
         PhpQuery::$debug = false;
3961 3961
         //		print __FILE__.':'.__LINE__."\n";
@@ -3966,7 +3966,7 @@  discard block
 block discarded – undo
3966 3966
 
3967 3967
     public function dumpLength()
3968 3968
     {
3969
-        print 'DUMP #' . (PhpQuery::$dumpCount++) . ' ';
3969
+        print 'DUMP #'.(PhpQuery::$dumpCount++).' ';
3970 3970
         $debug           = PhpQuery::$debug;
3971 3971
         PhpQuery::$debug = false;
3972 3972
         //		print __FILE__.':'.__LINE__."\n";
@@ -3977,7 +3977,7 @@  discard block
 block discarded – undo
3977 3977
 
3978 3978
     public function dumpTree($html = true, $title = true)
3979 3979
     {
3980
-        $output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
3980
+        $output          = $title ? 'DUMP #'.(PhpQuery::$dumpCount++)." \n" : '';
3981 3981
         $debug           = PhpQuery::$debug;
3982 3982
         PhpQuery::$debug = false;
3983 3983
         foreach ($this->stack() as $node)
@@ -3992,7 +3992,7 @@  discard block
 block discarded – undo
3992 3992
         $whois  = $this->whois($node);
3993 3993
         $return = '';
3994 3994
         if ($whois)
3995
-            $return .= str_repeat(' - ', $intend) . $whois . "\n";
3995
+            $return .= str_repeat(' - ', $intend).$whois."\n";
3996 3996
         if (isset($node->childNodes))
3997 3997
             foreach ($node->childNodes as $chNode)
3998 3998
                 $return .= $this->__dumpTree($chNode, $intend + 1);
@@ -4005,7 +4005,7 @@  discard block
 block discarded – undo
4005 4005
      */
4006 4006
     public function dumpDie()
4007 4007
     {
4008
-        print __FILE__ . ':' . __LINE__;
4008
+        print __FILE__.':'.__LINE__;
4009 4009
         var_dump($this->htmlOuter());
4010 4010
         die();
4011 4011
     }
Please login to merge, or discard this patch.
Braces   +493 added lines, -345 removed lines patch added patch discarded remove patch
@@ -562,10 +562,12 @@  discard block
 block discarded – undo
562 562
         }
563 563
         foreach ($queries as $k => $q) {
564 564
             if (isset($q[0])) {
565
-                if (isset($q[0][0]) && $q[0][0] == ':')
566
-                    array_unshift($queries[$k], '*');
567
-                if ($q[0] != '>')
568
-                    array_unshift($queries[$k], ' ');
565
+                if (isset($q[0][0]) && $q[0][0] == ':') {
566
+                                    array_unshift($queries[$k], '*');
567
+                }
568
+                if ($q[0] != '>') {
569
+                                    array_unshift($queries[$k], ' ');
570
+                }
569 571
             }
570 572
         }
571 573
         return $queries;
@@ -585,21 +587,22 @@  discard block
 block discarded – undo
585 587
         $args = func_get_args();
586 588
         $args = array_slice($args, 1);
587 589
         foreach ($args as $callback) {
588
-            if (is_array($return))
589
-                foreach ($return as $k => $v)
590
+            if (is_array($return)) {
591
+                            foreach ($return as $k => $v)
590 592
                     $return[$k] = PhpQuery::callbackRun(
591 593
                         $callback,
592 594
                         array(
593 595
                             $v
594 596
                         )
595 597
                     );
596
-            else
597
-                $return = PhpQuery::callbackRun(
598
+            } else {
599
+                            $return = PhpQuery::callbackRun(
598 600
                     $callback,
599 601
                     array(
600 602
                         $return
601 603
                     )
602 604
                 );
605
+            }
603 606
         }
604 607
         return $return;
605 608
     }
@@ -619,9 +622,9 @@  discard block
 block discarded – undo
619 622
      */
620 623
     public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
621 624
     {
622
-        if ($index)
623
-            $return = $this->eq($index)->text();
624
-        else {
625
+        if ($index) {
626
+                    $return = $this->eq($index)->text();
627
+        } else {
625 628
             $return = array();
626 629
             for ($i = 0; $i < $this->size(); $i++) {
627 630
                 $return[] = $this->eq($i)->text();
@@ -656,9 +659,9 @@  discard block
 block discarded – undo
656 659
      */
657 660
     public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null)
658 661
     {
659
-        if ($index)
660
-            $return = $this->eq($index)->text();
661
-        else {
662
+        if ($index) {
663
+                    $return = $this->eq($index)->text();
664
+        } else {
662 665
             $return = array();
663 666
             for ($i = 0; $i < $this->size(); $i++) {
664 667
                 $return[] = $this->eq($i)->text();
@@ -668,21 +671,22 @@  discard block
 block discarded – undo
668 671
             $args = array_slice($args, 1);
669 672
         }
670 673
         foreach ($args as $callback) {
671
-            if (is_array($return))
672
-                foreach ($return as $k => $v)
674
+            if (is_array($return)) {
675
+                            foreach ($return as $k => $v)
673 676
                     $return[$k] = PhpQuery::callbackRun(
674 677
                         $callback,
675 678
                         array(
676 679
                             $v
677 680
                         )
678 681
                     );
679
-            else
680
-                $return = PhpQuery::callbackRun(
682
+            } else {
683
+                            $return = PhpQuery::callbackRun(
681 684
                     $callback,
682 685
                     array(
683 686
                         $return
684 687
                     )
685 688
                 );
689
+            }
686 690
         }
687 691
         return $return;
688 692
     }
@@ -702,8 +706,9 @@  discard block
 block discarded – undo
702 706
         $new->previous = $this;
703 707
         if (is_null($newStack)) {
704 708
             $new->elements = $this->elements;
705
-            if ($this->elementsBackup)
706
-                $this->elements = $this->elementsBackup;
709
+            if ($this->elementsBackup) {
710
+                            $this->elements = $this->elementsBackup;
711
+            }
707 712
         } else if (is_string($newStack)) {
708 713
             $new->elements = PhpQuery::pq($newStack, $this->getDocumentID())->stack();
709 714
         } else {
@@ -730,11 +735,13 @@  discard block
 block discarded – undo
730 735
             $classesCount     = count($classes);
731 736
             $nodeClasses      = explode(' ', $node->getAttribute('class'));
732 737
             $nodeClassesCount = count($nodeClasses);
733
-            if ($classesCount > $nodeClassesCount)
734
-                return false;
738
+            if ($classesCount > $nodeClassesCount) {
739
+                            return false;
740
+            }
735 741
             $diff = count(array_diff($classes, $nodeClasses));
736
-            if (!$diff)
737
-                return true;
742
+            if (!$diff) {
743
+                            return true;
744
+            }
738 745
             // single-class
739 746
         } else {
740 747
             return in_array(
@@ -751,11 +758,13 @@  discard block
 block discarded – undo
751 758
      */
752 759
     protected function runQuery($XQuery, $selector = null, $compare = null)
753 760
     {
754
-        if ($compare && !method_exists($this, $compare))
755
-            return false;
761
+        if ($compare && !method_exists($this, $compare)) {
762
+                    return false;
763
+        }
756 764
         $stack = array();
757
-        if (!$this->elements)
758
-            $this->debug('Stack empty, skipping...');
765
+        if (!$this->elements) {
766
+                    $this->debug('Stack empty, skipping...');
767
+        }
759 768
         //		var_dump($this->elements[0]->nodeType);
760 769
         // element, document
761 770
         foreach ($this->stack(
@@ -787,8 +796,9 @@  discard block
 block discarded – undo
787 796
             // run query, get elements
788 797
             $nodes = $this->xpath->query($query);
789 798
             $this->debug("QUERY FETCHED");
790
-            if (!$nodes->length)
791
-                $this->debug('Nothing found');
799
+            if (!$nodes->length) {
800
+                            $this->debug('Nothing found');
801
+            }
792 802
             $debug = array();
793 803
             foreach ($nodes as $node) {
794 804
                 $matched = false;
@@ -810,23 +820,26 @@  discard block
 block discarded – undo
810 820
                             $node
811 821
                         )
812 822
                     )
813
-                    )
814
-                        $matched = true;
823
+                    ) {
824
+                                            $matched = true;
825
+                    }
815 826
                     PhpQuery::$debug = $PhpQueryDebug;
816 827
                 } else {
817 828
                     $matched = true;
818 829
                 }
819 830
                 if ($matched) {
820
-                    if (PhpQuery::$debug)
821
-                        $debug[] = $this->whois($node);
831
+                    if (PhpQuery::$debug) {
832
+                                            $debug[] = $this->whois($node);
833
+                    }
822 834
                     $stack[] = $node;
823 835
                 }
824 836
             }
825 837
             if (PhpQuery::$debug) {
826 838
                 $this->debug("Matched " . count($debug) . ": " . implode(', ', $debug));
827 839
             }
828
-            if ($detachAfter)
829
-                $this->root->removeChild($detachAfter);
840
+            if ($detachAfter) {
841
+                            $this->root->removeChild($detachAfter);
842
+            }
830 843
         }
831 844
         $this->elements = $stack;
832 845
     }
@@ -841,9 +854,10 @@  discard block
 block discarded – undo
841 854
      */
842 855
     public function find($selectors, $context = null, $noHistory = false)
843 856
     {
844
-        if (!$noHistory)
845
-            // backup last stack /for end()/
857
+        if (!$noHistory) {
858
+                    // backup last stack /for end()/
846 859
             $this->elementsBackup = $this->elements;
860
+        }
847 861
         // allow to define context
848 862
         // TODO combine code below with PhpQuery::pq() context guessing code
849 863
         //   as generic function
@@ -854,9 +868,10 @@  discard block
 block discarded – undo
854 868
                 );
855 869
             } elseif (is_array($context)) {
856 870
                 $this->elements = array();
857
-                foreach ($context as $c)
858
-                    if ($c instanceof \DOMElement)
871
+                foreach ($context as $c) {
872
+                                    if ($c instanceof \DOMElement)
859 873
                         $this->elements[] = $c;
874
+                }
860 875
             } elseif ($context instanceof PhpQueryObject) {
861 876
                 $this->elements = $context->elements;
862 877
             }
@@ -900,13 +915,15 @@  discard block
 block discarded – undo
900 915
                     }
901 916
                     // ID
902 917
                 } else if ($s[0] == '#') {
903
-                    if ($delimiterBefore)
904
-                        $XQuery .= '*';
918
+                    if ($delimiterBefore) {
919
+                                            $XQuery .= '*';
920
+                    }
905 921
                     $XQuery .= "[@id='" . substr($s, 1) . "']";
906 922
                     // ATTRIBUTES
907 923
                 } else if ($s[0] == '[') {
908
-                    if ($delimiterBefore)
909
-                        $XQuery .= '*';
924
+                    if ($delimiterBefore) {
925
+                                            $XQuery .= '*';
926
+                    }
910 927
                     // strip side brackets
911 928
                     $attr    = trim($s, '][');
912 929
                     $execute = false;
@@ -930,27 +947,31 @@  discard block
 block discarded – undo
930 947
                     if ($execute) {
931 948
                         $this->runQuery($XQuery, $s, 'is');
932 949
                         $XQuery = '';
933
-                        if (!$this->length())
934
-                            break;
950
+                        if (!$this->length()) {
951
+                                                    break;
952
+                        }
935 953
                     }
936 954
                     // CLASSES
937 955
                 } else if ($s[0] == '.') {
938 956
                     // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
939 957
                     // thx wizDom ;)
940
-                    if ($delimiterBefore)
941
-                        $XQuery .= '*';
958
+                    if ($delimiterBefore) {
959
+                                            $XQuery .= '*';
960
+                    }
942 961
                     $XQuery .= '[@class]';
943 962
                     $this->runQuery($XQuery, $s, 'matchClasses');
944 963
                     $XQuery = '';
945
-                    if (!$this->length())
946
-                        break;
964
+                    if (!$this->length()) {
965
+                                            break;
966
+                    }
947 967
                     // ~ General Sibling Selector
948 968
                 } else if ($s[0] == '~') {
949 969
                     $this->runQuery($XQuery);
950 970
                     $XQuery         = '';
951 971
                     $this->elements = $this->siblings(substr($s, 1))->elements;
952
-                    if (!$this->length())
953
-                        break;
972
+                    if (!$this->length()) {
973
+                                            break;
974
+                    }
954 975
                     // + Adjacent sibling selectors
955 976
                 } else if ($s[0] == '+') {
956 977
                     // TODO /following-sibling::
@@ -962,13 +983,16 @@  discard block
 block discarded – undo
962 983
                     foreach ($subElements as $node) {
963 984
                         // search first \DOMElement sibling
964 985
                         $test = $node->nextSibling;
965
-                        while ($test && !($test instanceof \DOMElement))
966
-                            $test = $test->nextSibling;
967
-                        if ($test && $this->is($subSelector, $test))
968
-                            $this->elements[] = $test;
986
+                        while ($test && !($test instanceof \DOMElement)) {
987
+                                                    $test = $test->nextSibling;
988
+                        }
989
+                        if ($test && $this->is($subSelector, $test)) {
990
+                                                    $this->elements[] = $test;
991
+                        }
992
+                    }
993
+                    if (!$this->length()) {
994
+                                            break;
969 995
                     }
970
-                    if (!$this->length())
971
-                        break;
972 996
                     // PSEUDO CLASSES
973 997
                 } else if ($s[0] == ':') {
974 998
                     // TODO optimization for :first :last
@@ -976,11 +1000,13 @@  discard block
 block discarded – undo
976 1000
                         $this->runQuery($XQuery);
977 1001
                         $XQuery = '';
978 1002
                     }
979
-                    if (!$this->length())
980
-                        break;
1003
+                    if (!$this->length()) {
1004
+                                            break;
1005
+                    }
981 1006
                     $this->pseudoClasses($s);
982
-                    if (!$this->length())
983
-                        break;
1007
+                    if (!$this->length()) {
1008
+                                            break;
1009
+                    }
984 1010
                     // DIRECT DESCENDANDS
985 1011
                 } else if ($s == '>') {
986 1012
                     $XQuery .= '/';
@@ -1000,9 +1026,10 @@  discard block
 block discarded – undo
1000 1026
                 $this->runQuery($XQuery);
1001 1027
                 $XQuery = '';
1002 1028
             }
1003
-            foreach ($this->elements as $node)
1004
-                if (!$this->elementsContainsNode($node, $stack))
1029
+            foreach ($this->elements as $node) {
1030
+                            if (!$this->elementsContainsNode($node, $stack))
1005 1031
                     $stack[] = $node;
1032
+            }
1006 1033
         }
1007 1034
         $this->elements = $stack;
1008 1035
         return $this->newInstance();
@@ -1026,10 +1053,11 @@  discard block
 block discarded – undo
1026 1053
             case 'odd':
1027 1054
                 $stack = array();
1028 1055
                 foreach ($this->elements as $i => $node) {
1029
-                    if ($class == 'even' && ($i % 2) == 0)
1030
-                        $stack[] = $node;
1031
-                    else if ($class == 'odd' && $i % 2)
1032
-                        $stack[] = $node;
1056
+                    if ($class == 'even' && ($i % 2) == 0) {
1057
+                                            $stack[] = $node;
1058
+                    } else if ($class == 'odd' && $i % 2) {
1059
+                                            $stack[] = $node;
1060
+                    }
1033 1061
                 }
1034 1062
                 $this->elements = $stack;
1035 1063
                 break;
@@ -1046,16 +1074,18 @@  discard block
 block discarded – undo
1046 1074
                 $this->elements = array_slice($this->elements, 0, $args + 1);
1047 1075
                 break;
1048 1076
             case 'first':
1049
-                if (isset($this->elements[0]))
1050
-                    $this->elements = array(
1077
+                if (isset($this->elements[0])) {
1078
+                                    $this->elements = array(
1051 1079
                         $this->elements[0]
1052 1080
                     );
1081
+                }
1053 1082
                 break;
1054 1083
             case 'last':
1055
-                if ($this->elements)
1056
-                    $this->elements = array(
1084
+                if ($this->elements) {
1085
+                                    $this->elements = array(
1057 1086
                         $this->elements[count($this->elements) - 1]
1058 1087
                     );
1088
+                }
1059 1089
                 break;
1060 1090
             /*case 'parent':
1061 1091
           $stack = array();
@@ -1069,8 +1099,9 @@  discard block
 block discarded – undo
1069 1099
                 $text  = trim($args, "\"'");
1070 1100
                 $stack = array();
1071 1101
                 foreach ($this->elements as $node) {
1072
-                    if (mb_stripos($node->textContent, $text) === false)
1073
-                        continue;
1102
+                    if (mb_stripos($node->textContent, $text) === false) {
1103
+                                            continue;
1104
+                    }
1074 1105
                     $stack[] = $node;
1075 1106
                 }
1076 1107
                 $this->elements = $stack;
@@ -1084,16 +1115,18 @@  discard block
 block discarded – undo
1084 1115
                 $args  = explode(',', str_replace(', ', ',', trim($args, "\"'")));
1085 1116
                 $start = $args[0];
1086 1117
                 $end   = isset($args[1]) ? $args[1] : null;
1087
-                if ($end > 0)
1088
-                    $end = $end - $start;
1118
+                if ($end > 0) {
1119
+                                    $end = $end - $start;
1120
+                }
1089 1121
                 $this->elements = array_slice($this->elements, $start, $end);
1090 1122
                 break;
1091 1123
             case 'has':
1092 1124
                 $selector = trim($args, "\"'");
1093 1125
                 $stack    = array();
1094 1126
                 foreach ($this->stack(1) as $el) {
1095
-                    if ($this->find($selector, $el, true)->length)
1096
-                        $stack[] = $el;
1127
+                    if ($this->find($selector, $el, true)->length) {
1128
+                                            $stack[] = $el;
1129
+                    }
1097 1130
                 }
1098 1131
                 $this->elements = $stack;
1099 1132
                 break;
@@ -1231,14 +1264,16 @@  discard block
 block discarded – undo
1231 1264
                 break;
1232 1265
             case 'nth-child':
1233 1266
                 $param = trim($args, "\"'");
1234
-                if (!$param)
1235
-                    break;
1267
+                if (!$param) {
1268
+                                    break;
1269
+                }
1236 1270
                 // nth-child(n+b) to nth-child(1n+b)
1237
-                if ($param{0} == 'n')
1238
-                    $param = '1' . $param;
1271
+                if ($param{0} == 'n') {
1272
+                                    $param = '1' . $param;
1273
+                }
1239 1274
                 // :nth-child(index/even/odd/equation)
1240
-                if ($param == 'even' || $param == 'odd')
1241
-                    $mapped = $this->map(
1275
+                if ($param == 'even' || $param == 'odd') {
1276
+                                    $mapped = $this->map(
1242 1277
                         create_function(
1243 1278
                             '$node, $param',
1244 1279
                             '$index = pq($node)->prevAll()->size()+1;
@@ -1252,10 +1287,10 @@  discard block
 block discarded – undo
1252 1287
                         new \CallbackParam(),
1253 1288
                         $param
1254 1289
                     );
1255
-                else if (mb_strlen($param) > 1
1290
+                } else if (mb_strlen($param) > 1
1256 1291
                     && preg_match('/^(\d*)n([-+]?)(\d*)/', $param) === 1
1257
-                )
1258
-                    // an+b
1292
+                ) {
1293
+                                    // an+b
1259 1294
                     $mapped = $this->map(
1260 1295
                         create_function(
1261 1296
                             '$node, $param',
@@ -1299,8 +1334,8 @@  discard block
 block discarded – undo
1299 1334
                         new \CallbackParam(),
1300 1335
                         $param
1301 1336
                     );
1302
-                else
1303
-                    // index
1337
+                } else {
1338
+                                    // index
1304 1339
                     $mapped = $this->map(
1305 1340
                         create_function(
1306 1341
                             '$node, $index',
@@ -1315,6 +1350,7 @@  discard block
 block discarded – undo
1315 1350
                         new \CallbackParam(),
1316 1351
                         $param
1317 1352
                     );
1353
+                }
1318 1354
                 $this->elements = $mapped->elements;
1319 1355
                 break;
1320 1356
             default:
@@ -1345,21 +1381,24 @@  discard block
 block discarded – undo
1345 1381
                 $selector
1346 1382
             )
1347 1383
         );
1348
-        if (!$selector)
1349
-            return false;
1384
+        if (!$selector) {
1385
+                    return false;
1386
+        }
1350 1387
         $oldStack    = $this->elements;
1351 1388
         $returnArray = false;
1352 1389
         if ($nodes && is_array($nodes)) {
1353 1390
             $this->elements = $nodes;
1354
-        } else if ($nodes)
1355
-            $this->elements = array(
1391
+        } else if ($nodes) {
1392
+                    $this->elements = array(
1356 1393
                 $nodes
1357 1394
             );
1395
+        }
1358 1396
         $this->filter($selector, true);
1359 1397
         $stack          = $this->elements;
1360 1398
         $this->elements = $oldStack;
1361
-        if ($nodes)
1362
-            return $stack ? $stack : null;
1399
+        if ($nodes) {
1400
+                    return $stack ? $stack : null;
1401
+        }
1363 1402
         return (bool) count($stack);
1364 1403
     }
1365 1404
 
@@ -1391,8 +1430,9 @@  discard block
 block discarded – undo
1391 1430
                     $node
1392 1431
                 )
1393 1432
             );
1394
-            if (is_null($result) || (!is_null($result) && $result))
1395
-                $newStack[] = $node;
1433
+            if (is_null($result) || (!is_null($result) && $result)) {
1434
+                            $newStack[] = $node;
1435
+            }
1396 1436
         }
1397 1437
         $this->elements = $newStack;
1398 1438
         return $_skipHistory ? $this : $this->newInstance();
@@ -1408,10 +1448,12 @@  discard block
 block discarded – undo
1408 1448
      */
1409 1449
     public function filter($selectors, $_skipHistory = false)
1410 1450
     {
1411
-        if ($selectors instanceof \Callback OR $selectors instanceof \Closure)
1412
-            return $this->filterCallback($selectors, $_skipHistory);
1413
-        if (!$_skipHistory)
1414
-            $this->elementsBackup = $this->elements;
1451
+        if ($selectors instanceof \Callback OR $selectors instanceof \Closure) {
1452
+                    return $this->filterCallback($selectors, $_skipHistory);
1453
+        }
1454
+        if (!$_skipHistory) {
1455
+                    $this->elementsBackup = $this->elements;
1456
+        }
1415 1457
         $notSimpleSelector = array(
1416 1458
             ' ',
1417 1459
             '>',
@@ -1419,23 +1461,27 @@  discard block
 block discarded – undo
1419 1461
             '+',
1420 1462
             '/'
1421 1463
         );
1422
-        if (!is_array($selectors))
1423
-            $selectors = $this->parseSelector($selectors);
1424
-        if (!$_skipHistory)
1425
-            $this->debug(
1464
+        if (!is_array($selectors)) {
1465
+                    $selectors = $this->parseSelector($selectors);
1466
+        }
1467
+        if (!$_skipHistory) {
1468
+                    $this->debug(
1426 1469
                 array(
1427 1470
                     "Filtering:",
1428 1471
                     $selectors
1429 1472
                 )
1430 1473
             );
1474
+        }
1431 1475
         $finalStack = array();
1432 1476
         foreach ($selectors as $selector) {
1433 1477
             $stack = array();
1434
-            if (!$selector)
1435
-                break;
1478
+            if (!$selector) {
1479
+                            break;
1480
+            }
1436 1481
             // avoid first space or /
1437
-            if (in_array($selector[0], $notSimpleSelector))
1438
-                $selector = array_slice($selector, 1);
1482
+            if (in_array($selector[0], $notSimpleSelector)) {
1483
+                            $selector = array_slice($selector, 1);
1484
+            }
1439 1485
             // PER NODE selector chunks
1440 1486
             foreach ($this->stack() as $node) {
1441 1487
                 $break = false;
@@ -1446,21 +1492,25 @@  discard block
 block discarded – undo
1446 1492
                             $attr = trim($s, '[]');
1447 1493
                             if (mb_strpos($attr, '=')) {
1448 1494
                                 list($attr, $val) = explode('=', $attr);
1449
-                                if ($attr == 'nodeType' && $node->nodeType != $val)
1450
-                                    $break = true;
1495
+                                if ($attr == 'nodeType' && $node->nodeType != $val) {
1496
+                                                                    $break = true;
1497
+                                }
1451 1498
                             }
1452
-                        } else
1453
-                            $break = true;
1499
+                        } else {
1500
+                                                    $break = true;
1501
+                        }
1454 1502
                     } else {
1455 1503
                         // \DOMElement only
1456 1504
                         // ID
1457 1505
                         if ($s[0] == '#') {
1458
-                            if ($node->getAttribute('id') != substr($s, 1))
1459
-                                $break = true;
1506
+                            if ($node->getAttribute('id') != substr($s, 1)) {
1507
+                                                            $break = true;
1508
+                            }
1460 1509
                             // CLASSES
1461 1510
                         } else if ($s[0] == '.') {
1462
-                            if (!$this->matchClasses($s, $node))
1463
-                                $break = true;
1511
+                            if (!$this->matchClasses($s, $node)) {
1512
+                                                            $break = true;
1513
+                            }
1464 1514
                             // ATTRS
1465 1515
                         } else if ($s[0] == '[') {
1466 1516
                             // strip side brackets
@@ -1469,8 +1519,9 @@  discard block
 block discarded – undo
1469 1519
                                 list($attr, $val) = explode('=', $attr);
1470 1520
                                 $val = self::unQuote($val);
1471 1521
                                 if ($attr == 'nodeType') {
1472
-                                    if ($val != $node->nodeType)
1473
-                                        $break = true;
1522
+                                    if ($val != $node->nodeType) {
1523
+                                                                            $break = true;
1524
+                                    }
1474 1525
                                 } else if ($this->isRegexp($attr)) {
1475 1526
                                     $val = extension_loaded('mbstring')
1476 1527
                                     && PhpQuery::$mbstringSupport ? quotemeta(trim($val, '"\''))
@@ -1494,12 +1545,15 @@  discard block
 block discarded – undo
1494 1545
                                     $isMatch = extension_loaded('mbstring')
1495 1546
                                     && PhpQuery::$mbstringSupport ? mb_ereg_match($pattern, $node->getAttribute($attr))
1496 1547
                                         : preg_match("@{$pattern}@", $node->getAttribute($attr));
1497
-                                    if (!$isMatch)
1498
-                                        $break = true;
1499
-                                } else if ($node->getAttribute($attr) != $val)
1500
-                                    $break = true;
1501
-                            } else if (!$node->hasAttribute($attr))
1502
-                                $break = true;
1548
+                                    if (!$isMatch) {
1549
+                                                                            $break = true;
1550
+                                    }
1551
+                                } else if ($node->getAttribute($attr) != $val) {
1552
+                                                                    $break = true;
1553
+                                }
1554
+                            } else if (!$node->hasAttribute($attr)) {
1555
+                                                            $break = true;
1556
+                            }
1503 1557
                             // PSEUDO CLASSES
1504 1558
                         } else if ($s[0] == ':') {
1505 1559
                             // skip
@@ -1508,10 +1562,12 @@  discard block
 block discarded – undo
1508 1562
                             if ($s != '*') {
1509 1563
                                 // TODO namespaces
1510 1564
                                 if (isset($node->tagName)) {
1511
-                                    if ($node->tagName != $s)
1512
-                                        $break = true;
1513
-                                } else if ($s == 'html' && !$this->isRoot($node))
1514
-                                    $break = true;
1565
+                                    if ($node->tagName != $s) {
1566
+                                                                            $break = true;
1567
+                                    }
1568
+                                } else if ($s == 'html' && !$this->isRoot($node)) {
1569
+                                                                    $break = true;
1570
+                                }
1515 1571
                             }
1516 1572
                             // AVOID NON-SIMPLE SELECTORS
1517 1573
                         } else if (in_array($s, $notSimpleSelector)) {
@@ -1524,24 +1580,28 @@  discard block
 block discarded – undo
1524 1580
                             );
1525 1581
                         }
1526 1582
                     }
1527
-                    if ($break)
1528
-                        break;
1583
+                    if ($break) {
1584
+                                            break;
1585
+                    }
1529 1586
                 }
1530 1587
                 // if element passed all chunks of selector - add it to new stack
1531
-                if (!$break)
1532
-                    $stack[] = $node;
1588
+                if (!$break) {
1589
+                                    $stack[] = $node;
1590
+                }
1533 1591
             }
1534 1592
             $tmpStack       = $this->elements;
1535 1593
             $this->elements = $stack;
1536 1594
             // PER ALL NODES selector chunks
1537
-            foreach ($selector as $s)
1538
-                // PSEUDO CLASSES
1595
+            foreach ($selector as $s) {
1596
+                            // PSEUDO CLASSES
1539 1597
                 if ($s[0] == ':')
1540 1598
                     $this->pseudoClasses($s);
1541
-            foreach ($this->elements as $node)
1542
-                // XXX it should be merged without duplicates
1599
+            }
1600
+            foreach ($this->elements as $node) {
1601
+                            // XXX it should be merged without duplicates
1543 1602
                 // but jQuery doesnt do that
1544 1603
                 $finalStack[] = $node;
1604
+            }
1545 1605
             $this->elements = $tmpStack;
1546 1606
         }
1547 1607
         $this->elements = $finalStack;
@@ -1583,10 +1643,11 @@  discard block
 block discarded – undo
1583 1643
         }
1584 1644
         if (mb_strpos($url, ' ') !== false) {
1585 1645
             $matches = null;
1586
-            if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport)
1587
-                mb_ereg('^([^ ]+) (.*)$', $url, $matches);
1588
-            else
1589
-                preg_match('@^([^ ]+) (.*)$@', $url, $matches);
1646
+            if (extension_loaded('mbstring') && PhpQuery::$mbstringSupport) {
1647
+                            mb_ereg('^([^ ]+) (.*)$', $url, $matches);
1648
+            } else {
1649
+                            preg_match('@^([^ ]+) (.*)$@', $url, $matches);
1650
+            }
1590 1651
             $url      = $matches[1];
1591 1652
             $selector = $matches[2];
1592 1653
             // FIXME this sucks, pass as callback param
@@ -1817,8 +1878,9 @@  discard block
 block discarded – undo
1817 1878
      */
1818 1879
     public function trigger($type, $data = array())
1819 1880
     {
1820
-        foreach ($this->elements as $node)
1821
-            PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
1881
+        foreach ($this->elements as $node) {
1882
+                    PhpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
1883
+        }
1822 1884
         return $this;
1823 1885
     }
1824 1886
 
@@ -1853,8 +1915,9 @@  discard block
 block discarded – undo
1853 1915
             $callback = $data;
1854 1916
             $data     = null;
1855 1917
         }
1856
-        foreach ($this->elements as $node)
1857
-            PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
1918
+        foreach ($this->elements as $node) {
1919
+                    PhpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
1920
+        }
1858 1921
         return $this;
1859 1922
     }
1860 1923
 
@@ -1869,8 +1932,9 @@  discard block
 block discarded – undo
1869 1932
      */
1870 1933
     public function unbind($type = null, $callback = null)
1871 1934
     {
1872
-        foreach ($this->elements as $node)
1873
-            PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
1935
+        foreach ($this->elements as $node) {
1936
+                    PhpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
1937
+        }
1874 1938
         return $this;
1875 1939
     }
1876 1940
 
@@ -1882,8 +1946,9 @@  discard block
 block discarded – undo
1882 1946
      */
1883 1947
     public function change($callback = null)
1884 1948
     {
1885
-        if ($callback)
1886
-            return $this->bind('change', $callback);
1949
+        if ($callback) {
1950
+                    return $this->bind('change', $callback);
1951
+        }
1887 1952
         return $this->trigger('change');
1888 1953
     }
1889 1954
 
@@ -1895,8 +1960,9 @@  discard block
 block discarded – undo
1895 1960
      */
1896 1961
     public function submit($callback = null)
1897 1962
     {
1898
-        if ($callback)
1899
-            return $this->bind('submit', $callback);
1963
+        if ($callback) {
1964
+                    return $this->bind('submit', $callback);
1965
+        }
1900 1966
         return $this->trigger('submit');
1901 1967
     }
1902 1968
 
@@ -1908,8 +1974,9 @@  discard block
 block discarded – undo
1908 1974
      */
1909 1975
     public function click($callback = null)
1910 1976
     {
1911
-        if ($callback)
1912
-            return $this->bind('click', $callback);
1977
+        if ($callback) {
1978
+                    return $this->bind('click', $callback);
1979
+        }
1913 1980
         return $this->trigger('click');
1914 1981
     }
1915 1982
 
@@ -1922,12 +1989,14 @@  discard block
 block discarded – undo
1922 1989
     public function wrapAllOld($wrapper)
1923 1990
     {
1924 1991
         $wrapper = pq($wrapper)->_clone();
1925
-        if (!$wrapper->length() || !$this->length())
1926
-            return $this;
1992
+        if (!$wrapper->length() || !$this->length()) {
1993
+                    return $this;
1994
+        }
1927 1995
         $wrapper->insertBefore($this->elements[0]);
1928 1996
         $deepest = $wrapper->elements[0];
1929
-        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1930
-            $deepest = $deepest->firstChild;
1997
+        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) {
1998
+                    $deepest = $deepest->firstChild;
1999
+        }
1931 2000
         pq($deepest)->append($this);
1932 2001
         return $this;
1933 2002
     }
@@ -1941,8 +2010,9 @@  discard block
 block discarded – undo
1941 2010
      */
1942 2011
     public function wrapAll($wrapper)
1943 2012
     {
1944
-        if (!$this->length())
1945
-            return $this;
2013
+        if (!$this->length()) {
2014
+                    return $this;
2015
+        }
1946 2016
         return PhpQuery::pq($wrapper, $this->getDocumentID())->clone()->insertBefore($this->get(0))->map(
1947 2017
             array(
1948 2018
                 $this,
@@ -1960,8 +2030,9 @@  discard block
 block discarded – undo
1960 2030
     public function ___wrapAllCallback($node)
1961 2031
     {
1962 2032
         $deepest = $node;
1963
-        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement)
1964
-            $deepest = $deepest->firstChild;
2033
+        while ($deepest->firstChild && $deepest->firstChild instanceof \DOMElement) {
2034
+                    $deepest = $deepest->firstChild;
2035
+        }
1965 2036
         return $deepest;
1966 2037
     }
1967 2038
 
@@ -1987,8 +2058,9 @@  discard block
 block discarded – undo
1987 2058
      */
1988 2059
     public function wrap($wrapper)
1989 2060
     {
1990
-        foreach ($this->stack() as $node)
1991
-            PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
2061
+        foreach ($this->stack() as $node) {
2062
+                    PhpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
2063
+        }
1992 2064
         return $this;
1993 2065
     }
1994 2066
 
@@ -2002,8 +2074,9 @@  discard block
 block discarded – undo
2002 2074
      */
2003 2075
     public function wrapPHP($codeBefore, $codeAfter)
2004 2076
     {
2005
-        foreach ($this->stack() as $node)
2006
-            PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
2077
+        foreach ($this->stack() as $node) {
2078
+                    PhpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
2079
+        }
2007 2080
         return $this;
2008 2081
     }
2009 2082
 
@@ -2015,8 +2088,9 @@  discard block
 block discarded – undo
2015 2088
      */
2016 2089
     public function wrapInner($wrapper)
2017 2090
     {
2018
-        foreach ($this->stack() as $node)
2019
-            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
2091
+        foreach ($this->stack() as $node) {
2092
+                    PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
2093
+        }
2020 2094
         return $this;
2021 2095
     }
2022 2096
 
@@ -2030,8 +2104,9 @@  discard block
 block discarded – undo
2030 2104
      */
2031 2105
     public function wrapInnerPHP($codeBefore, $codeAfter)
2032 2106
     {
2033
-        foreach ($this->stack(1) as $node)
2034
-            PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
2107
+        foreach ($this->stack(1) as $node) {
2108
+                    PhpQuery::pq($node, $this->getDocumentID())->contents()->wrapAllPHP($codeBefore, $codeAfter);
2109
+        }
2035 2110
         return $this;
2036 2111
     }
2037 2112
 
@@ -2065,15 +2140,18 @@  discard block
 block discarded – undo
2065 2140
     public function contentsUnwrap()
2066 2141
     {
2067 2142
         foreach ($this->stack(1) as $node) {
2068
-            if (!$node->parentNode)
2069
-                continue;
2143
+            if (!$node->parentNode) {
2144
+                            continue;
2145
+            }
2070 2146
             $childNodes = array();
2071 2147
             // any modification in DOM tree breaks childNodes iteration, so cache them first
2072
-            foreach ($node->childNodes as $chNode)
2073
-                $childNodes[] = $chNode;
2074
-            foreach ($childNodes as $chNode)
2075
-                //				$node->parentNode->appendChild($chNode);
2148
+            foreach ($node->childNodes as $chNode) {
2149
+                            $childNodes[] = $chNode;
2150
+            }
2151
+            foreach ($childNodes as $chNode) {
2152
+                            //				$node->parentNode->appendChild($chNode);
2076 2153
                 $node->parentNode->insertBefore($chNode, $node);
2154
+            }
2077 2155
             $node->parentNode->removeChild($node);
2078 2156
         }
2079 2157
         return $this;
@@ -2105,8 +2183,9 @@  discard block
 block discarded – undo
2105 2183
         $oldStack             = $this->elements;
2106 2184
         $this->elementsBackup = $this->elements;
2107 2185
         $this->elements       = array();
2108
-        if (isset($oldStack[$num]))
2109
-            $this->elements[] = $oldStack[$num];
2186
+        if (isset($oldStack[$num])) {
2187
+                    $this->elements[] = $oldStack[$num];
2188
+        }
2110 2189
         return $this->newInstance();
2111 2190
     }
2112 2191
 
@@ -2204,8 +2283,9 @@  discard block
 block discarded – undo
2204 2283
      */
2205 2284
     public function replaceAll($selector)
2206 2285
     {
2207
-        foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node)
2208
-            PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
2286
+        foreach (PhpQuery::pq($selector, $this->getDocumentID()) as $node) {
2287
+                    PhpQuery::pq($node, $this->getDocumentID())->after($this->_clone())->remove();
2288
+        }
2209 2289
         return $this;
2210 2290
     }
2211 2291
 
@@ -2218,10 +2298,12 @@  discard block
 block discarded – undo
2218 2298
     {
2219 2299
         $loop = $selector ? $this->filter($selector)->elements : $this->elements;
2220 2300
         foreach ($loop as $node) {
2221
-            if (!$node->parentNode)
2222
-                continue;
2223
-            if (isset($node->tagName))
2224
-                $this->debug("Removing '{$node->tagName}'");
2301
+            if (!$node->parentNode) {
2302
+                            continue;
2303
+            }
2304
+            if (isset($node->tagName)) {
2305
+                            $this->debug("Removing '{$node->tagName}'");
2306
+            }
2225 2307
             $node->parentNode->removeChild($node);
2226 2308
             // Mutation event
2227 2309
             $event = new Dom\DOMEvent(array(
@@ -2271,22 +2353,23 @@  discard block
 block discarded – undo
2271 2353
     public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null)
2272 2354
     {
2273 2355
         $args = func_get_args();
2274
-        if ($this->documentWrapper->isXML)
2275
-            return call_user_func_array(
2356
+        if ($this->documentWrapper->isXML) {
2357
+                    return call_user_func_array(
2276 2358
                 array(
2277 2359
                     $this,
2278 2360
                     'xml'
2279 2361
                 ),
2280 2362
                 $args
2281 2363
             );
2282
-        else
2283
-            return call_user_func_array(
2364
+        } else {
2365
+                    return call_user_func_array(
2284 2366
                 array(
2285 2367
                     $this,
2286 2368
                     'html'
2287 2369
                 ),
2288 2370
                 $args
2289 2371
             );
2372
+        }
2290 2373
     }
2291 2374
 
2292 2375
     /**
@@ -2301,22 +2384,23 @@  discard block
 block discarded – undo
2301 2384
     public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null)
2302 2385
     {
2303 2386
         $args = func_get_args();
2304
-        if ($this->documentWrapper->isXML)
2305
-            return call_user_func_array(
2387
+        if ($this->documentWrapper->isXML) {
2388
+                    return call_user_func_array(
2306 2389
                 array(
2307 2390
                     $this,
2308 2391
                     'xmlOuter'
2309 2392
                 ),
2310 2393
                 $args
2311 2394
             );
2312
-        else
2313
-            return call_user_func_array(
2395
+        } else {
2396
+                    return call_user_func_array(
2314 2397
                 array(
2315 2398
                     $this,
2316 2399
                     'htmlOuter'
2317 2400
                 ),
2318 2401
                 $args
2319 2402
             );
2403
+        }
2320 2404
     }
2321 2405
 
2322 2406
     /**
@@ -2339,8 +2423,9 @@  discard block
 block discarded – undo
2339 2423
                 // for now, limit events for textarea
2340 2424
                 if (($this->isXHTML() || $this->isHTML())
2341 2425
                     && $node->tagName == 'textarea'
2342
-                )
2343
-                    $oldHtml = pq($node, $this->getDocumentID())->markup();
2426
+                ) {
2427
+                                    $oldHtml = pq($node, $this->getDocumentID())->markup();
2428
+                }
2344 2429
                 foreach ($nodes as $newNode) {
2345 2430
                     $node->appendChild(
2346 2431
                         $alreadyAdded ? $newNode->cloneNode(true)
@@ -2350,8 +2435,9 @@  discard block
 block discarded – undo
2350 2435
                 // for now, limit events for textarea
2351 2436
                 if (($this->isXHTML() || $this->isHTML())
2352 2437
                     && $node->tagName == 'textarea'
2353
-                )
2354
-                    $this->markupEvents($html, $oldHtml, $node);
2438
+                ) {
2439
+                                    $this->markupEvents($html, $oldHtml, $node);
2440
+                }
2355 2441
             }
2356 2442
             return $this;
2357 2443
         } else {
@@ -2477,12 +2563,15 @@  discard block
 block discarded – undo
2477 2563
         foreach ($this->stack(1) as $node) {
2478 2564
             //			foreach($node->getElementsByTagName('*') as $newNode) {
2479 2565
             foreach ($node->childNodes as $newNode) {
2480
-                if ($newNode->nodeType != 1)
2481
-                    continue;
2482
-                if ($selector && !$this->is($selector, $newNode))
2483
-                    continue;
2484
-                if ($this->elementsContainsNode($newNode, $stack))
2485
-                    continue;
2566
+                if ($newNode->nodeType != 1) {
2567
+                                    continue;
2568
+                }
2569
+                if ($selector && !$this->is($selector, $newNode)) {
2570
+                                    continue;
2571
+                }
2572
+                if ($this->elementsContainsNode($newNode, $stack)) {
2573
+                                    continue;
2574
+                }
2486 2575
                 $stack[] = $newNode;
2487 2576
             }
2488 2577
         }
@@ -2684,25 +2773,27 @@  discard block
 block discarded – undo
2684 2773
                 if ($target instanceof self) {
2685 2774
                     if ($to) {
2686 2775
                         $insertTo = $target->elements;
2687
-                        if ($this->documentFragment && $this->stackIsRoot())
2688
-                            // get all body children
2776
+                        if ($this->documentFragment && $this->stackIsRoot()) {
2777
+                                                    // get all body children
2689 2778
                             //							$loop = $this->find('body > *')->elements;
2690 2779
                             // TODO test it, test it hard...
2691 2780
                             //							$loop = $this->newInstance($this->root)->find('> *')->elements;
2692 2781
                             $loop = $this->root->childNodes;
2693
-                        else
2694
-                            $loop = $this->elements;
2782
+                        } else {
2783
+                                                    $loop = $this->elements;
2784
+                        }
2695 2785
                         // import nodes if needed
2696 2786
                         $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2697 2787
                             : $target->documentWrapper->import($loop);
2698 2788
                     } else {
2699 2789
                         $insertTo = $this->elements;
2700
-                        if ($target->documentFragment && $target->stackIsRoot())
2701
-                            // get all body children
2790
+                        if ($target->documentFragment && $target->stackIsRoot()) {
2791
+                                                    // get all body children
2702 2792
                             //							$loop = $target->find('body > *')->elements;
2703 2793
                             $loop = $target->root->childNodes;
2704
-                        else
2705
-                            $loop = $target->elements;
2794
+                        } else {
2795
+                                                    $loop = $target->elements;
2796
+                        }
2706 2797
                         // import nodes if needed
2707 2798
                         $insertFrom = $this->getDocumentID() == $target->getDocumentID() ? $loop
2708 2799
                             : $this->documentWrapper->import($loop);
@@ -2716,22 +2807,26 @@  discard block
 block discarded – undo
2716 2807
                         $insertTo = array(
2717 2808
                             $target
2718 2809
                         );
2719
-                        if ($this->documentFragment && $this->stackIsRoot())
2720
-                            // get all body children
2810
+                        if ($this->documentFragment && $this->stackIsRoot()) {
2811
+                                                    // get all body children
2721 2812
                             $loop = $this->root->childNodes;
2813
+                        }
2722 2814
                         //							$loop = $this->find('body > *')->elements;
2723
-                        else
2724
-                            $loop = $this->elements;
2725
-                        foreach ($loop as $fromNode)
2726
-                            // import nodes if needed
2815
+                        else {
2816
+                                                    $loop = $this->elements;
2817
+                        }
2818
+                        foreach ($loop as $fromNode) {
2819
+                                                    // import nodes if needed
2727 2820
                             $insertFrom[] = !$fromNode->ownerDocument->isSameNode(
2728 2821
                                 $target->ownerDocument
2729 2822
                             ) ? $target->ownerDocument->importNode($fromNode, true)
2730 2823
                                 : $fromNode;
2824
+                        }
2731 2825
                     } else {
2732 2826
                         // import node if needed
2733
-                        if (!$target->ownerDocument->isSameNode($this->document))
2734
-                            $target = $this->document->importNode($target, true);
2827
+                        if (!$target->ownerDocument->isSameNode($this->document)) {
2828
+                                                    $target = $this->document->importNode($target, true);
2829
+                        }
2735 2830
                         $insertTo     = $this->elements;
2736 2831
                         $insertFrom[] = $target;
2737 2832
                     }
@@ -2773,17 +2868,19 @@  discard block
 block discarded – undo
2773 2868
                         break;
2774 2869
                     case 'insertBefore':
2775 2870
                     case 'before':
2776
-                        if (!$toNode->parentNode)
2777
-                            throw new \Exception("No parentNode, can't do {$type}()");
2778
-                        else
2779
-                            $toNode->parentNode->insertBefore($insert, $toNode);
2871
+                        if (!$toNode->parentNode) {
2872
+                                                    throw new \Exception("No parentNode, can't do {$type}()");
2873
+                        } else {
2874
+                                                    $toNode->parentNode->insertBefore($insert, $toNode);
2875
+                        }
2780 2876
                         break;
2781 2877
                     case 'insertAfter':
2782 2878
                     case 'after':
2783
-                        if (!$toNode->parentNode)
2784
-                            throw new \Exception("No parentNode, can't do {$type}()");
2785
-                        else
2786
-                            $toNode->parentNode->insertBefore($insert, $nextSibling);
2879
+                        if (!$toNode->parentNode) {
2880
+                                                    throw new \Exception("No parentNode, can't do {$type}()");
2881
+                        } else {
2882
+                                                    $toNode->parentNode->insertBefore($insert, $nextSibling);
2883
+                        }
2787 2884
                         break;
2788 2885
                 }
2789 2886
                 // Mutation event
@@ -2816,8 +2913,9 @@  discard block
 block discarded – undo
2816 2913
         $subject = $subject instanceof PhpQueryObject ? $subject->elements[0]
2817 2914
             : $subject;
2818 2915
         foreach ($this->newInstance() as $k => $node) {
2819
-            if ($node->isSameNode($subject))
2820
-                $index = $k;
2916
+            if ($node->isSameNode($subject)) {
2917
+                            $index = $k;
2918
+            }
2821 2919
         }
2822 2920
         return $index;
2823 2921
     }
@@ -2841,8 +2939,9 @@  discard block
 block discarded – undo
2841 2939
         //			$start = $last+$start;
2842 2940
         //		if ($start > $last)
2843 2941
         //			return array();
2844
-        if ($end > 0)
2845
-            $end = $end - $start;
2942
+        if ($end > 0) {
2943
+                    $end = $end - $start;
2944
+        }
2846 2945
         return $this->newInstance(array_slice($this->elements, $start, $end));
2847 2946
     }
2848 2947
 
@@ -2868,15 +2967,17 @@  discard block
 block discarded – undo
2868 2967
      */
2869 2968
     public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null)
2870 2969
     {
2871
-        if (isset($text))
2872
-            return $this->html(htmlspecialchars($text));
2970
+        if (isset($text)) {
2971
+                    return $this->html(htmlspecialchars($text));
2972
+        }
2873 2973
         $args   = func_get_args();
2874 2974
         $args   = array_slice($args, 1);
2875 2975
         $return = '';
2876 2976
         foreach ($this->elements as $node) {
2877 2977
             $text = $node->textContent;
2878
-            if (count($this->elements) > 1 && $text)
2879
-                $text .= "\n";
2978
+            if (count($this->elements) > 1 && $text) {
2979
+                            $text .= "\n";
2980
+            }
2880 2981
             foreach ($args as $callback) {
2881 2982
                 $text = PhpQuery::callbackRun(
2882 2983
                     $callback,
@@ -2969,8 +3070,9 @@  discard block
 block discarded – undo
2969 3070
                 ),
2970 3071
                 $args
2971 3072
             );
2972
-        } else
2973
-            throw new \Exception("Method '{$method}' doesnt exist");
3073
+        } else {
3074
+                    throw new \Exception("Method '{$method}' doesnt exist");
3075
+        }
2974 3076
     }
2975 3077
 
2976 3078
     /**
@@ -3043,11 +3145,13 @@  discard block
 block discarded – undo
3043 3145
             $test = $node;
3044 3146
             while (isset($test->{$direction}) && $test->{$direction}) {
3045 3147
                 $test = $test->{$direction};
3046
-                if (!$test instanceof \DOMElement)
3047
-                    continue;
3148
+                if (!$test instanceof \DOMElement) {
3149
+                                    continue;
3150
+                }
3048 3151
                 $stack[] = $test;
3049
-                if ($limitToOne)
3050
-                    break;
3152
+                if ($limitToOne) {
3153
+                                    break;
3154
+                }
3051 3155
             }
3052 3156
         }
3053 3157
         if ($selector) {
@@ -3073,8 +3177,9 @@  discard block
 block discarded – undo
3073 3177
             $this->getElementSiblings('nextSibling', $selector)
3074 3178
         );
3075 3179
         foreach ($siblings as $node) {
3076
-            if (!$this->elementsContainsNode($node, $stack))
3077
-                $stack[] = $node;
3180
+            if (!$this->elementsContainsNode($node, $stack)) {
3181
+                            $stack[] = $node;
3182
+            }
3078 3183
         }
3079 3184
         return $this->newInstance($stack);
3080 3185
     }
@@ -3087,32 +3192,37 @@  discard block
 block discarded – undo
3087 3192
      */
3088 3193
     public function not($selector = null)
3089 3194
     {
3090
-        if (is_string($selector))
3091
-            PhpQuery::debug(
3195
+        if (is_string($selector)) {
3196
+                    PhpQuery::debug(
3092 3197
                 array(
3093 3198
                     'not',
3094 3199
                     $selector
3095 3200
                 )
3096 3201
             );
3097
-        else
3098
-            PhpQuery::debug('not');
3202
+        } else {
3203
+                    PhpQuery::debug('not');
3204
+        }
3099 3205
         $stack = array();
3100 3206
         if ($selector instanceof self || $selector instanceof \DOMNODE) {
3101 3207
             foreach ($this->stack() as $node) {
3102 3208
                 if ($selector instanceof self) {
3103 3209
                     $matchFound = false;
3104 3210
                     foreach ($selector->stack() as $notNode) {
3105
-                        if ($notNode->isSameNode($node))
3106
-                            $matchFound = true;
3211
+                        if ($notNode->isSameNode($node)) {
3212
+                                                    $matchFound = true;
3213
+                        }
3214
+                    }
3215
+                    if (!$matchFound) {
3216
+                                            $stack[] = $node;
3107 3217
                     }
3108
-                    if (!$matchFound)
3109
-                        $stack[] = $node;
3110 3218
                 } else if ($selector instanceof \DOMNODE) {
3111
-                    if (!$selector->isSameNode($node))
3112
-                        $stack[] = $node;
3219
+                    if (!$selector->isSameNode($node)) {
3220
+                                            $stack[] = $node;
3221
+                    }
3113 3222
                 } else {
3114
-                    if (!$this->is($selector))
3115
-                        $stack[] = $node;
3223
+                    if (!$this->is($selector)) {
3224
+                                            $stack[] = $node;
3225
+                    }
3116 3226
                 }
3117 3227
             }
3118 3228
         } else {
@@ -3125,9 +3235,10 @@  discard block
 block discarded – undo
3125 3235
             //					$this->filter(array($s))->stack()
3126 3236
             //				);
3127 3237
             //			}
3128
-            foreach ($orgStack as $node)
3129
-                if (!$this->elementsContainsNode($node, $matched))
3238
+            foreach ($orgStack as $node) {
3239
+                            if (!$this->elementsContainsNode($node, $matched))
3130 3240
                     $stack[] = $node;
3241
+            }
3131 3242
         }
3132 3243
         return $this->newInstance($stack);
3133 3244
     }
@@ -3140,8 +3251,9 @@  discard block
 block discarded – undo
3140 3251
      */
3141 3252
     public function add($selector = null)
3142 3253
     {
3143
-        if (!$selector)
3144
-            return $this;
3254
+        if (!$selector) {
3255
+                    return $this;
3256
+        }
3145 3257
         $stack                = array();
3146 3258
         $this->elementsBackup = $this->elements;
3147 3259
         $found                = PhpQuery::pq($selector, $this->getDocumentID());
@@ -3154,10 +3266,11 @@  discard block
 block discarded – undo
3154 3266
      */
3155 3267
     protected function merge()
3156 3268
     {
3157
-        foreach (func_get_args() as $nodes)
3158
-            foreach ($nodes as $newNode)
3269
+        foreach (func_get_args() as $nodes) {
3270
+                    foreach ($nodes as $newNode)
3159 3271
                 if (!$this->elementsContainsNode($newNode))
3160 3272
                     $this->elements[] = $newNode;
3273
+        }
3161 3274
     }
3162 3275
 
3163 3276
     /**
@@ -3168,8 +3281,9 @@  discard block
 block discarded – undo
3168 3281
     {
3169 3282
         $loop = !is_null($elementsStack) ? $elementsStack : $this->elements;
3170 3283
         foreach ($loop as $node) {
3171
-            if ($node->isSameNode($nodeToCheck))
3172
-                return true;
3284
+            if ($node->isSameNode($nodeToCheck)) {
3285
+                            return true;
3286
+            }
3173 3287
         }
3174 3288
         return false;
3175 3289
     }
@@ -3183,15 +3297,17 @@  discard block
 block discarded – undo
3183 3297
     public function parent($selector = null)
3184 3298
     {
3185 3299
         $stack = array();
3186
-        foreach ($this->elements as $node)
3187
-            if ($node->parentNode
3300
+        foreach ($this->elements as $node) {
3301
+                    if ($node->parentNode
3188 3302
                 && !$this->elementsContainsNode($node->parentNode, $stack)
3189 3303
             )
3190 3304
                 $stack[] = $node->parentNode;
3305
+        }
3191 3306
         $this->elementsBackup = $this->elements;
3192 3307
         $this->elements       = $stack;
3193
-        if ($selector)
3194
-            $this->filter($selector, true);
3308
+        if ($selector) {
3309
+                    $this->filter($selector, true);
3310
+        }
3195 3311
         return $this->newInstance();
3196 3312
     }
3197 3313
 
@@ -3204,14 +3320,16 @@  discard block
 block discarded – undo
3204 3320
     public function parents($selector = null)
3205 3321
     {
3206 3322
         $stack = array();
3207
-        if (!$this->elements)
3208
-            $this->debug('parents() - stack empty');
3323
+        if (!$this->elements) {
3324
+                    $this->debug('parents() - stack empty');
3325
+        }
3209 3326
         foreach ($this->elements as $node) {
3210 3327
             $test = $node;
3211 3328
             while ($test->parentNode) {
3212 3329
                 $test = $test->parentNode;
3213
-                if ($this->isRoot($test))
3214
-                    break;
3330
+                if ($this->isRoot($test)) {
3331
+                                    break;
3332
+                }
3215 3333
                 if (!$this->elementsContainsNode($test, $stack)) {
3216 3334
                     $stack[] = $test;
3217 3335
                     continue;
@@ -3220,8 +3338,9 @@  discard block
 block discarded – undo
3220 3338
         }
3221 3339
         $this->elementsBackup = $this->elements;
3222 3340
         $this->elements       = $stack;
3223
-        if ($selector)
3224
-            $this->filter($selector, true);
3341
+        if ($selector) {
3342
+                    $this->filter($selector, true);
3343
+        }
3225 3344
         return $this->newInstance();
3226 3345
     }
3227 3346
 
@@ -3234,16 +3353,19 @@  discard block
 block discarded – undo
3234 3353
      */
3235 3354
     public function stack($nodeTypes = null)
3236 3355
     {
3237
-        if (!isset($nodeTypes))
3238
-            return $this->elements;
3239
-        if (!is_array($nodeTypes))
3240
-            $nodeTypes = array(
3356
+        if (!isset($nodeTypes)) {
3357
+                    return $this->elements;
3358
+        }
3359
+        if (!is_array($nodeTypes)) {
3360
+                    $nodeTypes = array(
3241 3361
                 $nodeTypes
3242 3362
             );
3363
+        }
3243 3364
         $return = array();
3244 3365
         foreach ($this->elements as $node) {
3245
-            if (in_array($node->nodeType, $nodeTypes))
3246
-                $return[] = $node;
3366
+            if (in_array($node->nodeType, $nodeTypes)) {
3367
+                            $return[] = $node;
3368
+            }
3247 3369
         }
3248 3370
         return $return;
3249 3371
     }
@@ -3252,8 +3374,9 @@  discard block
 block discarded – undo
3252 3374
     protected function attrEvents($attr, $oldAttr, $oldValue, $node)
3253 3375
     {
3254 3376
         // skip events for XML documents
3255
-        if (!$this->isXHTML() && !$this->isHTML())
3256
-            return;
3377
+        if (!$this->isXHTML() && !$this->isHTML()) {
3378
+                    return;
3379
+        }
3257 3380
         $event = null;
3258 3381
         // identify
3259 3382
         $isInputValue = $node->tagName == 'input'
@@ -3331,11 +3454,13 @@  discard block
 block discarded – undo
3331 3454
             } else if ($attr == '*') {
3332 3455
                 // jQuery difference
3333 3456
                 $return = array();
3334
-                foreach ($node->attributes as $n => $v)
3335
-                    $return[$n] = $v->value;
3457
+                foreach ($node->attributes as $n => $v) {
3458
+                                    $return[$n] = $v->value;
3459
+                }
3336 3460
                 return $return;
3337
-            } else
3338
-                return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null;
3461
+            } else {
3462
+                            return $node->hasAttribute($attr) ? $node->getAttribute($attr) : null;
3463
+            }
3339 3464
         }
3340 3465
         return is_null($value) ? '' : $this;
3341 3466
     }
@@ -3362,8 +3487,9 @@  discard block
 block discarded – undo
3362 3487
     protected function getNodeAttrs($node)
3363 3488
     {
3364 3489
         $return = array();
3365
-        foreach ($node->attributes as $n => $o)
3366
-            $return[] = $n;
3490
+        foreach ($node->attributes as $n => $o) {
3491
+                    $return[] = $n;
3492
+        }
3367 3493
         return $return;
3368 3494
     }
3369 3495
 
@@ -3393,11 +3519,13 @@  discard block
 block discarded – undo
3393 3519
             } else if ($attr == '*') {
3394 3520
                 // jQuery diff
3395 3521
                 $return = array();
3396
-                foreach ($node->attributes as $n => $v)
3397
-                    $return[$n] = $v->value;
3522
+                foreach ($node->attributes as $n => $v) {
3523
+                                    $return[$n] = $v->value;
3524
+                }
3398 3525
                 return $return;
3399
-            } else
3400
-                return $node->getAttribute($attr);
3526
+            } else {
3527
+                            return $node->getAttribute($attr);
3528
+            }
3401 3529
         }
3402 3530
         return $this;
3403 3531
     }
@@ -3435,14 +3563,16 @@  discard block
 block discarded – undo
3435 3563
         if (!isset($val)) {
3436 3564
             if ($this->eq(0)->is('select')) {
3437 3565
                 $selected = $this->eq(0)->find('option[selected=selected]');
3438
-                if ($selected->is('[value]'))
3439
-                    return $selected->attr('value');
3440
-                else
3441
-                    return $selected->text();
3442
-            } else if ($this->eq(0)->is('textarea'))
3443
-                return $this->eq(0)->markup();
3444
-            else
3445
-                return $this->eq(0)->attr('value');
3566
+                if ($selected->is('[value]')) {
3567
+                                    return $selected->attr('value');
3568
+                } else {
3569
+                                    return $selected->text();
3570
+                }
3571
+            } else if ($this->eq(0)->is('textarea')) {
3572
+                            return $this->eq(0)->markup();
3573
+            } else {
3574
+                            return $this->eq(0)->attr('value');
3575
+            }
3446 3576
         } else {
3447 3577
             $_val = null;
3448 3578
             foreach ($this->stack(1) as $node) {
@@ -3458,20 +3588,22 @@  discard block
 block discarded – undo
3458 3588
                 ) {
3459 3589
                     $isChecked = in_array($node->attr('value'), $val)
3460 3590
                         || in_array($node->attr('name'), $val);
3461
-                    if ($isChecked)
3462
-                        $node->attr('checked', 'checked');
3463
-                    else
3464
-                        $node->removeAttr('checked');
3591
+                    if ($isChecked) {
3592
+                                            $node->attr('checked', 'checked');
3593
+                    } else {
3594
+                                            $node->removeAttr('checked');
3595
+                    }
3465 3596
                 } else if ($node->get(0)->tagName == 'select') {
3466 3597
                     if (!isset($_val)) {
3467 3598
                         $_val = array();
3468
-                        if (!is_array($val))
3469
-                            $_val = array(
3599
+                        if (!is_array($val)) {
3600
+                                                    $_val = array(
3470 3601
                                 (string) $val
3471 3602
                             );
3472
-                        else
3473
-                            foreach ($val as $v)
3603
+                        } else {
3604
+                                                    foreach ($val as $v)
3474 3605
                                 $_val[] = $v;
3606
+                        }
3475 3607
                     }
3476 3608
                     foreach ($node['option']->stack(1) as $option) {
3477 3609
                         $option   = pq($option, $this->getDocumentID());
@@ -3488,15 +3620,17 @@  discard block
 block discarded – undo
3488 3620
                         //								$selected = true;
3489 3621
                         //							else if ($optionText == $v && $optionTextLenght == mb_strlen($v))
3490 3622
                         //								$selected = true;
3491
-                        if ($selected)
3492
-                            $option->attr('selected', 'selected');
3493
-                        else
3494
-                            $option->removeAttr('selected');
3623
+                        if ($selected) {
3624
+                                                    $option->attr('selected', 'selected');
3625
+                        } else {
3626
+                                                    $option->removeAttr('selected');
3627
+                        }
3495 3628
                     }
3496
-                } else if ($node->get(0)->tagName == 'textarea')
3497
-                    $node->markup($val);
3498
-                else
3499
-                    $node->attr('value', $val);
3629
+                } else if ($node->get(0)->tagName == 'textarea') {
3630
+                                    $node->markup($val);
3631
+                } else {
3632
+                                    $node->attr('value', $val);
3633
+                }
3500 3634
             }
3501 3635
         }
3502 3636
         return $this;
@@ -3509,8 +3643,9 @@  discard block
 block discarded – undo
3509 3643
      */
3510 3644
     public function andSelf()
3511 3645
     {
3512
-        if ($this->previous)
3513
-            $this->elements = array_merge($this->elements, $this->previous->elements);
3646
+        if ($this->previous) {
3647
+                    $this->elements = array_merge($this->elements, $this->previous->elements);
3648
+        }
3514 3649
         return $this;
3515 3650
     }
3516 3651
 
@@ -3522,17 +3657,19 @@  discard block
 block discarded – undo
3522 3657
      */
3523 3658
     public function addClass($className)
3524 3659
     {
3525
-        if (!$className)
3526
-            return $this;
3660
+        if (!$className) {
3661
+                    return $this;
3662
+        }
3527 3663
         foreach ($this->stack(1) as $node) {
3528
-            if (!$this->is(".$className", $node))
3529
-                $node->setAttribute(
3664
+            if (!$this->is(".$className", $node)) {
3665
+                            $node->setAttribute(
3530 3666
                     'class',
3531 3667
                     trim(
3532 3668
                         $node->getAttribute('class') . ' '
3533 3669
                         . $className
3534 3670
                     )
3535 3671
                 );
3672
+            }
3536 3673
         }
3537 3674
         return $this;
3538 3675
     }
@@ -3563,8 +3700,9 @@  discard block
 block discarded – undo
3563 3700
     public function hasClass($className)
3564 3701
     {
3565 3702
         foreach ($this->stack(1) as $node) {
3566
-            if ($this->is(".$className", $node))
3567
-                return true;
3703
+            if ($this->is(".$className", $node)) {
3704
+                            return true;
3705
+            }
3568 3706
         }
3569 3707
         return false;
3570 3708
     }
@@ -3586,10 +3724,11 @@  discard block
 block discarded – undo
3586 3724
                         $className
3587 3725
                     )
3588 3726
                 );
3589
-                if ($classes)
3590
-                    $node->setAttribute('class', implode(' ', $classes));
3591
-                else
3592
-                    $node->removeAttribute('class');
3727
+                if ($classes) {
3728
+                                    $node->setAttribute('class', implode(' ', $classes));
3729
+                } else {
3730
+                                    $node->removeAttribute('class');
3731
+                }
3593 3732
             }
3594 3733
         }
3595 3734
         return $this;
@@ -3604,10 +3743,11 @@  discard block
 block discarded – undo
3604 3743
     public function toggleClass($className)
3605 3744
     {
3606 3745
         foreach ($this->stack(1) as $node) {
3607
-            if ($this->is($node, '.' . $className))
3608
-                $this->removeClass($className);
3609
-            else
3610
-                $this->addClass($className);
3746
+            if ($this->is($node, '.' . $className)) {
3747
+                            $this->removeClass($className);
3748
+            } else {
3749
+                            $this->addClass($className);
3750
+            }
3611 3751
         }
3612 3752
         return $this;
3613 3753
     }
@@ -3657,14 +3797,15 @@  discard block
 block discarded – undo
3657 3797
             $paramStructure = func_get_args();
3658 3798
             $paramStructure = array_slice($paramStructure, 1);
3659 3799
         }
3660
-        foreach ($this->elements as $v)
3661
-            PhpQuery::callbackRun(
3800
+        foreach ($this->elements as $v) {
3801
+                    PhpQuery::callbackRun(
3662 3802
                 $callback,
3663 3803
                 array(
3664 3804
                     $v
3665 3805
                 ),
3666 3806
                 $paramStructure
3667 3807
             );
3808
+        }
3668 3809
         return $this;
3669 3810
     }
3670 3811
 
@@ -3732,8 +3873,9 @@  discard block
 block discarded – undo
3732 3873
             // is child which we look up doesn't exist
3733 3874
             return PhpQuery::data($this->get(0), $key, $value, $this->getDocumentID());
3734 3875
         } else {
3735
-            foreach ($this as $node)
3736
-                PhpQuery::data($node, $key, $value, $this->getDocumentID());
3876
+            foreach ($this as $node) {
3877
+                            PhpQuery::data($node, $key, $value, $this->getDocumentID());
3878
+            }
3737 3879
             return $this;
3738 3880
         }
3739 3881
     }
@@ -3746,8 +3888,9 @@  discard block
 block discarded – undo
3746 3888
      */
3747 3889
     public function removeData($key)
3748 3890
     {
3749
-        foreach ($this as $node)
3750
-            PhpQuery::removeData($node, $key, $this->getDocumentID());
3891
+        foreach ($this as $node) {
3892
+                    PhpQuery::removeData($node, $key, $this->getDocumentID());
3893
+        }
3751 3894
         return $this;
3752 3895
     }
3753 3896
     // INTERFACE IMPLEMENTATIONS
@@ -3884,8 +4027,9 @@  discard block
 block discarded – undo
3884 4027
                 while ($sibling->previousSibling) {
3885 4028
                     $sibling   = $sibling->previousSibling;
3886 4029
                     $isElement = $sibling instanceof \DOMElement;
3887
-                    if ($isElement && $sibling->tagName == $node->tagName)
3888
-                        $i++;
4030
+                    if ($isElement && $sibling->tagName == $node->tagName) {
4031
+                                            $i++;
4032
+                    }
3889 4033
                 }
3890 4034
                 $xpath[] = $this->isXML() ? "*[local-name()='{$node->tagName}'][{$i}]"
3891 4035
                     : "{$node->tagName}[{$i}]";
@@ -3928,9 +4072,10 @@  discard block
 block discarded – undo
3928 4072
                         : '') . ($node->getAttribute('selected') ? '[selected]' : '')
3929 4073
                     . ($node->getAttribute('checked') ? '[checked]' : '');
3930 4074
             } else if ($node instanceof \DOMTEXT) {
3931
-                if (trim($node->textContent))
3932
-                    $return[] = 'Text:'
4075
+                if (trim($node->textContent)) {
4076
+                                    $return[] = 'Text:'
3933 4077
                         . substr(str_replace("\n", ' ', $node->textContent), 0, 15);
4078
+                }
3934 4079
             } else {
3935 4080
 
3936 4081
             }
@@ -3980,8 +4125,9 @@  discard block
 block discarded – undo
3980 4125
         $output          = $title ? 'DUMP #' . (PhpQuery::$dumpCount++) . " \n" : '';
3981 4126
         $debug           = PhpQuery::$debug;
3982 4127
         PhpQuery::$debug = false;
3983
-        foreach ($this->stack() as $node)
3984
-            $output .= $this->__dumpTree($node);
4128
+        foreach ($this->stack() as $node) {
4129
+                    $output .= $this->__dumpTree($node);
4130
+        }
3985 4131
         PhpQuery::$debug = $debug;
3986 4132
         print $html ? nl2br(str_replace(' ', '&nbsp;', $output)) : $output;
3987 4133
         return $this;
@@ -3991,11 +4137,13 @@  discard block
 block discarded – undo
3991 4137
     {
3992 4138
         $whois  = $this->whois($node);
3993 4139
         $return = '';
3994
-        if ($whois)
3995
-            $return .= str_repeat(' - ', $intend) . $whois . "\n";
3996
-        if (isset($node->childNodes))
3997
-            foreach ($node->childNodes as $chNode)
4140
+        if ($whois) {
4141
+                    $return .= str_repeat(' - ', $intend) . $whois . "\n";
4142
+        }
4143
+        if (isset($node->childNodes)) {
4144
+                    foreach ($node->childNodes as $chNode)
3998 4145
                 $return .= $this->__dumpTree($chNode, $intend + 1);
4146
+        }
3999 4147
         return $return;
4000 4148
     }
4001 4149
 
Please login to merge, or discard this patch.
src/Plugin/Scripts.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@
 block discarded – undo
69 69
      * @param $name
70 70
      * @param $callback
71 71
      * @throws \Exception
72
-     * @return bool
72
+     * @return boolean|null
73 73
      */
74 74
 	public static function script($name, $callback) {
75 75
 		if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name])
Please login to merge, or discard this patch.
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -20,13 +20,13 @@  discard block
 block discarded – undo
20 20
 	public static $PhpQueryMethods = null;
21 21
 	public static $config = array();
22 22
 
23
-    /**
24
-     * Enter description here...
25
-     *
26
-     * @param \PhpQuery\PhpQueryObject $self
27
-     * @param                          $arg1
28
-     * @return null|\PhpQuery\PhpQueryObject
29
-     */
23
+	/**
24
+	 * Enter description here...
25
+	 *
26
+	 * @param \PhpQuery\PhpQueryObject $self
27
+	 * @param                          $arg1
28
+	 * @return null|\PhpQuery\PhpQueryObject
29
+	 */
30 30
 	public static function script($self, $arg1) {
31 31
 		$params = func_get_args();
32 32
 		$params = array_slice($params, 2);
@@ -57,20 +57,20 @@  discard block
 block discarded – undo
57 57
 		}
58 58
 	}
59 59
 
60
-    /**
61
-     * Extend scripts' namespace with $name related with $callback.
62
-     *
63
-     * Callback parameter order looks like this:
64
-     * - $this
65
-     * - $params
66
-     * - &$return
67
-     * - $config
68
-     *
69
-     * @param $name
70
-     * @param $callback
71
-     * @throws \Exception
72
-     * @return bool
73
-     */
60
+	/**
61
+	 * Extend scripts' namespace with $name related with $callback.
62
+	 *
63
+	 * Callback parameter order looks like this:
64
+	 * - $this
65
+	 * - $params
66
+	 * - &$return
67
+	 * - $config
68
+	 *
69
+	 * @param $name
70
+	 * @param $callback
71
+	 * @throws \Exception
72
+	 * @return bool
73
+	 */
74 74
 	public static function script($name, $callback) {
75 75
 		if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name])
76 76
 			throw new \Exception("Script name conflict - '$name'");
Please login to merge, or discard this patch.
Braces   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -72,8 +72,9 @@
 block discarded – undo
72 72
      * @return bool
73 73
      */
74 74
 	public static function script($name, $callback) {
75
-		if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name])
76
-			throw new \Exception("Script name conflict - '$name'");
75
+		if (\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name]) {
76
+					throw new \Exception("Script name conflict - '$name'");
77
+		}
77 78
 		\PhpQuery\Plugin\UtilScripts::$scriptMethods[$name] = $callback;
78 79
 	}
79 80
 }
80 81
\ No newline at end of file
Please login to merge, or discard this patch.
src/Tests/BasicTest.php 3 patches
Doc Comments   -1 removed lines patch added patch discarded remove patch
@@ -187,7 +187,6 @@
 block discarded – undo
187 187
   }
188 188
 
189 189
   /**
190
-   * @param PhpQueryObject $pq
191 190
    * @dataProvider provider
192 191
    * @return void
193 192
    */
Please login to merge, or discard this patch.
Indentation   +95 added lines, -95 removed lines patch added patch discarded remove patch
@@ -7,12 +7,12 @@  discard block
 block discarded – undo
7 7
 
8 8
 class BasicTest extends \PHPUnit_Framework_TestCase {
9 9
   function provider() {
10
-    // TODO change filename
11
-    return array(
12
-      array(
13
-        PhpQuery::newDocumentFile(__DIR__ . '/test.html')
14
-      )
15
-    );
10
+	// TODO change filename
11
+	return array(
12
+	  array(
13
+		PhpQuery::newDocumentFile(__DIR__ . '/test.html')
14
+	  )
15
+	);
16 16
   }
17 17
 
18 18
   /**
@@ -21,12 +21,12 @@  discard block
 block discarded – undo
21 21
    * @return void
22 22
    */
23 23
   function testFilterWithPseudoclass($pq) {
24
-    $pq = $pq->find('p')->filter('.body:gt(1)');
25
-    $result = array(
26
-      'p.body',
27
-    );
24
+	$pq = $pq->find('p')->filter('.body:gt(1)');
25
+	$result = array(
26
+	  'p.body',
27
+	);
28 28
 
29
-    $this->assertTrue($pq->whois() == $result);
29
+	$this->assertTrue($pq->whois() == $result);
30 30
   }
31 31
 
32 32
   /**
@@ -35,12 +35,12 @@  discard block
 block discarded – undo
35 35
    * @return void
36 36
    */
37 37
   function testSlice($pq) {
38
-    $testResult = array(
39
-      'li#testID',
40
-    );
41
-    $pq = $pq->find('li')->slice(1, 2);
38
+	$testResult = array(
39
+	  'li#testID',
40
+	);
41
+	$pq = $pq->find('li')->slice(1, 2);
42 42
 
43
-    $this->assertTrue($pq->whois() == $testResult);
43
+	$this->assertTrue($pq->whois() == $testResult);
44 44
   }
45 45
 
46 46
   /**
@@ -49,29 +49,29 @@  discard block
 block discarded – undo
49 49
    * @return void
50 50
    */
51 51
   function testSlice2($pq) {
52
-    // SLICE2
53
-    $testResult = array(
54
-      'li#testID',
55
-      'li',
56
-      'li#i_have_nested_list',
57
-      'li.nested',
58
-    );
52
+	// SLICE2
53
+	$testResult = array(
54
+	  'li#testID',
55
+	  'li',
56
+	  'li#i_have_nested_list',
57
+	  'li.nested',
58
+	);
59 59
 
60
-    $pq = $pq->find('li')->slice(1, -1);
60
+	$pq = $pq->find('li')->slice(1, -1);
61 61
 
62
-    $this->assertTrue($pq->whois() == $testResult);
62
+	$this->assertTrue($pq->whois() == $testResult);
63 63
   }
64 64
 
65 65
   /**
66 66
    * @return void
67 67
    */
68 68
   function testMultiInsert() {
69
-    // Multi-insert
70
-    $pq = PhpQuery::newDocument('<li><span class="field1"></span><span class="field1"></span></li>')->find('.field1')->php('longlongtest');
71
-    $validResult = '<li><span class="field1"><php>longlongtest</php></span><span class="field1"><php>longlongtest</php></span></li>';
72
-    similar_text($pq->htmlOuter(), $validResult, $similarity);
69
+	// Multi-insert
70
+	$pq = PhpQuery::newDocument('<li><span class="field1"></span><span class="field1"></span></li>')->find('.field1')->php('longlongtest');
71
+	$validResult = '<li><span class="field1"><php>longlongtest</php></span><span class="field1"><php>longlongtest</php></span></li>';
72
+	similar_text($pq->htmlOuter(), $validResult, $similarity);
73 73
 
74
-    $this->assertGreaterThan(80, $similarity);
74
+	$this->assertGreaterThan(80, $similarity);
75 75
 
76 76
   }
77 77
 
@@ -81,10 +81,10 @@  discard block
 block discarded – undo
81 81
    * @return void
82 82
    */
83 83
   function testIndex($pq) {
84
-    $testResult = 1;
85
-    $pq = $pq->find('p')->index($pq->find('p.title:first'));
84
+	$testResult = 1;
85
+	$pq = $pq->find('p')->index($pq->find('p.title:first'));
86 86
 
87
-    $this->assertTrue($pq == $testResult);
87
+	$this->assertTrue($pq == $testResult);
88 88
   }
89 89
 
90 90
   /**
@@ -93,20 +93,20 @@  discard block
 block discarded – undo
93 93
    * @return void
94 94
    */
95 95
   function testClone($pq) {
96
-    $testResult = 3;
97
-    $document = null;
98
-    $pq = $pq->toReference($document)->find('p:first');
99
-
100
-    foreach (array(
101
-      0,
102
-      1,
103
-      2
104
-    ) as $i) {
105
-      $pq->clone()->addClass("clone-test")->addClass("class-$i")->insertBefore($pq);
106
-    }
107
-
108
-    $size = $document->find('.clone-test')->size();
109
-    $this->assertEquals($testResult, $size);
96
+	$testResult = 3;
97
+	$document = null;
98
+	$pq = $pq->toReference($document)->find('p:first');
99
+
100
+	foreach (array(
101
+	  0,
102
+	  1,
103
+	  2
104
+	) as $i) {
105
+	  $pq->clone()->addClass("clone-test")->addClass("class-$i")->insertBefore($pq);
106
+	}
107
+
108
+	$size = $document->find('.clone-test')->size();
109
+	$this->assertEquals($testResult, $size);
110 110
   }
111 111
 
112 112
   /**
@@ -115,11 +115,11 @@  discard block
 block discarded – undo
115 115
    * @return void
116 116
    */
117 117
   function testNextSibling($pq) {
118
-    $testResult = 3;
119
-    $document = null;
120
-    $result = $pq->find('li:first')->next()->next()->prev()->is('#testID');
118
+	$testResult = 3;
119
+	$document = null;
120
+	$result = $pq->find('li:first')->next()->next()->prev()->is('#testID');
121 121
 
122
-    $this->assertTrue($result);
122
+	$this->assertTrue($result);
123 123
   }
124 124
 
125 125
   /**
@@ -128,8 +128,8 @@  discard block
 block discarded – undo
128 128
    * @return void
129 129
    */
130 130
   function testSimpleDataInsertion($pq) {
131
-    $testName = 'Simple data insertion';
132
-    $testResult = <<<EOF
131
+	$testName = 'Simple data insertion';
132
+	$testResult = <<<EOF
133 133
 <div class="articles">
134 134
         div.articles text node
135 135
         <ul>
@@ -154,36 +154,36 @@  discard block
 block discarded – undo
154 154
 <p class="after">paragraph after UL</p>
155 155
     </div>
156 156
 EOF;
157
-    $expected_pq = PhpQuery::newDocumentHTML($testResult);
158
-    $rows = array(
159
-      array(
160
-        'title' => 'News 1 title',
161
-        'body' => 'News 1 body',
162
-      ),
163
-      array(
164
-        'title' => 'News 2 title',
165
-        'body' => 'News 2 body',
166
-      ),
167
-      array(
168
-        'title' => 'News 3',
169
-        'body' => 'News 3 body',
170
-      ),
171
-    );
172
-    $articles = $pq->find('.articles ul');
173
-    $rowSrc = $articles->find('li')->remove()->eq(0);
174
-    foreach ($rows as $r) {
175
-      $row = $rowSrc->_clone();
176
-      foreach ($r as $field => $value) {
177
-        $row->find(".{$field}")->html($value);
178
-        //		die($row->htmlOuter());
179
-      }
180
-      $row->appendTo($articles);
181
-    }
182
-    $result = $pq->find('.articles')->htmlOuter();
183
-    //         print htmlspecialchars("<pre>{$result}</pre>").'<br />';
184
-
185
-    $this->assertEqualXMLStructure($expected_pq->find('.articles')->elements[0], $pq->find('.articles')->elements[0]);
186
-    //         $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement);
157
+	$expected_pq = PhpQuery::newDocumentHTML($testResult);
158
+	$rows = array(
159
+	  array(
160
+		'title' => 'News 1 title',
161
+		'body' => 'News 1 body',
162
+	  ),
163
+	  array(
164
+		'title' => 'News 2 title',
165
+		'body' => 'News 2 body',
166
+	  ),
167
+	  array(
168
+		'title' => 'News 3',
169
+		'body' => 'News 3 body',
170
+	  ),
171
+	);
172
+	$articles = $pq->find('.articles ul');
173
+	$rowSrc = $articles->find('li')->remove()->eq(0);
174
+	foreach ($rows as $r) {
175
+	  $row = $rowSrc->_clone();
176
+	  foreach ($r as $field => $value) {
177
+		$row->find(".{$field}")->html($value);
178
+		//		die($row->htmlOuter());
179
+	  }
180
+	  $row->appendTo($articles);
181
+	}
182
+	$result = $pq->find('.articles')->htmlOuter();
183
+	//         print htmlspecialchars("<pre>{$result}</pre>").'<br />';
184
+
185
+	$this->assertEqualXMLStructure($expected_pq->find('.articles')->elements[0], $pq->find('.articles')->elements[0]);
186
+	//         $this->assertEqualXMLStructure(DOMDocument::loadHTML($testResult)->documentElement, DOMDocument::loadHTML($result)->documentElement);
187 187
   }
188 188
 
189 189
   /**
@@ -192,17 +192,17 @@  discard block
 block discarded – undo
192 192
    * @return void
193 193
    */
194 194
   public function testCssParser() {
195
-    PhpQuery::$enableCssShorthand = FALSE;
196
-
197
-    $expected_html = '<div style="color:red;display:none;margin:20px;padding:10px"><span>Hello World!</span></div>';
198
-    $expected_pq = PhpQuery::newDocumentHTML($expected_html);
199
-
200
-    $test_pq = PhpQuery::newDocumentHTML('<div style="margin:10px; padding:10px">');
201
-    $test = pq('div');
202
-    $test->append('<span>Hello World!</span>');
203
-    $test->hide();
204
-    $test->css('color', 'red');
205
-    $test->css('margin', '20px');
206
-    $this->assertEqualXMLStructure($expected_pq->find('div')->elements[0], $test->elements[0]);
195
+	PhpQuery::$enableCssShorthand = FALSE;
196
+
197
+	$expected_html = '<div style="color:red;display:none;margin:20px;padding:10px"><span>Hello World!</span></div>';
198
+	$expected_pq = PhpQuery::newDocumentHTML($expected_html);
199
+
200
+	$test_pq = PhpQuery::newDocumentHTML('<div style="margin:10px; padding:10px">');
201
+	$test = pq('div');
202
+	$test->append('<span>Hello World!</span>');
203
+	$test->hide();
204
+	$test->css('color', 'red');
205
+	$test->css('margin', '20px');
206
+	$this->assertEqualXMLStructure($expected_pq->find('div')->elements[0], $test->elements[0]);
207 207
   }
208 208
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@
 block discarded – undo
10 10
     // TODO change filename
11 11
     return array(
12 12
       array(
13
-        PhpQuery::newDocumentFile(__DIR__ . '/test.html')
13
+        PhpQuery::newDocumentFile(__DIR__.'/test.html')
14 14
       )
15 15
     );
16 16
   }
Please login to merge, or discard this patch.
src/Plugin/Scripts/fix_webroot.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -5,12 +5,12 @@
 block discarded – undo
5 5
 		.':not([href^=http://])'
6 6
 		.':not([src^=http://])'
7 7
 		.':not([src^=/])';
8
-foreach($self[$selector]->filter($filter) as $el) {
8
+foreach ($self[$selector]->filter($filter) as $el) {
9 9
 	$el = pq($el, $self->getDocumentID());
10 10
 	// imgs and scripts
11
-	if ( $el->is('img') || $el->is('script') )
11
+	if ($el->is('img') || $el->is('script'))
12 12
 		$el->attr('src', $params[0].$el->attr('src'));
13 13
 	// css
14
-	if ( $el->is('link') )
14
+	if ($el->is('link'))
15 15
 		$el->attr('href', $params[0].$el->attr('href'));
16 16
 }
17 17
\ No newline at end of file
Please login to merge, or discard this patch.
Braces   +7 added lines, -5 removed lines patch added patch discarded remove patch
@@ -8,9 +8,11 @@
 block discarded – undo
8 8
 foreach($self[$selector]->filter($filter) as $el) {
9 9
 	$el = pq($el, $self->getDocumentID());
10 10
 	// imgs and scripts
11
-	if ( $el->is('img') || $el->is('script') )
12
-		$el->attr('src', $params[0].$el->attr('src'));
11
+	if ( $el->is('img') || $el->is('script') ) {
12
+			$el->attr('src', $params[0].$el->attr('src'));
13
+	}
13 14
 	// css
14
-	if ( $el->is('link') )
15
-		$el->attr('href', $params[0].$el->attr('href'));
16
-}
17 15
\ No newline at end of file
16
+	if ( $el->is('link') ) {
17
+			$el->attr('href', $params[0].$el->attr('href'));
18
+	}
19
+	}
18 20
\ No newline at end of file
Please login to merge, or discard this patch.