Lazy Load by WP Rocket - Version 1.3.1

Version Description

  • 2017-09-07
  • Don't apply lazyload on Divi slider
Download this release

Release Info

Developer wp_media
Plugin Icon 128x128 Lazy Load by WP Rocket
Version 1.3.1
Comparing to
See all releases

Code changes from version 1.3 to 1.3.1

readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: creativejuiz, tabrisrp, wp_media
3
  Tags: lazyload, lazy load, images, iframes, thumbnail, thumbnails, smiley, smilies, avatar, gravatar
4
  Requires at least: 3.0
5
  Tested up to: 4.8.1
6
- Stable tag: 1.3
7
 
8
  The tiny Lazy Load script for WordPress without jQuery, works for images and iframes.
9
 
@@ -50,6 +50,10 @@ You can also use the filters `rocket_lazyload_excluded_attributes` or `rocket_la
50
  Some plugins are not compatible without lazy loading. Please open a support thread, and we will see how we can solve the issue by excluding lazy loading for this plugin.
51
 
52
  == Changelog ==
 
 
 
 
53
  = 1.3 =
54
  * 2017-09-01
55
  * Improve HTML parsing of images and iframes to be faster and more efficient
3
  Tags: lazyload, lazy load, images, iframes, thumbnail, thumbnails, smiley, smilies, avatar, gravatar
4
  Requires at least: 3.0
5
  Tested up to: 4.8.1
6
+ Stable tag: 1.3.1
7
 
8
  The tiny Lazy Load script for WordPress without jQuery, works for images and iframes.
9
 
50
  Some plugins are not compatible without lazy loading. Please open a support thread, and we will see how we can solve the issue by excluding lazy loading for this plugin.
51
 
52
  == Changelog ==
53
+ = 1.3.1 =
54
+ * 2017-09-07
55
+ * Don't apply lazyload on Divi slider
56
+
57
  = 1.3 =
58
  * 2017-09-01
59
  * Improve HTML parsing of images and iframes to be faster and more efficient
rocket-lazy-load.php CHANGED
@@ -5,7 +5,7 @@ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
5
  * Plugin Name: Rocket Lazy Load
6
  * Plugin URI: http://wordpress.org/plugins/rocket-lazy-load/
7
  * Description: The tiny Lazy Load script for WordPress without jQuery or others libraries.
8
- * Version: 1.3
9
  * Requires PHP: 5.4
10
  * Author: WP Media
11
  * Author URI: https://wp-rocket.me
@@ -27,7 +27,7 @@ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
27
  * You should have received a copy of the GNU General Public License
28
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
  */
30
- define( 'ROCKET_LL_VERSION', '1.3' );
31
  define( 'ROCKET_LL_PATH', realpath( plugin_dir_path( __FILE__ ) ) . '/' );
32
  define( 'ROCKET_LL_3RD_PARTY_PATH', ROCKET_LL_PATH . '3rd-party/' );
33
  define( 'ROCKET_LL_ASSETS_URL', plugin_dir_url( __FILE__ ) . 'assets/' );
@@ -165,7 +165,7 @@ add_action( 'wp_enqueue_scripts', 'rocket_lazyload_enqueue', PHP_INT_MAX );
165
  */
166
  function rocket_lazyload_async_script( $tag, $handle ) {
167
  if ( 'rocket-lazyload' === $handle ) {
168
- return str_replace( '<script', '<script async data-cfasync="false" data-minify="1"', $tag );
169
  }
170
 
171
  return $tag;
@@ -196,7 +196,7 @@ function rocket_lazyload_images( $html ) {
196
  $dom->load( $html );
197
  $images = $dom->getElementsByTag( 'img' );
198
 
199
- if ( ! $images ) {
200
  return $html;
201
  }
202
 
@@ -207,6 +207,12 @@ function rocket_lazyload_images( $html ) {
207
  continue;
208
  }
209
 
 
 
 
 
 
 
210
  $img = new PHPHtmlParser\Dom\Tag( 'img' );
211
 
212
  foreach ( $image_attributes as $key => $value ) {
@@ -241,7 +247,6 @@ function rocket_lazyload_images( $html ) {
241
 
242
  $noscript->addChild( $original_image );
243
 
244
- $parent = $image->getParent();
245
  $parent->insertAfter( $noscript, $image->id() );
246
  }
247
 
@@ -437,7 +442,7 @@ function rocket_lazyload_iframes( $html ) {
437
  $dom->load( $html );
438
  $iframes = $dom->getElementsByTag( 'iframe' );
439
 
440
- if ( ! $iframes ) {
441
  return $html;
442
  }
443
 
5
  * Plugin Name: Rocket Lazy Load
6
  * Plugin URI: http://wordpress.org/plugins/rocket-lazy-load/
7
  * Description: The tiny Lazy Load script for WordPress without jQuery or others libraries.
8
+ * Version: 1.3.1
9
  * Requires PHP: 5.4
10
  * Author: WP Media
11
  * Author URI: https://wp-rocket.me
27
  * You should have received a copy of the GNU General Public License
28
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
  */
30
+ define( 'ROCKET_LL_VERSION', '1.3.1' );
31
  define( 'ROCKET_LL_PATH', realpath( plugin_dir_path( __FILE__ ) ) . '/' );
32
  define( 'ROCKET_LL_3RD_PARTY_PATH', ROCKET_LL_PATH . '3rd-party/' );
33
  define( 'ROCKET_LL_ASSETS_URL', plugin_dir_url( __FILE__ ) . 'assets/' );
165
  */
166
  function rocket_lazyload_async_script( $tag, $handle ) {
167
  if ( 'rocket-lazyload' === $handle ) {
168
+ return str_replace( '<script', '<script async data-minify="1"', $tag );
169
  }
170
 
171
  return $tag;
196
  $dom->load( $html );
197
  $images = $dom->getElementsByTag( 'img' );
198
 
199
+ if ( empty( $images ) ) {
200
  return $html;
201
  }
202
 
207
  continue;
208
  }
209
 
210
+ $parent = $image->getParent();
211
+
212
+ if ( false !== strpos( $parent->getAttribute( 'class' ), 'et_pb_slide_image' ) ) {
213
+ continue;
214
+ }
215
+
216
  $img = new PHPHtmlParser\Dom\Tag( 'img' );
217
 
218
  foreach ( $image_attributes as $key => $value ) {
247
 
248
  $noscript->addChild( $original_image );
249
 
 
250
  $parent->insertAfter( $noscript, $image->id() );
251
  }
252
 
442
  $dom->load( $html );
443
  $iframes = $dom->getElementsByTag( 'iframe' );
444
 
445
+ if ( empty( $iframes ) ) {
446
  return $html;
447
  }
448
 
vendor/composer/installed.json CHANGED
@@ -49,31 +49,32 @@
49
  },
50
  {
51
  "name": "paquettg/php-html-parser",
52
- "version": "1.7.0",
53
- "version_normalized": "1.7.0.0",
54
  "source": {
55
  "type": "git",
56
  "url": "https://github.com/paquettg/php-html-parser.git",
57
- "reference": "18845e09831dd0772b88b51e788a4f74c701224c"
58
  },
59
  "dist": {
60
  "type": "zip",
61
- "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/18845e09831dd0772b88b51e788a4f74c701224c",
62
- "reference": "18845e09831dd0772b88b51e788a4f74c701224c",
63
  "shasum": ""
64
  },
65
  "require": {
 
66
  "paquettg/string-encode": "~0.1.0",
67
- "php": ">=5.4"
68
  },
69
  "require-dev": {
70
  "mockery/mockery": "~0.9.0",
71
- "phpunit/phpunit": "~4.8.0",
72
- "satooshi/php-coveralls": "~0.6.0"
73
  },
74
- "time": "2016-04-06T15:24:40+00:00",
75
  "type": "library",
76
- "installation-source": "dist",
77
  "autoload": {
78
  "psr-0": {
79
  "PHPHtmlParser": "src/"
49
  },
50
  {
51
  "name": "paquettg/php-html-parser",
52
+ "version": "dev-dev",
53
+ "version_normalized": "dev-dev",
54
  "source": {
55
  "type": "git",
56
  "url": "https://github.com/paquettg/php-html-parser.git",
57
+ "reference": "e85e379a07143f60471d289748f7d26513e28c99"
58
  },
59
  "dist": {
60
  "type": "zip",
61
+ "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/e85e379a07143f60471d289748f7d26513e28c99",
62
+ "reference": "e85e379a07143f60471d289748f7d26513e28c99",
63
  "shasum": ""
64
  },
65
  "require": {
66
+ "ext-mbstring": "*",
67
  "paquettg/string-encode": "~0.1.0",
68
+ "php": ">=5.6"
69
  },
70
  "require-dev": {
71
  "mockery/mockery": "~0.9.0",
72
+ "phpunit/phpunit": "~5.7.0",
73
+ "satooshi/php-coveralls": "~1.0.0"
74
  },
75
+ "time": "2017-07-24T00:37:01+00:00",
76
  "type": "library",
77
+ "installation-source": "source",
78
  "autoload": {
79
  "psr-0": {
80
  "PHPHtmlParser": "src/"
vendor/paquettg/php-html-parser/composer.json CHANGED
@@ -14,12 +14,13 @@
14
  }
15
  ],
16
  "require": {
17
- "php": ">=5.4",
 
18
  "paquettg/string-encode": "~0.1.0"
19
  },
20
  "require-dev": {
21
- "phpunit/phpunit": "~4.8.0",
22
- "satooshi/php-coveralls": "~0.6.0",
23
  "mockery/mockery": "~0.9.0"
24
  },
25
  "autoload": {
14
  }
15
  ],
16
  "require": {
17
+ "php": ">=5.6",
18
+ "ext-mbstring": "*",
19
  "paquettg/string-encode": "~0.1.0"
20
  },
21
  "require-dev": {
22
+ "phpunit/phpunit": "~5.7.0",
23
+ "satooshi/php-coveralls": "~1.0.0",
24
  "mockery/mockery": "~0.9.0"
25
  },
26
  "autoload": {
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Curl.php CHANGED
@@ -28,6 +28,11 @@ class Curl implements CurlInterface
28
 
29
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
30
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
 
 
 
 
 
31
 
32
  $content = curl_exec($ch);
33
  if ($content === false) {
28
 
29
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
30
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
31
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
32
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
33
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
34
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36');
35
+ curl_setopt($ch, CURLOPT_URL, $url);
36
 
37
  $content = curl_exec($ch);
38
  if ($content === false) {
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom.php CHANGED
@@ -79,17 +79,32 @@ class Dom
79
  * @var array
80
  */
81
  protected $selfClosing = [
82
- 'img',
 
 
83
  'br',
 
 
 
 
84
  'input',
85
- 'meta',
86
  'link',
87
- 'hr',
88
- 'base',
89
- 'embed',
90
  'spacer',
 
 
91
  ];
92
 
 
 
 
 
 
 
 
93
  /**
94
  * Returns the inner html of the root node.
95
  *
@@ -120,6 +135,7 @@ class Dom
120
  */
121
  public function load($str, $options = [])
122
  {
 
123
  // check if it's a file
124
  if (strpos($str, "\n") === false && is_file($str)) {
125
  return $this->loadFromFile($str, $options);
@@ -219,6 +235,20 @@ class Dom
219
  return $this->root->find($selector, $nth);
220
  }
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  /**
223
  * Adds the tag (or tags in an array) to the list of tags that will always
224
  * be self closing.
@@ -267,6 +297,53 @@ class Dom
267
  return $this;
268
  }
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  /**
271
  * Simple wrapper function that returns the first child.
272
  *
@@ -291,6 +368,42 @@ class Dom
291
  return $this->root->lastChild();
292
  }
293
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  /**
295
  * Simple wrapper function that returns an element by the
296
  * id.
@@ -391,7 +504,9 @@ class Dom
391
  }
392
 
393
  // strip out server side scripts
394
- $str = mb_eregi_replace("(<\?)(.*?)(\?>)", '', $str);
 
 
395
 
396
  // strip smarty scripts
397
  $str = mb_eregi_replace("(\{\w)(.*?)(\})", '', $str);
@@ -450,7 +565,7 @@ class Dom
450
  trim($str) != ''
451
  ) {
452
  // we found text we care about
453
- $textNode = new TextNode($str);
454
  $activeNode->addChild($textNode);
455
  }
456
  }
@@ -516,8 +631,8 @@ class Dom
516
  }
517
 
518
  if (empty($name)) {
519
- $this->content->fastForward(1);
520
- continue;
521
  }
522
 
523
  $this->content->skipByToken('blank');
@@ -588,6 +703,13 @@ class Dom
588
 
589
  // We force self closing on this tag.
590
  $node->getTag()->selfClosing();
 
 
 
 
 
 
 
591
  }
592
 
593
  $this->content->fastForward(1);
79
  * @var array
80
  */
81
  protected $selfClosing = [
82
+ 'area',
83
+ 'base',
84
+ 'basefont',
85
  'br',
86
+ 'col',
87
+ 'embed',
88
+ 'hr',
89
+ 'img',
90
  'input',
91
+ 'keygen',
92
  'link',
93
+ 'meta',
94
+ 'param',
95
+ 'source',
96
  'spacer',
97
+ 'track',
98
+ 'wbr'
99
  ];
100
 
101
+ /**
102
+ * A list of tags where there should be no /> at the end (html5 style)
103
+ *
104
+ * @var array
105
+ */
106
+ protected $noSlash = [];
107
+
108
  /**
109
  * Returns the inner html of the root node.
110
  *
135
  */
136
  public function load($str, $options = [])
137
  {
138
+ AbstractNode::resetCount();
139
  // check if it's a file
140
  if (strpos($str, "\n") === false && is_file($str)) {
141
  return $this->loadFromFile($str, $options);
235
  return $this->root->find($selector, $nth);
236
  }
237
 
238
+ /**
239
+ * Find element by Id on the root node
240
+ *
241
+ * @param int $id Element Id
242
+ * @return mixed
243
+ *
244
+ */
245
+ public function findById($id)
246
+ {
247
+ $this->isLoaded();
248
+
249
+ return $this->root->findById($id);
250
+ }
251
+
252
  /**
253
  * Adds the tag (or tags in an array) to the list of tags that will always
254
  * be self closing.
297
  return $this;
298
  }
299
 
300
+
301
+ /**
302
+ * Adds a tag to the list of self closing tags that should not have a trailing slash
303
+ *
304
+ * @param $tag
305
+ * @return $this
306
+ */
307
+ public function addNoSlashTag($tag)
308
+ {
309
+ if ( ! is_array($tag)) {
310
+ $tag = [$tag];
311
+ }
312
+ foreach ($tag as $value) {
313
+ $this->noSlash[] = $value;
314
+ }
315
+
316
+ return $this;
317
+ }
318
+
319
+ /**
320
+ * Removes a tag from the list of no-slash tags.
321
+ *
322
+ * @param $tag
323
+ * @return $this
324
+ */
325
+ public function removeNoSlashTag($tag)
326
+ {
327
+ if ( ! is_array($tag)) {
328
+ $tag = [$tag];
329
+ }
330
+ $this->noSlash = array_diff($this->noSlash, $tag);
331
+
332
+ return $this;
333
+ }
334
+
335
+ /**
336
+ * Empties the list of no-slash tags.
337
+ *
338
+ * @return $this
339
+ */
340
+ public function clearNoSlashTags()
341
+ {
342
+ $this->noSlash = [];
343
+
344
+ return $this;
345
+ }
346
+
347
  /**
348
  * Simple wrapper function that returns the first child.
349
  *
368
  return $this->root->lastChild();
369
  }
370
 
371
+ /**
372
+ * Simple wrapper function that returns count of child elements
373
+ *
374
+ * @return int
375
+ */
376
+ public function countChildren()
377
+ {
378
+ $this->isLoaded();
379
+
380
+ return $this->root->countChildren();
381
+ }
382
+
383
+ /**
384
+ * Get array of children
385
+ *
386
+ * @return array
387
+ */
388
+ public function getChildren()
389
+ {
390
+ $this->isLoaded();
391
+
392
+ return $this->root->getChildren();
393
+ }
394
+
395
+ /**
396
+ * Check if node have children nodes
397
+ *
398
+ * @return bool
399
+ */
400
+ public function hasChildren()
401
+ {
402
+ $this->isLoaded();
403
+
404
+ return $this->root->hasChildren();
405
+ }
406
+
407
  /**
408
  * Simple wrapper function that returns an element by the
409
  * id.
504
  }
505
 
506
  // strip out server side scripts
507
+ if ($this->options->get('serverSideScriptis') == true){
508
+ $str = mb_eregi_replace("(<\?)(.*?)(\?>)", '', $str);
509
+ }
510
 
511
  // strip smarty scripts
512
  $str = mb_eregi_replace("(\{\w)(.*?)(\})", '', $str);
565
  trim($str) != ''
566
  ) {
567
  // we found text we care about
568
+ $textNode = new TextNode($str, $this->options->removeDoubleSpace);
569
  $activeNode->addChild($textNode);
570
  }
571
  }
631
  }
632
 
633
  if (empty($name)) {
634
+ $this->content->skipByToken('blank');
635
+ continue;
636
  }
637
 
638
  $this->content->skipByToken('blank');
703
 
704
  // We force self closing on this tag.
705
  $node->getTag()->selfClosing();
706
+
707
+ // Should this tag use a trailing slash?
708
+ if(in_array($tag, $this->noSlash))
709
+ {
710
+ $node->getTag()->noTrailingSlash();
711
+ }
712
+
713
  }
714
 
715
  $this->content->fastForward(1);
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/AbstractNode.php CHANGED
@@ -5,6 +5,7 @@ use PHPHtmlParser\Exceptions\CircularException;
5
  use PHPHtmlParser\Exceptions\ParentNotFoundException;
6
  use PHPHtmlParser\Selector;
7
  use stringEncode\Encode;
 
8
 
9
  /**
10
  * Dom node object.
@@ -17,7 +18,7 @@ use stringEncode\Encode;
17
  */
18
  abstract class AbstractNode
19
  {
20
-
21
  /**
22
  * Contains the tag name/type
23
  *
@@ -54,11 +55,12 @@ abstract class AbstractNode
54
  protected $encode;
55
 
56
  /**
57
- * Creates a unique spl hash for this node.
58
  */
59
  public function __construct()
60
  {
61
- $this->id = spl_object_hash($this);
 
62
  }
63
 
64
  /**
@@ -83,7 +85,7 @@ abstract class AbstractNode
83
  case 'tag':
84
  return $this->getTag();
85
  case 'parent':
86
- $this->getParent();
87
  }
88
 
89
  return null;
@@ -110,6 +112,14 @@ abstract class AbstractNode
110
  return $this->outerHtml();
111
  }
112
 
 
 
 
 
 
 
 
 
113
  /**
114
  * Returns the id of this object.
115
  */
@@ -152,9 +162,6 @@ abstract class AbstractNode
152
  // assign child to parent
153
  $this->parent->addChild($this);
154
 
155
- //clear any cache
156
- $this->clear();
157
-
158
  return $this;
159
  }
160
 
@@ -169,8 +176,8 @@ abstract class AbstractNode
169
  if ( ! is_null($this->parent)) {
170
  $this->parent->removeChild($this->id);
171
  }
172
-
173
- $this->parent = null;
174
  }
175
 
176
  /**
@@ -220,6 +227,15 @@ abstract class AbstractNode
220
  return null;
221
  }
222
 
 
 
 
 
 
 
 
 
 
223
  /**
224
  * Attempts to get the next sibling.
225
  *
@@ -293,6 +309,18 @@ abstract class AbstractNode
293
  return $attribute;
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  /**
297
  * A wrapper method that simply calls the setAttribute method
298
  * on the tag of this node.
@@ -305,6 +333,9 @@ abstract class AbstractNode
305
  {
306
  $this->tag->setAttribute($key, $value);
307
 
 
 
 
308
  return $this;
309
  }
310
 
@@ -318,6 +349,9 @@ abstract class AbstractNode
318
  public function removeAttribute($key)
319
  {
320
  $this->tag->removeAttribute($key);
 
 
 
321
  }
322
 
323
  /**
@@ -329,8 +363,10 @@ abstract class AbstractNode
329
  public function removeAllAttributes()
330
  {
331
  $this->tag->removeAllAttributes();
332
- }
333
 
 
 
 
334
  /**
335
  * Function to locate a specific ancestor tag in the path to the root.
336
  *
@@ -378,6 +414,20 @@ abstract class AbstractNode
378
  return $nodes;
379
  }
380
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  /**
382
  * Gets the inner html of this node.
383
  *
@@ -407,4 +457,14 @@ abstract class AbstractNode
407
  * @return void
408
  */
409
  abstract protected function clear();
 
 
 
 
 
 
 
 
 
 
410
  }
5
  use PHPHtmlParser\Exceptions\ParentNotFoundException;
6
  use PHPHtmlParser\Selector;
7
  use stringEncode\Encode;
8
+ use PHPHtmlParser\Finder;
9
 
10
  /**
11
  * Dom node object.
18
  */
19
  abstract class AbstractNode
20
  {
21
+ private static $count = 0;
22
  /**
23
  * Contains the tag name/type
24
  *
55
  protected $encode;
56
 
57
  /**
58
+ * Creates a unique id for this node.
59
  */
60
  public function __construct()
61
  {
62
+ $this->id = self::$count;
63
+ self::$count++;
64
  }
65
 
66
  /**
85
  case 'tag':
86
  return $this->getTag();
87
  case 'parent':
88
+ return $this->getParent();
89
  }
90
 
91
  return null;
112
  return $this->outerHtml();
113
  }
114
 
115
+ /**
116
+ * Reset node counter
117
+ */
118
+ public static function resetCount()
119
+ {
120
+ self::$count = 0;
121
+ }
122
+
123
  /**
124
  * Returns the id of this object.
125
  */
162
  // assign child to parent
163
  $this->parent->addChild($this);
164
 
 
 
 
165
  return $this;
166
  }
167
 
176
  if ( ! is_null($this->parent)) {
177
  $this->parent->removeChild($this->id);
178
  }
179
+ $this->parent->clear();
180
+ $this->clear();
181
  }
182
 
183
  /**
227
  return null;
228
  }
229
 
230
+ public function hasNextSibling()
231
+ {
232
+ if (is_null($this->parent) || (!$this->parent->hasChildren())) {
233
+ return false;
234
+ }
235
+
236
+ return $this->parent->hasNextChild($this->id());
237
+ }
238
+
239
  /**
240
  * Attempts to get the next sibling.
241
  *
309
  return $attribute;
310
  }
311
 
312
+ /**
313
+ * A wrapper method that simply calls the hasAttribute method
314
+ * on the tag of this node.
315
+ *
316
+ * @param string $key
317
+ * @return bool
318
+ */
319
+ public function hasAttribute($key)
320
+ {
321
+ return $this->tag->hasAttribute($key);
322
+ }
323
+
324
  /**
325
  * A wrapper method that simply calls the setAttribute method
326
  * on the tag of this node.
333
  {
334
  $this->tag->setAttribute($key, $value);
335
 
336
+ //clear any cache
337
+ $this->clear();
338
+
339
  return $this;
340
  }
341
 
349
  public function removeAttribute($key)
350
  {
351
  $this->tag->removeAttribute($key);
352
+
353
+ //clear any cache
354
+ $this->clear();
355
  }
356
 
357
  /**
363
  public function removeAllAttributes()
364
  {
365
  $this->tag->removeAllAttributes();
 
366
 
367
+ //clear any cache
368
+ $this->clear();
369
+ }
370
  /**
371
  * Function to locate a specific ancestor tag in the path to the root.
372
  *
414
  return $nodes;
415
  }
416
 
417
+ /**
418
+ * Find node by id
419
+ *
420
+ * @param $id
421
+ * @return bool|AbstractNode
422
+ */
423
+ public function findById($id)
424
+ {
425
+ $finder= new Finder($id);
426
+
427
+ return $finder->find($this);
428
+ }
429
+
430
+
431
  /**
432
  * Gets the inner html of this node.
433
  *
457
  * @return void
458
  */
459
  abstract protected function clear();
460
+
461
+ /**
462
+ * Check is node type textNode
463
+ *
464
+ * @return boolean
465
+ */
466
+ public function isTextNode() {
467
+
468
+ return false;
469
+ }
470
  }
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/HtmlNode.php CHANGED
@@ -186,6 +186,10 @@ class HtmlNode extends InnerNode
186
  $this->innerHtml = null;
187
  $this->outerHtml = null;
188
  $this->text = null;
 
 
 
 
189
  }
190
 
191
  /**
186
  $this->innerHtml = null;
187
  $this->outerHtml = null;
188
  $this->text = null;
189
+
190
+ if (is_null($this->parent) === false) {
191
+ $this->parent->clear();
192
+ }
193
  }
194
 
195
  /**
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/InnerNode.php CHANGED
@@ -234,6 +234,18 @@ abstract class InnerNode extends ArrayNode
234
  return $this;
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  /**
238
  * Attempts to get the next child.
239
  *
@@ -294,13 +306,28 @@ abstract class InnerNode extends ArrayNode
294
  */
295
  public function replaceChild($childId, AbstractNode $newChild)
296
  {
297
- $oldChild = $this->getChild($childId);
298
- $keys = array_keys($this->children);
299
- $index = array_search($childId, $keys, true);
300
- $keys[$index] = $newChild->id();
301
- $this->children = array_combine($keys, $this->children);
302
- $this->children[$newChild->id()] = $newChild;
303
- unset($oldChild);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  }
305
 
306
  /**
234
  return $this;
235
  }
236
 
237
+ /**
238
+ * Check if has next Child
239
+ *
240
+ * @param $id childId
241
+ * @return mixed
242
+ */
243
+ public function hasNextChild($id)
244
+ {
245
+ $child= $this->getChild($id);
246
+ return $this->children[$child->id()]['next'];
247
+ }
248
+
249
  /**
250
  * Attempts to get the next child.
251
  *
306
  */
307
  public function replaceChild($childId, AbstractNode $newChild)
308
  {
309
+ $oldChild = $this->children[$childId];
310
+
311
+ $newChild->prev = $oldChild['prev'];
312
+ $newChild->next = $oldChild['next'];
313
+
314
+ $keys = array_keys($this->children);
315
+ $index = array_search($childId, $keys, true);
316
+ $keys[$index] = $newChild->id();
317
+ $this->children = array_combine($keys, $this->children);
318
+ $this->children[$newChild->id()] = array(
319
+ 'prev' => $oldChild['prev'],
320
+ 'node' => $newChild,
321
+ 'next' => $oldChild['next']
322
+ );
323
+
324
+ if ($oldChild['prev'] && isset($this->children[$newChild->prev])) {
325
+ $this->children[$oldChild['prev']]['next'] = $newChild->id();
326
+ }
327
+
328
+ if ($oldChild['next'] && isset($this->children[$newChild->next])) {
329
+ $this->children[$oldChild['next']]['prev'] = $newChild->id();
330
+ }
331
  }
332
 
333
  /**
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/MockNode.php CHANGED
@@ -40,6 +40,9 @@ class MockNode extends InnerNode
40
  $this->innerHtml = null;
41
  $this->outerHtml = null;
42
  $this->text = null;
 
 
 
43
  }
44
 
45
  /**
40
  $this->innerHtml = null;
41
  $this->outerHtml = null;
42
  $this->text = null;
43
+ if (is_null($this->parent) === false) {
44
+ $this->parent->clear();
45
+ }
46
  }
47
 
48
  /**
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/Tag.php CHANGED
@@ -33,6 +33,13 @@ class Tag
33
  */
34
  protected $selfClosing = false;
35
 
 
 
 
 
 
 
 
36
  /**
37
  * Tag noise
38
  */
@@ -99,6 +106,19 @@ class Tag
99
  return $this;
100
  }
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  /**
103
  * Checks if the tag is self closing.
104
  *
@@ -153,6 +173,51 @@ class Tag
153
  return $this;
154
  }
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Removes an attribute from this tag.
158
  *
@@ -225,6 +290,17 @@ class Tag
225
  return $this->attr[$key];
226
  }
227
 
 
 
 
 
 
 
 
 
 
 
 
228
  /**
229
  * Generates the opening tag for this object.
230
  *
@@ -247,7 +323,7 @@ class Tag
247
  }
248
  }
249
 
250
- if ($this->selfClosing) {
251
  return $return.' />';
252
  } else {
253
  return $return.'>';
33
  */
34
  protected $selfClosing = false;
35
 
36
+ /**
37
+ * If self-closing, will this use a trailing slash. />
38
+ *
39
+ * @var bool
40
+ */
41
+ protected $trailingSlash = true;
42
+
43
  /**
44
  * Tag noise
45
  */
106
  return $this;
107
  }
108
 
109
+
110
+ /**
111
+ * Sets the tag to not use a trailing slash.
112
+ *
113
+ * @return $this
114
+ */
115
+ public function noTrailingSlash()
116
+ {
117
+ $this->trailingSlash = false;
118
+
119
+ return $this;
120
+ }
121
+
122
  /**
123
  * Checks if the tag is self closing.
124
  *
173
  return $this;
174
  }
175
 
176
+ /**
177
+ * Set inline style attribute value.
178
+ *
179
+ * @param $attr_key
180
+ * @param $attr_value
181
+ */
182
+ public function setStyleAttributeValue($attr_key, $attr_value)
183
+ {
184
+
185
+ $style_array = $this->getStyleAttributeArray();
186
+ $style_array[$attr_key] = $attr_value;
187
+
188
+ $style_string = '';
189
+ foreach ($style_array as $key => $value) {
190
+ $style_string .= $key . ':' . $value . ';';
191
+ }
192
+
193
+ $this->setAttribute('style', $style_string);
194
+ }
195
+
196
+ /**
197
+ * Get style attribute in array
198
+ *
199
+ * @return array|null
200
+ */
201
+ public function getStyleAttributeArray()
202
+ {
203
+ $value = $this->getAttribute('style')['value'];
204
+
205
+ if ($value === null) {
206
+ return null;
207
+ }
208
+
209
+ $value = explode(';', substr(trim($value), 0, -1));
210
+ $result = [];
211
+ foreach ($value as $attr) {
212
+ $attr = explode(':', $attr);
213
+ $result[$attr[0]] = $attr[1];
214
+ }
215
+
216
+ return $result;
217
+ }
218
+
219
+
220
+
221
  /**
222
  * Removes an attribute from this tag.
223
  *
290
  return $this->attr[$key];
291
  }
292
 
293
+ /**
294
+ * Returns TRUE if node has attribute
295
+ *
296
+ * @param string $key
297
+ * @return bool
298
+ */
299
+ public function hasAttribute($key)
300
+ {
301
+ return isset($this->attr[$key]);
302
+ }
303
+
304
  /**
305
  * Generates the opening tag for this object.
306
  *
323
  }
324
  }
325
 
326
+ if ($this->selfClosing && $this->trailingSlash) {
327
  return $return.' />';
328
  } else {
329
  return $return.'>';
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/TextNode.php CHANGED
@@ -35,10 +35,12 @@ class TextNode extends LeafNode
35
  *
36
  * @param string $text
37
  */
38
- public function __construct($text)
39
  {
40
- // remove double spaces
41
- $text = mb_ereg_replace('\s+', ' ', $text);
 
 
42
 
43
  // restore line breaks
44
  $text = str_replace('&#10;', "\n", $text);
@@ -72,6 +74,24 @@ class TextNode extends LeafNode
72
  }
73
  }
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /**
76
  * This node has no html, just return the text.
77
  *
@@ -102,4 +122,14 @@ class TextNode extends LeafNode
102
  {
103
  $this->convertedText = null;
104
  }
 
 
 
 
 
 
 
 
 
 
105
  }
35
  *
36
  * @param string $text
37
  */
38
+ public function __construct($text, $removeDoubleSpace = true)
39
  {
40
+ if ($removeDoubleSpace) {
41
+ // remove double spaces
42
+ $text = mb_ereg_replace('\s+', ' ', $text);
43
+ }
44
 
45
  // restore line breaks
46
  $text = str_replace('&#10;', "\n", $text);
74
  }
75
  }
76
 
77
+ /**
78
+ * Sets the text for this node.
79
+ *
80
+ * @var string $text
81
+ * @return void
82
+ */
83
+ public function setText($text)
84
+ {
85
+ $this->text = $text;
86
+
87
+ if ( ! is_null($this->encode)) {
88
+ $text = $this->encode->convert($text);
89
+
90
+ // remember the conversion
91
+ $this->convertedText = $text;
92
+ }
93
+ }
94
+
95
  /**
96
  * This node has no html, just return the text.
97
  *
122
  {
123
  $this->convertedText = null;
124
  }
125
+
126
+ /**
127
+ * Checks if the current node is a text node.
128
+ *
129
+ * @return bool
130
+ */
131
+ public function isTextNode()
132
+ {
133
+ return true;
134
+ }
135
  }
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Finder.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace PHPHtmlParser;
4
+
5
+ use PHPHtmlParser\Dom\AbstractNode;
6
+
7
+ class Finder
8
+ {
9
+ private $id;
10
+
11
+ /**
12
+ * Finder constructor.
13
+ * @param $id
14
+ */
15
+ public function __construct($id)
16
+ {
17
+ $this->id = $id;
18
+ }
19
+
20
+ /**
21
+ *
22
+ * Find node in tree by id
23
+ *
24
+ * @param AbstractNode $node
25
+ * @return bool|AbstractNode
26
+ */
27
+ public function find(AbstractNode $node)
28
+ {
29
+ if (!$node->id()) {
30
+ return $this->find($node->firstChild());
31
+ }
32
+
33
+ if ($node->id() == $this->id) {
34
+ return $node;
35
+ }
36
+
37
+ if ($node->hasNextSibling()) {
38
+ $nextSibling = $node->nextSibling();
39
+ if ($nextSibling->id() == $this->id) {
40
+ return $nextSibling;
41
+ }
42
+ if ($nextSibling->id() > $this->id) {
43
+ return $this->find($node->firstChild());
44
+ }
45
+ if ($nextSibling->id() < $this->id) {
46
+ return $this->find($nextSibling);
47
+ }
48
+ } else if (!$node->isTextNode()) {
49
+ return $this->find($node->firstChild());
50
+ }
51
+
52
+ return false;
53
+ }
54
+ }
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Options.php CHANGED
@@ -25,6 +25,7 @@ class Options
25
  'removeScripts' => true,
26
  'removeStyles' => true,
27
  'preserveLineBreaks' => false,
 
28
  ];
29
 
30
  /**
25
  'removeScripts' => true,
26
  'removeStyles' => true,
27
  'preserveLineBreaks' => false,
28
+ 'removeDoubleSpace' => true,
29
  ];
30
 
31
  /**
vendor/paquettg/php-html-parser/src/PHPHtmlParser/Selector.php CHANGED
@@ -232,9 +232,7 @@ class Selector
232
  $pass = false;
233
  }
234
  } else {
235
- if ($rule['key'] != 'plaintext' &&
236
- is_null($child->getAttribute($rule['key']))
237
- ) {
238
  $pass = false;
239
  }
240
  }
232
  $pass = false;
233
  }
234
  } else {
235
+ if ($rule['key'] != 'plaintext' && !$child->hasAttribute($rule['key'])) {
 
 
236
  $pass = false;
237
  }
238
  }