Version Description
- Fix: Background CSS wasn't working properly in a few cases.
- Update: Lazysizes updated to 5.1.1 (from 5.0.0).
- Update: Parser optimized.
Download this release
Release Info
Developer | TigrouMeow |
Plugin | WP Retina 2x |
Version | 5.5.7 |
Comparing to | |
See all releases |
Code changes from version 5.5.6 to 5.5.7
- common/admin.php +45 -31
- core.php +18 -15
- dashboard.php +2 -2
- js/lazysizes.min.js +1 -1
- readme.txt +6 -1
- vendor/composer/ClassLoader.php +1 -1
- vendor/composer/installed.json +6 -6
- vendor/kub-at/php-simple-html-dom-parser/README.md +2 -2
- vendor/kub-at/php-simple-html-dom-parser/src/KubAT/PhpSimple/lib/simple_html_dom.php +275 -737
- wp-retina-2x.php +3 -3
common/admin.php
CHANGED
@@ -29,22 +29,25 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
|
|
29 |
$this->prefix = $prefix;
|
30 |
$this->mainfile = $mainfile;
|
31 |
$this->domain = $domain;
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
44 |
}
|
45 |
}
|
46 |
}
|
47 |
-
|
48 |
add_filter( 'edd_sl_api_request_verify_ssl', array( $this, 'request_verify_ssl' ), 10, 0 );
|
49 |
}
|
50 |
|
@@ -348,30 +351,41 @@ if ( !class_exists( 'MeowApps_Admin' ) ) {
|
|
348 |
|
349 |
<h2 style="margin-bottom: 0px; margin-top: 25px;">Featured Plugins</h2>
|
350 |
<div class="meow-row meow-featured-plugins">
|
351 |
-
<div class="meow-box meow-col meow-span_1_of_2 ">
|
352 |
-
<ul class="">
|
353 |
-
<li><img src='<?= $this->common_url( 'img/wplr-sync.jpg' ) ?>' /><b>WP/LR Sync</b>
|
354 |
-
<?php echo $this->check_install( 'wplr-sync' ) ?><br />
|
355 |
-
Synchronize photos (folders, collections, keywords) from Lightroom to WordPress.</li>
|
356 |
-
<li><img src='<?= $this->common_url( 'img/meow-lightbox.jpg' ) ?>' /><b>Meow Lightbox</b>
|
357 |
-
<?php echo $this->check_install( 'meow-lightbox' ) ?><br />
|
358 |
-
Light but powerful lightbox that can also display photo information (EXIF).</li>
|
359 |
-
<li><img src='<?= $this->common_url( 'img/meow-gallery.jpg' ) ?>' /><b>Meow Gallery</b>
|
360 |
-
<?php echo $this->check_install( 'meow-gallery' ) ?><br />
|
361 |
-
Gallery (using the built-in WP gallery) that makes your website look better.</li>
|
362 |
-
</ul>
|
363 |
-
</div>
|
364 |
<div class="meow-box meow-col meow-span_1_of_2">
|
365 |
<ul class="">
|
366 |
-
<li><img src='<?= $this->common_url( 'img/media-
|
367 |
-
|
368 |
-
For nicer filenames and better SEO.</li>
|
369 |
-
<li><img src='<?= $this->common_url( 'img/media-cleaner.jpg' ) ?>' /><b>Media Cleaner</b>
|
370 |
<?php echo $this->check_install( 'media-cleaner' ) ?><br />
|
371 |
Detect the files which are not in use.</li>
|
372 |
-
<li><img src='<?= $this->common_url( 'img/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
<?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
|
374 |
-
The famous plugin that adds Retina support.</li
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
</ul>
|
376 |
</div>
|
377 |
</div>
|
29 |
$this->prefix = $prefix;
|
30 |
$this->mainfile = $mainfile;
|
31 |
$this->domain = $domain;
|
32 |
+
$this->is_theme = ( strpos( $this->mainfile, '-theme' ) !== false );
|
33 |
|
34 |
+
// If there is no mainfile, it's either a Pro only Plugin (with no Free version available) or a Theme.
|
35 |
+
if ( !$this->is_theme ) {
|
36 |
+
register_activation_hook( $mainfile, array( $this, 'show_meowapps_create_rating_date' ) );
|
37 |
+
if ( is_admin() ) {
|
38 |
+
$license = get_option( $this->prefix . '_license', "" );
|
39 |
+
if ( ( !empty( $license ) ) && !file_exists( plugin_dir_path( $this->mainfile ) . 'common/meowapps/admin.php' ) ) {
|
40 |
+
add_action( 'admin_notices', array( $this, 'admin_notices_licensed_free' ) );
|
41 |
+
}
|
42 |
+
if ( !$disableReview ) {
|
43 |
+
$rating_date = $this->create_rating_date();
|
44 |
+
if ( time() > $rating_date ) {
|
45 |
+
add_action( 'admin_notices', array( $this, 'admin_notices_rating' ) );
|
46 |
+
}
|
47 |
}
|
48 |
}
|
49 |
}
|
50 |
+
|
51 |
add_filter( 'edd_sl_api_request_verify_ssl', array( $this, 'request_verify_ssl' ), 10, 0 );
|
52 |
}
|
53 |
|
351 |
|
352 |
<h2 style="margin-bottom: 0px; margin-top: 25px;">Featured Plugins</h2>
|
353 |
<div class="meow-row meow-featured-plugins">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
<div class="meow-box meow-col meow-span_1_of_2">
|
355 |
<ul class="">
|
356 |
+
<li><img src='<?= $this->common_url( 'img/media-cleaner.jpg' ) ?>' />
|
357 |
+
<a href='https://meowapps.com/plugin/media-cleaner/'><b>Media Cleaner</b></a>
|
|
|
|
|
358 |
<?php echo $this->check_install( 'media-cleaner' ) ?><br />
|
359 |
Detect the files which are not in use.</li>
|
360 |
+
<li><img src='<?= $this->common_url( 'img/media-file-renamer.jpg' ) ?>' />
|
361 |
+
<a href='https://meowapps.com/plugin/media-file-renamer/'><b>Media File Renamer</b></a>
|
362 |
+
<?php echo $this->check_install( 'media-file-renamer' ) ?><br />
|
363 |
+
For nicer filenames and a better SEO.</li>
|
364 |
+
<li><img src='<?= $this->common_url( 'img/default.png' ) ?>' />
|
365 |
+
<a href='https://meowapps.com/plugin/contact-form-block/'><b>Contact Form Block</b></a>
|
366 |
+
<?php echo $this->check_install( 'contact-form-block' ) ?><br />
|
367 |
+
A simpler, nicer, prettier contact form.</li>
|
368 |
+
<!--li><img src='<?= $this->common_url( 'img/wp-retina-2x.jpg' ) ?>' />
|
369 |
+
<a href='https://meowapps.com/plugin/wp-retina-2x/'><b>WP Retina 2x</b></a>
|
370 |
<?php echo $this->check_install( 'wp-retina-2x' ) ?><br />
|
371 |
+
The famous plugin that adds Retina support.</li-->
|
372 |
+
|
373 |
+
</ul>
|
374 |
+
</div>
|
375 |
+
<div class="meow-box meow-col meow-span_1_of_2 ">
|
376 |
+
<ul class="">
|
377 |
+
<li><img src='<?= $this->common_url( 'img/meow-gallery.jpg' ) ?>' />
|
378 |
+
<a href='https://meowapps.com/plugin/meow-gallery/'><b>Meow Gallery</b></a>
|
379 |
+
<?php echo $this->check_install( 'meow-gallery' ) ?><br />
|
380 |
+
Beautiful but lightweight gallery with many layouts. The only one that allows you to uninstall it without losing anything.</li>
|
381 |
+
<li><img src='<?= $this->common_url( 'img/meow-lightbox.jpg' ) ?>' />
|
382 |
+
<a href='https://meowapps.com/plugin/meow-lightbox/'><b>Meow Lightbox</b></a>
|
383 |
+
<?php echo $this->check_install( 'meow-lightbox' ) ?><br />
|
384 |
+
Pretty and ultra-optimized Lightbox which can also display your EXIF data. You will love it.</li>
|
385 |
+
<li><img src='<?= $this->common_url( 'img/wplr-sync.jpg' ) ?>' />
|
386 |
+
<a href='https://meowapps.com/plugin/wplr-sync/'><b>WP/LR Sync</b></a>
|
387 |
+
<?php echo $this->check_install( 'wplr-sync' ) ?><br />
|
388 |
+
Synchronize your Lightroom to your WordPress. This plugin is loved by all the photographers using Lightroom and WordPress.</li>
|
389 |
</ul>
|
390 |
</div>
|
391 |
</div>
|
core.php
CHANGED
@@ -34,12 +34,10 @@ class Meow_WR2X_Core {
|
|
34 |
}
|
35 |
|
36 |
function is_rest() {
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
return true;
|
42 |
-
return false;
|
43 |
}
|
44 |
|
45 |
function init() {
|
@@ -206,21 +204,26 @@ class Meow_WR2X_Core {
|
|
206 |
if ( get_option( 'wr2x_picturefill_css_background', false ) && $this->admin->is_registered() ) {
|
207 |
// Standard CSS background
|
208 |
preg_match_all( "/url(?:\(['\"]?)(.*?)(?:['\"]?\))/", $buffer, $matches );
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
211 |
// Lazy CSS background
|
212 |
preg_match_all( "/data-background=(?:['\"])(.*?)(?:['\"])/", $buffer, $matches );
|
213 |
-
|
214 |
-
|
|
|
|
|
215 |
// Lazy CSS background
|
216 |
preg_match_all( "/data-bigimg=(?:['\"])(.*?)(?:['\"])/", $buffer, $matches );
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
$nodes_count = 0;
|
222 |
$nodes_replaced = 0;
|
223 |
-
for ( $c = 0; $c < count( $
|
224 |
$css = $match_css[$c];
|
225 |
$url = $match_url[$c];
|
226 |
if ( !$this->is_supported_image( $url ) )
|
34 |
}
|
35 |
|
36 |
function is_rest() {
|
37 |
+
if ( empty( $_SERVER[ 'REQUEST_URI' ] ) )
|
38 |
+
return false;
|
39 |
+
$rest_prefix = trailingslashit( rest_get_url_prefix() );
|
40 |
+
return strpos( $_SERVER[ 'REQUEST_URI' ], $rest_prefix ) !== false ? true : false;
|
|
|
|
|
41 |
}
|
42 |
|
43 |
function init() {
|
204 |
if ( get_option( 'wr2x_picturefill_css_background', false ) && $this->admin->is_registered() ) {
|
205 |
// Standard CSS background
|
206 |
preg_match_all( "/url(?:\(['\"]?)(.*?)(?:['\"]?\))/", $buffer, $matches );
|
207 |
+
//error_log( print_r( $matches, 1 ) );
|
208 |
+
if ( count( $matches ) == 2 ) {
|
209 |
+
$match_css = $matches[0];
|
210 |
+
$match_url = $matches[1];
|
211 |
+
}
|
212 |
// Lazy CSS background
|
213 |
preg_match_all( "/data-background=(?:['\"])(.*?)(?:['\"])/", $buffer, $matches );
|
214 |
+
if ( count( $matches ) == 2 ) {
|
215 |
+
$match_css = array_merge( $match_css, $matches[0] );
|
216 |
+
$match_url = array_merge( $match_url, $matches[1] );
|
217 |
+
}
|
218 |
// Lazy CSS background
|
219 |
preg_match_all( "/data-bigimg=(?:['\"])(.*?)(?:['\"])/", $buffer, $matches );
|
220 |
+
if ( count( $matches ) == 2 ) {
|
221 |
+
$match_css = array_merge( $match_css, $matches[0] );
|
222 |
+
$match_url = array_merge( $match_url, $matches[1] );
|
223 |
+
}
|
224 |
$nodes_count = 0;
|
225 |
$nodes_replaced = 0;
|
226 |
+
for ( $c = 0; $c < count( $match_css ); $c++ ) {
|
227 |
$css = $match_css[$c];
|
228 |
$url = $match_url[$c];
|
229 |
if ( !$this->is_supported_image( $url ) )
|
dashboard.php
CHANGED
@@ -214,9 +214,9 @@ class Meow_WR2X_Dashboard {
|
|
214 |
$disable_responsive = get_option( 'wr2x_disable_responsive', false );
|
215 |
$keep_src = get_option( 'wr2x_picturefill_keep_src', false );
|
216 |
|
217 |
-
if ( $method == 'HTML Rewrite' || $method == 'Retina-Images' || $disable_responsive
|
218 |
echo '<div class="error"><p>';
|
219 |
-
echo __( '<b>WARNING</b>. You are using an option that will be removed in a future release. The plan is to remove two methods (HTML Rewrite and Retina-Images), Disable Responsive
|
220 |
echo '</p></div>';
|
221 |
}
|
222 |
?>
|
214 |
$disable_responsive = get_option( 'wr2x_disable_responsive', false );
|
215 |
$keep_src = get_option( 'wr2x_picturefill_keep_src', false );
|
216 |
|
217 |
+
if ( $method == 'HTML Rewrite' || $method == 'Retina-Images' || $disable_responsive ) {
|
218 |
echo '<div class="error"><p>';
|
219 |
+
echo __( '<b>WARNING</b>. You are using an option that will be removed in a future release. The plan is to remove two methods (HTML Rewrite and Retina-Images), and Disable Responsive. Those options are not necessary, and it is better to keep the plugin clean and focus. This warning message will go away if you avoid using those options (and will disappear in a future release). If you are using one of those options and really would like to keep it, please contact the support.', 'wp-retina-2x' );
|
220 |
echo '</p></div>';
|
221 |
}
|
222 |
?>
|
js/lazysizes.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
/*! lazysizes - v5.1.
|
2 |
!function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}("undefined"!=typeof window?window:{},function(a,b){"use strict";var c,d;if(function(){var b,c={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};d=a.lazySizesConfig||a.lazysizesConfig||{};for(b in c)b in d||(d[b]=c[b])}(),!b||!b.getElementsByClassName)return{init:function(){},cfg:d,noSupport:!0};var e=b.documentElement,f=a.Date,g=a.HTMLPictureElement,h="addEventListener",i="getAttribute",j=a[h],k=a.setTimeout,l=a.requestAnimationFrame||k,m=a.requestIdleCallback,n=/^picture$/i,o=["load","error","lazyincluded","_lazyloaded"],p={},q=Array.prototype.forEach,r=function(a,b){return p[b]||(p[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),p[b].test(a[i]("class")||"")&&p[b]},s=function(a,b){r(a,b)||a.setAttribute("class",(a[i]("class")||"").trim()+" "+b)},t=function(a,b){var c;(c=r(a,b))&&a.setAttribute("class",(a[i]("class")||"").replace(c," "))},u=function(a,b,c){var d=c?h:"removeEventListener";c&&u(a,b),o.forEach(function(c){a[d](c,b)})},v=function(a,d,e,f,g){var h=b.createEvent("Event");return e||(e={}),e.instance=c,h.initEvent(d,!f,!g),h.detail=e,a.dispatchEvent(h),h},w=function(b,c){var e;!g&&(e=a.picturefill||d.pf)?(c&&c.src&&!b[i]("srcset")&&b.setAttribute("srcset",c.src),e({reevaluate:!0,elements:[b]})):c&&c.src&&(b.src=c.src)},x=function(a,b){return(getComputedStyle(a,null)||{})[b]},y=function(a,b,c){for(c=c||a.offsetWidth;c<d.minSize&&b&&!a._lazysizesWidth;)c=b.offsetWidth,b=b.parentNode;return c},z=function(){var a,c,d=[],e=[],f=d,g=function(){var b=f;for(f=d.length?e:d,a=!0,c=!1;b.length;)b.shift()();a=!1},h=function(d,e){a&&!e?d.apply(this,arguments):(f.push(d),c||(c=!0,(b.hidden?k:l)(g)))};return h._lsFlush=g,h}(),A=function(a,b){return b?function(){z(a)}:function(){var b=this,c=arguments;z(function(){a.apply(b,c)})}},B=function(a){var b,c=0,e=d.throttleDelay,g=d.ricTimeout,h=function(){b=!1,c=f.now(),a()},i=m&&g>49?function(){m(h,{timeout:g}),g!==d.ricTimeout&&(g=d.ricTimeout)}:A(function(){k(h)},!0);return function(a){var d;(a=!0===a)&&(g=33),b||(b=!0,d=e-(f.now()-c),d<0&&(d=0),a||d<9?i():k(i,d))}},C=function(a){var b,c,d=99,e=function(){b=null,a()},g=function(){var a=f.now()-c;a<d?k(g,d-a):(m||e)(e)};return function(){c=f.now(),b||(b=k(g,d))}},D=function(){var g,l,m,o,p,y,D,F,G,H,I,J,K=/^img$/i,L=/^iframe$/i,M="onscroll"in a&&!/(gle|ing)bot/.test(navigator.userAgent),N=0,O=0,P=0,Q=-1,R=function(a){P--,(!a||P<0||!a.target)&&(P=0)},S=function(a){return null==J&&(J="hidden"==x(b.body,"visibility")),J||"hidden"!=x(a.parentNode,"visibility")&&"hidden"!=x(a,"visibility")},T=function(a,c){var d,f=a,g=S(a);for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=e;)(g=(x(f,"opacity")||1)>0)&&"visible"!=x(f,"overflow")&&(d=f.getBoundingClientRect(),g=H>d.left&&G<d.right&&I>d.top-1&&F<d.bottom+1);return g},U=function(){var a,f,h,j,k,m,n,p,q,r,s,t,u=c.elements;if((o=d.loadMode)&&P<8&&(a=u.length)){for(f=0,Q++;f<a;f++)if(u[f]&&!u[f]._lazyRace)if(!M||c.prematureUnveil&&c.prematureUnveil(u[f]))aa(u[f]);else if((p=u[f][i]("data-expand"))&&(m=1*p)||(m=O),r||(r=!d.expand||d.expand<1?e.clientHeight>500&&e.clientWidth>500?500:370:d.expand,c._defEx=r,s=r*d.expFactor,t=d.hFac,J=null,O<s&&P<1&&Q>2&&o>2&&!b.hidden?(O=s,Q=0):O=o>1&&Q>1&&P<6?r:N),q!==m&&(y=innerWidth+m*t,D=innerHeight+m,n=-1*m,q=m),h=u[f].getBoundingClientRect(),(I=h.bottom)>=n&&(F=h.top)<=D&&(H=h.right)>=n*t&&(G=h.left)<=y&&(I||H||G||F)&&(d.loadHidden||S(u[f]))&&(l&&P<3&&!p&&(o<3||Q<4)||T(u[f],m))){if(aa(u[f]),k=!0,P>9)break}else!k&&l&&!j&&P<4&&Q<4&&o>2&&(g[0]||d.preloadAfterLoad)&&(g[0]||!p&&(I||H||G||F||"auto"!=u[f][i](d.sizesAttr)))&&(j=g[0]||u[f]);j&&!k&&aa(j)}},V=B(U),W=function(a){var b=a.target;if(b._lazyCache)return void delete b._lazyCache;R(a),s(b,d.loadedClass),t(b,d.loadingClass),u(b,Y),v(b,"lazyloaded")},X=A(W),Y=function(a){X({target:a.target})},Z=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},$=function(a){var b,c=a[i](d.srcsetAttr);(b=d.customMedia[a[i]("data-media")||a[i]("media")])&&a.setAttribute("media",b),c&&a.setAttribute("srcset",c)},_=A(function(a,b,c,e,f){var g,h,j,l,o,p;(o=v(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(c?s(a,d.autosizesClass):a.setAttribute("sizes",e)),h=a[i](d.srcsetAttr),g=a[i](d.srcAttr),f&&(j=a.parentNode,l=j&&n.test(j.nodeName||"")),p=b.firesLoad||"src"in a&&(h||g||l),o={target:a},s(a,d.loadingClass),p&&(clearTimeout(m),m=k(R,2500),u(a,Y,!0)),l&&q.call(j.getElementsByTagName("source"),$),h?a.setAttribute("srcset",h):g&&!l&&(L.test(a.nodeName)?Z(a,g):a.src=g),f&&(h||l)&&w(a,{src:g})),a._lazyRace&&delete a._lazyRace,t(a,d.lazyClass),z(function(){var b=a.complete&&a.naturalWidth>1;p&&!b||(b&&s(a,"ls-is-cached"),W(o),a._lazyCache=!0,k(function(){"_lazyCache"in a&&delete a._lazyCache},9)),"lazy"==a.loading&&P--},!0)}),aa=function(a){if(!a._lazyRace){var b,c=K.test(a.nodeName),e=c&&(a[i](d.sizesAttr)||a[i]("sizes")),f="auto"==e;(!f&&l||!c||!a[i]("src")&&!a.srcset||a.complete||r(a,d.errorClass)||!r(a,d.lazyClass))&&(b=v(a,"lazyunveilread").detail,f&&E.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,P++,_(a,b,f,e,c))}},ba=C(function(){d.loadMode=3,V()}),ca=function(){3==d.loadMode&&(d.loadMode=2),ba()},da=function(){if(!l){if(f.now()-p<999)return void k(da,999);l=!0,d.loadMode=3,V(),j("scroll",ca,!0)}};return{_:function(){p=f.now(),c.elements=b.getElementsByClassName(d.lazyClass),g=b.getElementsByClassName(d.lazyClass+" "+d.preloadClass),j("scroll",V,!0),j("resize",V,!0),a.MutationObserver?new MutationObserver(V).observe(e,{childList:!0,subtree:!0,attributes:!0}):(e[h]("DOMNodeInserted",V,!0),e[h]("DOMAttrModified",V,!0),setInterval(V,999)),j("hashchange",V,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(a){b[h](a,V,!0)}),/d$|^c/.test(b.readyState)?da():(j("load",da),b[h]("DOMContentLoaded",V),k(da,2e4)),c.elements.length?(U(),z._lsFlush()):V()},checkElems:V,unveil:aa,_aLSL:ca}}(),E=function(){var a,c=A(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),n.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;f<g;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||w(a,c.detail)}),e=function(a,b,d){var e,f=a.parentNode;f&&(d=y(a,f,d),e=v(a,"lazybeforesizes",{width:d,dataAttr:!!b}),e.defaultPrevented||(d=e.detail.width)&&d!==a._lazysizesWidth&&c(a,f,e,d))},f=function(){var b,c=a.length;if(c)for(b=0;b<c;b++)e(a[b])},g=C(f);return{_:function(){a=b.getElementsByClassName(d.autosizesClass),j("resize",g)},checkElems:g,updateElem:e}}(),F=function(){!F.i&&b.getElementsByClassName&&(F.i=!0,E._(),D._())};return k(function(){d.init&&F()}),c={cfg:d,autoSizer:E,loader:D,init:F,uP:w,aC:s,rC:t,hC:r,fire:v,gW:y,rAF:z}});
|
1 |
+
/*! lazysizes - v5.1.1 */
|
2 |
!function(a,b){var c=b(a,a.document);a.lazySizes=c,"object"==typeof module&&module.exports&&(module.exports=c)}("undefined"!=typeof window?window:{},function(a,b){"use strict";var c,d;if(function(){var b,c={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};d=a.lazySizesConfig||a.lazysizesConfig||{};for(b in c)b in d||(d[b]=c[b])}(),!b||!b.getElementsByClassName)return{init:function(){},cfg:d,noSupport:!0};var e=b.documentElement,f=a.Date,g=a.HTMLPictureElement,h="addEventListener",i="getAttribute",j=a[h],k=a.setTimeout,l=a.requestAnimationFrame||k,m=a.requestIdleCallback,n=/^picture$/i,o=["load","error","lazyincluded","_lazyloaded"],p={},q=Array.prototype.forEach,r=function(a,b){return p[b]||(p[b]=new RegExp("(\\s|^)"+b+"(\\s|$)")),p[b].test(a[i]("class")||"")&&p[b]},s=function(a,b){r(a,b)||a.setAttribute("class",(a[i]("class")||"").trim()+" "+b)},t=function(a,b){var c;(c=r(a,b))&&a.setAttribute("class",(a[i]("class")||"").replace(c," "))},u=function(a,b,c){var d=c?h:"removeEventListener";c&&u(a,b),o.forEach(function(c){a[d](c,b)})},v=function(a,d,e,f,g){var h=b.createEvent("Event");return e||(e={}),e.instance=c,h.initEvent(d,!f,!g),h.detail=e,a.dispatchEvent(h),h},w=function(b,c){var e;!g&&(e=a.picturefill||d.pf)?(c&&c.src&&!b[i]("srcset")&&b.setAttribute("srcset",c.src),e({reevaluate:!0,elements:[b]})):c&&c.src&&(b.src=c.src)},x=function(a,b){return(getComputedStyle(a,null)||{})[b]},y=function(a,b,c){for(c=c||a.offsetWidth;c<d.minSize&&b&&!a._lazysizesWidth;)c=b.offsetWidth,b=b.parentNode;return c},z=function(){var a,c,d=[],e=[],f=d,g=function(){var b=f;for(f=d.length?e:d,a=!0,c=!1;b.length;)b.shift()();a=!1},h=function(d,e){a&&!e?d.apply(this,arguments):(f.push(d),c||(c=!0,(b.hidden?k:l)(g)))};return h._lsFlush=g,h}(),A=function(a,b){return b?function(){z(a)}:function(){var b=this,c=arguments;z(function(){a.apply(b,c)})}},B=function(a){var b,c=0,e=d.throttleDelay,g=d.ricTimeout,h=function(){b=!1,c=f.now(),a()},i=m&&g>49?function(){m(h,{timeout:g}),g!==d.ricTimeout&&(g=d.ricTimeout)}:A(function(){k(h)},!0);return function(a){var d;(a=!0===a)&&(g=33),b||(b=!0,d=e-(f.now()-c),d<0&&(d=0),a||d<9?i():k(i,d))}},C=function(a){var b,c,d=99,e=function(){b=null,a()},g=function(){var a=f.now()-c;a<d?k(g,d-a):(m||e)(e)};return function(){c=f.now(),b||(b=k(g,d))}},D=function(){var g,l,m,o,p,y,D,F,G,H,I,J,K=/^img$/i,L=/^iframe$/i,M="onscroll"in a&&!/(gle|ing)bot/.test(navigator.userAgent),N=0,O=0,P=0,Q=-1,R=function(a){P--,(!a||P<0||!a.target)&&(P=0)},S=function(a){return null==J&&(J="hidden"==x(b.body,"visibility")),J||"hidden"!=x(a.parentNode,"visibility")&&"hidden"!=x(a,"visibility")},T=function(a,c){var d,f=a,g=S(a);for(F-=c,I+=c,G-=c,H+=c;g&&(f=f.offsetParent)&&f!=b.body&&f!=e;)(g=(x(f,"opacity")||1)>0)&&"visible"!=x(f,"overflow")&&(d=f.getBoundingClientRect(),g=H>d.left&&G<d.right&&I>d.top-1&&F<d.bottom+1);return g},U=function(){var a,f,h,j,k,m,n,p,q,r,s,t,u=c.elements;if((o=d.loadMode)&&P<8&&(a=u.length)){for(f=0,Q++;f<a;f++)if(u[f]&&!u[f]._lazyRace)if(!M||c.prematureUnveil&&c.prematureUnveil(u[f]))aa(u[f]);else if((p=u[f][i]("data-expand"))&&(m=1*p)||(m=O),r||(r=!d.expand||d.expand<1?e.clientHeight>500&&e.clientWidth>500?500:370:d.expand,c._defEx=r,s=r*d.expFactor,t=d.hFac,J=null,O<s&&P<1&&Q>2&&o>2&&!b.hidden?(O=s,Q=0):O=o>1&&Q>1&&P<6?r:N),q!==m&&(y=innerWidth+m*t,D=innerHeight+m,n=-1*m,q=m),h=u[f].getBoundingClientRect(),(I=h.bottom)>=n&&(F=h.top)<=D&&(H=h.right)>=n*t&&(G=h.left)<=y&&(I||H||G||F)&&(d.loadHidden||S(u[f]))&&(l&&P<3&&!p&&(o<3||Q<4)||T(u[f],m))){if(aa(u[f]),k=!0,P>9)break}else!k&&l&&!j&&P<4&&Q<4&&o>2&&(g[0]||d.preloadAfterLoad)&&(g[0]||!p&&(I||H||G||F||"auto"!=u[f][i](d.sizesAttr)))&&(j=g[0]||u[f]);j&&!k&&aa(j)}},V=B(U),W=function(a){var b=a.target;if(b._lazyCache)return void delete b._lazyCache;R(a),s(b,d.loadedClass),t(b,d.loadingClass),u(b,Y),v(b,"lazyloaded")},X=A(W),Y=function(a){X({target:a.target})},Z=function(a,b){try{a.contentWindow.location.replace(b)}catch(c){a.src=b}},$=function(a){var b,c=a[i](d.srcsetAttr);(b=d.customMedia[a[i]("data-media")||a[i]("media")])&&a.setAttribute("media",b),c&&a.setAttribute("srcset",c)},_=A(function(a,b,c,e,f){var g,h,j,l,o,p;(o=v(a,"lazybeforeunveil",b)).defaultPrevented||(e&&(c?s(a,d.autosizesClass):a.setAttribute("sizes",e)),h=a[i](d.srcsetAttr),g=a[i](d.srcAttr),f&&(j=a.parentNode,l=j&&n.test(j.nodeName||"")),p=b.firesLoad||"src"in a&&(h||g||l),o={target:a},s(a,d.loadingClass),p&&(clearTimeout(m),m=k(R,2500),u(a,Y,!0)),l&&q.call(j.getElementsByTagName("source"),$),h?a.setAttribute("srcset",h):g&&!l&&(L.test(a.nodeName)?Z(a,g):a.src=g),f&&(h||l)&&w(a,{src:g})),a._lazyRace&&delete a._lazyRace,t(a,d.lazyClass),z(function(){var b=a.complete&&a.naturalWidth>1;p&&!b||(b&&s(a,"ls-is-cached"),W(o),a._lazyCache=!0,k(function(){"_lazyCache"in a&&delete a._lazyCache},9)),"lazy"==a.loading&&P--},!0)}),aa=function(a){if(!a._lazyRace){var b,c=K.test(a.nodeName),e=c&&(a[i](d.sizesAttr)||a[i]("sizes")),f="auto"==e;(!f&&l||!c||!a[i]("src")&&!a.srcset||a.complete||r(a,d.errorClass)||!r(a,d.lazyClass))&&(b=v(a,"lazyunveilread").detail,f&&E.updateElem(a,!0,a.offsetWidth),a._lazyRace=!0,P++,_(a,b,f,e,c))}},ba=C(function(){d.loadMode=3,V()}),ca=function(){3==d.loadMode&&(d.loadMode=2),ba()},da=function(){if(!l){if(f.now()-p<999)return void k(da,999);l=!0,d.loadMode=3,V(),j("scroll",ca,!0)}};return{_:function(){p=f.now(),c.elements=b.getElementsByClassName(d.lazyClass),g=b.getElementsByClassName(d.lazyClass+" "+d.preloadClass),j("scroll",V,!0),j("resize",V,!0),a.MutationObserver?new MutationObserver(V).observe(e,{childList:!0,subtree:!0,attributes:!0}):(e[h]("DOMNodeInserted",V,!0),e[h]("DOMAttrModified",V,!0),setInterval(V,999)),j("hashchange",V,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(a){b[h](a,V,!0)}),/d$|^c/.test(b.readyState)?da():(j("load",da),b[h]("DOMContentLoaded",V),k(da,2e4)),c.elements.length?(U(),z._lsFlush()):V()},checkElems:V,unveil:aa,_aLSL:ca}}(),E=function(){var a,c=A(function(a,b,c,d){var e,f,g;if(a._lazysizesWidth=d,d+="px",a.setAttribute("sizes",d),n.test(b.nodeName||""))for(e=b.getElementsByTagName("source"),f=0,g=e.length;f<g;f++)e[f].setAttribute("sizes",d);c.detail.dataAttr||w(a,c.detail)}),e=function(a,b,d){var e,f=a.parentNode;f&&(d=y(a,f,d),e=v(a,"lazybeforesizes",{width:d,dataAttr:!!b}),e.defaultPrevented||(d=e.detail.width)&&d!==a._lazysizesWidth&&c(a,f,e,d))},f=function(){var b,c=a.length;if(c)for(b=0;b<c;b++)e(a[b])},g=C(f);return{_:function(){a=b.getElementsByClassName(d.autosizesClass),j("resize",g)},checkElems:g,updateElem:e}}(),F=function(){!F.i&&b.getElementsByClassName&&(F.i=!0,E._(),D._())};return k(function(){d.init&&F()}),c={cfg:d,autoSizer:E,loader:D,init:F,uP:w,aC:s,rC:t,hC:r,fire:v,gW:y,rAF:z}});
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Donate link: https://commerce.coinbase.com/checkout/d047546a-77a8-41c8-9ea9-4a95
|
|
5 |
Requires at least: 4.4
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 7.0
|
8 |
-
Stable tag: 5.5.
|
9 |
|
10 |
Make your website look beautiful and crisp on modern displays by creating and displaying retina images. WP 4.4+ is also supported and enhanced.
|
11 |
|
@@ -39,6 +39,11 @@ The plugin cannot inject CSS to handles the images added through CSS, that's bot
|
|
39 |
|
40 |
== Changelog ==
|
41 |
|
|
|
|
|
|
|
|
|
|
|
42 |
= 5.5.6 =
|
43 |
* Update: Lazysizes updated to 5.1.0 (from 4.0.4).
|
44 |
|
5 |
Requires at least: 4.4
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 7.0
|
8 |
+
Stable tag: 5.5.7
|
9 |
|
10 |
Make your website look beautiful and crisp on modern displays by creating and displaying retina images. WP 4.4+ is also supported and enhanced.
|
11 |
|
39 |
|
40 |
== Changelog ==
|
41 |
|
42 |
+
= 5.5.7 =
|
43 |
+
* Fix: Background CSS wasn't working properly in a few cases.
|
44 |
+
* Update: Lazysizes updated to 5.1.1 (from 5.0.0).
|
45 |
+
* Update: Parser optimized.
|
46 |
+
|
47 |
= 5.5.6 =
|
48 |
* Update: Lazysizes updated to 5.1.0 (from 4.0.4).
|
49 |
|
vendor/composer/ClassLoader.php
CHANGED
@@ -279,7 +279,7 @@ class ClassLoader
|
|
279 |
*/
|
280 |
public function setApcuPrefix($apcuPrefix)
|
281 |
{
|
282 |
-
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
283 |
}
|
284 |
|
285 |
/**
|
279 |
*/
|
280 |
public function setApcuPrefix($apcuPrefix)
|
281 |
{
|
282 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
283 |
}
|
284 |
|
285 |
/**
|
vendor/composer/installed.json
CHANGED
@@ -1,23 +1,23 @@
|
|
1 |
[
|
2 |
{
|
3 |
"name": "kub-at/php-simple-html-dom-parser",
|
4 |
-
"version": "1.
|
5 |
-
"version_normalized": "1.
|
6 |
"source": {
|
7 |
"type": "git",
|
8 |
"url": "https://github.com/Kub-AT/php-simple-html-dom-parser.git",
|
9 |
-
"reference": "
|
10 |
},
|
11 |
"dist": {
|
12 |
"type": "zip",
|
13 |
-
"url": "https://api.github.com/repos/Kub-AT/php-simple-html-dom-parser/zipball/
|
14 |
-
"reference": "
|
15 |
"shasum": ""
|
16 |
},
|
17 |
"require": {
|
18 |
"php": ">=5.3.2"
|
19 |
},
|
20 |
-
"time": "2019-
|
21 |
"type": "library",
|
22 |
"installation-source": "dist",
|
23 |
"autoload": {
|
1 |
[
|
2 |
{
|
3 |
"name": "kub-at/php-simple-html-dom-parser",
|
4 |
+
"version": "1.9",
|
5 |
+
"version_normalized": "1.9.0.0",
|
6 |
"source": {
|
7 |
"type": "git",
|
8 |
"url": "https://github.com/Kub-AT/php-simple-html-dom-parser.git",
|
9 |
+
"reference": "1fe277a7616b5d7cfd192a8908cbc7653dc9baee"
|
10 |
},
|
11 |
"dist": {
|
12 |
"type": "zip",
|
13 |
+
"url": "https://api.github.com/repos/Kub-AT/php-simple-html-dom-parser/zipball/1fe277a7616b5d7cfd192a8908cbc7653dc9baee",
|
14 |
+
"reference": "1fe277a7616b5d7cfd192a8908cbc7653dc9baee",
|
15 |
"shasum": ""
|
16 |
},
|
17 |
"require": {
|
18 |
"php": ">=5.3.2"
|
19 |
},
|
20 |
+
"time": "2019-06-03T05:50:36+00:00",
|
21 |
"type": "library",
|
22 |
"installation-source": "dist",
|
23 |
"autoload": {
|
vendor/kub-at/php-simple-html-dom-parser/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
php-simple-html-dom-parser
|
2 |
==========================
|
3 |
|
4 |
-
Version 1.
|
5 |
-
PHP Simple HTML DOM Parser changelog: https://sourceforge.net/projects/simplehtmldom/files/simplehtmldom/1.
|
6 |
|
7 |
|
8 |
Install
|
1 |
php-simple-html-dom-parser
|
2 |
==========================
|
3 |
|
4 |
+
Version 1.9 - PHP 7.3 compatible
|
5 |
+
PHP Simple HTML DOM Parser changelog: https://sourceforge.net/projects/simplehtmldom/files/simplehtmldom/1.9/
|
6 |
|
7 |
|
8 |
Install
|
vendor/kub-at/php-simple-html-dom-parser/src/KubAT/PhpSimple/lib/simple_html_dom.php
CHANGED
@@ -5,64 +5,24 @@ namespace simple_html_dom;
|
|
5 |
* Website: http://sourceforge.net/projects/simplehtmldom/
|
6 |
* Additional projects: http://sourceforge.net/projects/debugobject/
|
7 |
* Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
|
8 |
-
* Contributions by:
|
9 |
-
* Yousuke Kumakura (Attribute filters)
|
10 |
-
* Vadim Voituk (Negative indexes supports of "find" method)
|
11 |
-
* Antcs (Constructor with automatically load contents either text or file/url)
|
12 |
*
|
13 |
-
*
|
14 |
-
*
|
15 |
-
* Paperg - Added case insensitive testing of the value of the selector.
|
16 |
-
*
|
17 |
-
* Paperg - Added tag_start for the starting index of tags - NOTE: This works
|
18 |
-
* but not accurately. This tag_start gets counted AFTER \r\n have been crushed
|
19 |
-
* out, and after the remove_noice calls so it will not reflect the REAL
|
20 |
-
* position of the tag in the source, it will almost always be smaller by some
|
21 |
-
* amount. We use this to determine how far into the file the tag in question
|
22 |
-
* is. This "percentage" will never be accurate as the $dom->size is the "real"
|
23 |
-
* number of bytes the dom was created from. But for most purposes, it's a
|
24 |
-
* really good estimation.
|
25 |
-
*
|
26 |
-
* Paperg - Added the forceTagsClosed to the dom constructor. Forcing tags
|
27 |
-
* closed is great for malformed html, but it CAN lead to parsing errors.
|
28 |
-
*
|
29 |
-
* Allow the user to tell us how much they trust the html.
|
30 |
-
*
|
31 |
-
* Paperg add the text and plaintext to the selectors for the find syntax.
|
32 |
-
* plaintext implies text in the innertext of a node. text implies that the
|
33 |
-
* tag is a text node. This allows for us to find tags based on the text they
|
34 |
-
* contain.
|
35 |
-
*
|
36 |
-
* Create find_ancestor_tag to see if a tag is - at any level - inside of
|
37 |
-
* another specific tag.
|
38 |
-
*
|
39 |
-
* Paperg: added parse_charset so that we know about the character set of
|
40 |
-
* the source document. NOTE: If the user's system has a routine called
|
41 |
-
* get_last_retrieve_url_contents_content_type availalbe, we will assume it's
|
42 |
-
* returning the content-type header from the last transfer or curl_exec, and
|
43 |
-
* we will parse that and use it in preference to any other method of charset
|
44 |
-
* detection.
|
45 |
-
*
|
46 |
-
* Found infinite loop in the case of broken html in restore_noise. Rewrote to
|
47 |
-
* protect from that.
|
48 |
*
|
49 |
-
*
|
|
|
|
|
|
|
|
|
50 |
*
|
51 |
-
*
|
52 |
-
*
|
|
|
|
|
53 |
*
|
54 |
-
*
|
55 |
-
* @author John Schlick
|
56 |
-
* @author Rus Carroll
|
57 |
-
* @version Rev. 1.8.1 (247)
|
58 |
-
* @package PlaceLocalInclude
|
59 |
-
* @subpackage simple_html_dom
|
60 |
*/
|
61 |
|
62 |
-
/**
|
63 |
-
* All of the Defines for the classes below.
|
64 |
-
* @author S.C. Chen <me578022@gmail.com>
|
65 |
-
*/
|
66 |
define('HDOM_TYPE_ELEMENT', 1);
|
67 |
define('HDOM_TYPE_COMMENT', 2);
|
68 |
define('HDOM_TYPE_TEXT', 3);
|
@@ -81,25 +41,12 @@ define('HDOM_INFO_INNER', 5);
|
|
81 |
define('HDOM_INFO_OUTER', 6);
|
82 |
define('HDOM_INFO_ENDSPACE', 7);
|
83 |
|
84 |
-
/** The default target charset */
|
85 |
defined('DEFAULT_TARGET_CHARSET') || define('DEFAULT_TARGET_CHARSET', 'UTF-8');
|
86 |
-
|
87 |
-
/** The default <br> text used instead of <br> tags when returning text */
|
88 |
defined('DEFAULT_BR_TEXT') || define('DEFAULT_BR_TEXT', "\r\n");
|
89 |
-
|
90 |
-
/** The default <span> text used instead of <span> tags when returning text */
|
91 |
defined('DEFAULT_SPAN_TEXT') || define('DEFAULT_SPAN_TEXT', ' ');
|
92 |
-
|
93 |
-
/** The maximum file size the parser should load */
|
94 |
defined('MAX_FILE_SIZE') || define('MAX_FILE_SIZE', 600000);
|
95 |
-
|
96 |
-
/** Contents between curly braces "{" and "}" are interpreted as text */
|
97 |
define('HDOM_SMARTY_AS_TEXT', 1);
|
98 |
|
99 |
-
// helper functions
|
100 |
-
// -----------------------------------------------------------------------------
|
101 |
-
// get html dom from file
|
102 |
-
// $maxlen is defined in the code as PHP_STREAM_COPY_ALL which is defined as -1.
|
103 |
function file_get_html(
|
104 |
$url,
|
105 |
$use_include_path = false,
|
@@ -113,10 +60,8 @@ function file_get_html(
|
|
113 |
$defaultBRText = DEFAULT_BR_TEXT,
|
114 |
$defaultSpanText = DEFAULT_SPAN_TEXT)
|
115 |
{
|
116 |
-
// Ensure maximum length is greater than zero
|
117 |
if($maxLen <= 0) { $maxLen = MAX_FILE_SIZE; }
|
118 |
|
119 |
-
// We DO force the tags to be terminated.
|
120 |
$dom = new simple_html_dom(
|
121 |
null,
|
122 |
$lowercase,
|
@@ -124,7 +69,8 @@ function file_get_html(
|
|
124 |
$target_charset,
|
125 |
$stripRN,
|
126 |
$defaultBRText,
|
127 |
-
$defaultSpanText
|
|
|
128 |
|
129 |
/**
|
130 |
* For sourceforge users: uncomment the next line and comment the
|
@@ -135,19 +81,18 @@ function file_get_html(
|
|
135 |
$use_include_path,
|
136 |
$context,
|
137 |
$offset,
|
138 |
-
$maxLen
|
139 |
-
|
140 |
-
// Paperg - use our own mechanism for getting the contents as we want to
|
141 |
-
// control the timeout.
|
142 |
// $contents = retrieve_url_contents($url);
|
143 |
-
if (empty($contents) || strlen($contents) > $maxLen) { return false; }
|
144 |
|
145 |
-
|
146 |
-
|
147 |
-
|
|
|
|
|
|
|
148 |
}
|
149 |
|
150 |
-
// get html dom from string
|
151 |
function str_get_html(
|
152 |
$str,
|
153 |
$lowercase = true,
|
@@ -164,97 +109,34 @@ function str_get_html(
|
|
164 |
$target_charset,
|
165 |
$stripRN,
|
166 |
$defaultBRText,
|
167 |
-
$defaultSpanText
|
|
|
168 |
|
169 |
if (empty($str) || strlen($str) > MAX_FILE_SIZE) {
|
170 |
$dom->clear();
|
171 |
return false;
|
172 |
}
|
173 |
|
174 |
-
$dom->load($str, $lowercase, $stripRN);
|
175 |
-
return $dom;
|
176 |
}
|
177 |
|
178 |
-
// dump html dom tree
|
179 |
function dump_html_tree($node, $show_attr = true, $deep = 0)
|
180 |
{
|
181 |
$node->dump($node);
|
182 |
}
|
183 |
|
184 |
-
/**
|
185 |
-
* simple html dom node
|
186 |
-
* PaperG - added ability for "find" routine to lowercase the value of the
|
187 |
-
* selector.
|
188 |
-
*
|
189 |
-
* PaperG - added $tag_start to track the start position of the tag in the total
|
190 |
-
* byte index
|
191 |
-
*
|
192 |
-
* @package PlaceLocalInclude
|
193 |
-
*/
|
194 |
class simple_html_dom_node
|
195 |
{
|
196 |
-
/**
|
197 |
-
* Node type
|
198 |
-
*
|
199 |
-
* Default is {@see HDOM_TYPE_TEXT}
|
200 |
-
*
|
201 |
-
* @var int
|
202 |
-
*/
|
203 |
public $nodetype = HDOM_TYPE_TEXT;
|
204 |
-
|
205 |
-
/**
|
206 |
-
* Tag name
|
207 |
-
*
|
208 |
-
* Default is 'text'
|
209 |
-
*
|
210 |
-
* @var string
|
211 |
-
*/
|
212 |
public $tag = 'text';
|
213 |
-
|
214 |
-
/**
|
215 |
-
* List of attributes
|
216 |
-
*
|
217 |
-
* @var array
|
218 |
-
*/
|
219 |
public $attr = array();
|
220 |
-
|
221 |
-
/**
|
222 |
-
* List of child node objects
|
223 |
-
*
|
224 |
-
* @var array
|
225 |
-
*/
|
226 |
public $children = array();
|
227 |
public $nodes = array();
|
228 |
-
|
229 |
-
/**
|
230 |
-
* The parent node object
|
231 |
-
*
|
232 |
-
* @var object|null
|
233 |
-
*/
|
234 |
public $parent = null;
|
235 |
-
|
236 |
-
// The "info" array - see HDOM_INFO_... for what each element contains.
|
237 |
public $_ = array();
|
238 |
-
|
239 |
-
/**
|
240 |
-
* Start position of the tag in the document
|
241 |
-
*
|
242 |
-
* @var int
|
243 |
-
*/
|
244 |
public $tag_start = 0;
|
245 |
-
|
246 |
-
/**
|
247 |
-
* The DOM object
|
248 |
-
*
|
249 |
-
* @var object|null
|
250 |
-
*/
|
251 |
private $dom = null;
|
252 |
|
253 |
-
/**
|
254 |
-
* Construct new node object
|
255 |
-
*
|
256 |
-
* Adds itself to the list of DOM Nodes {@see simple_html_dom::$nodes}
|
257 |
-
*/
|
258 |
function __construct($dom)
|
259 |
{
|
260 |
$this->dom = $dom;
|
@@ -271,7 +153,6 @@ class simple_html_dom_node
|
|
271 |
return $this->outertext();
|
272 |
}
|
273 |
|
274 |
-
// clean up memory due to php5 circular references memory leak...
|
275 |
function clear()
|
276 |
{
|
277 |
$this->dom = null;
|
@@ -280,17 +161,14 @@ class simple_html_dom_node
|
|
280 |
$this->children = null;
|
281 |
}
|
282 |
|
283 |
-
|
284 |
-
function dump($show_attr = true, $deep = 0)
|
285 |
{
|
286 |
-
|
287 |
-
|
288 |
-
echo $lead . $this->tag;
|
289 |
|
290 |
if ($show_attr && count($this->attr) > 0) {
|
291 |
echo '(';
|
292 |
foreach ($this->attr as $k => $v) {
|
293 |
-
echo "[$k]=>\"
|
294 |
}
|
295 |
echo ')';
|
296 |
}
|
@@ -298,14 +176,12 @@ class simple_html_dom_node
|
|
298 |
echo "\n";
|
299 |
|
300 |
if ($this->nodes) {
|
301 |
-
foreach ($this->nodes as $
|
302 |
-
$
|
303 |
}
|
304 |
}
|
305 |
}
|
306 |
|
307 |
-
|
308 |
-
// Debugging function to dump a single dom node with a bunch of information about it.
|
309 |
function dump_node($echo = true)
|
310 |
{
|
311 |
$string = $this->tag;
|
@@ -313,7 +189,7 @@ class simple_html_dom_node
|
|
313 |
if (count($this->attr) > 0) {
|
314 |
$string .= '(';
|
315 |
foreach ($this->attr as $k => $v) {
|
316 |
-
$string .= "[$k]=>\"
|
317 |
}
|
318 |
$string .= ')';
|
319 |
}
|
@@ -324,24 +200,24 @@ class simple_html_dom_node
|
|
324 |
if (is_array($v)) {
|
325 |
$string .= "[$k]=>(";
|
326 |
foreach ($v as $k2 => $v2) {
|
327 |
-
$string .= "[$k2]=>\"
|
328 |
}
|
329 |
$string .= ')';
|
330 |
} else {
|
331 |
-
$string .= "[$k]=>\"
|
332 |
}
|
333 |
}
|
334 |
$string .= ')';
|
335 |
}
|
336 |
|
337 |
if (isset($this->text)) {
|
338 |
-
$string .=
|
339 |
}
|
340 |
|
341 |
-
$string .=
|
342 |
|
343 |
if (isset($node->_[HDOM_INFO_INNER])) {
|
344 |
-
$string .= $node->_[HDOM_INFO_INNER] . "'";
|
345 |
} else {
|
346 |
$string .= ' NULL ';
|
347 |
}
|
@@ -359,13 +235,6 @@ class simple_html_dom_node
|
|
359 |
}
|
360 |
}
|
361 |
|
362 |
-
/**
|
363 |
-
* Return or set parent node
|
364 |
-
*
|
365 |
-
* @param object|null $parent (optional) The parent node, `null` to return
|
366 |
-
* the current parent node.
|
367 |
-
* @return object|null The parent node
|
368 |
-
*/
|
369 |
function parent($parent = null)
|
370 |
{
|
371 |
// I am SURE that this doesn't work properly.
|
@@ -380,22 +249,11 @@ class simple_html_dom_node
|
|
380 |
return $this->parent;
|
381 |
}
|
382 |
|
383 |
-
/**
|
384 |
-
* @return bool True if the node has at least one child node
|
385 |
-
*/
|
386 |
function has_child()
|
387 |
{
|
388 |
return !empty($this->children);
|
389 |
}
|
390 |
|
391 |
-
/**
|
392 |
-
* Get child node at specified index
|
393 |
-
*
|
394 |
-
* @param int $idx The index of the child node to return, `-1` to return all
|
395 |
-
* child nodes.
|
396 |
-
* @return object|array|null The child node at the specified index, all child
|
397 |
-
* nodes or null if the index is invalid.
|
398 |
-
*/
|
399 |
function children($idx = -1)
|
400 |
{
|
401 |
if ($idx === -1) {
|
@@ -409,15 +267,6 @@ class simple_html_dom_node
|
|
409 |
return null;
|
410 |
}
|
411 |
|
412 |
-
/**
|
413 |
-
* Get first child node
|
414 |
-
*
|
415 |
-
* @return object|null The first child node or null if the current node has
|
416 |
-
* no child nodes.
|
417 |
-
*
|
418 |
-
* @todo Use `empty()` instead of `count()` to improve performance on large
|
419 |
-
* arrays.
|
420 |
-
*/
|
421 |
function first_child()
|
422 |
{
|
423 |
if (count($this->children) > 0) {
|
@@ -426,108 +275,70 @@ class simple_html_dom_node
|
|
426 |
return null;
|
427 |
}
|
428 |
|
429 |
-
/**
|
430 |
-
* Get last child node
|
431 |
-
*
|
432 |
-
* @return object|null The last child node or null if the current node has
|
433 |
-
* no child nodes.
|
434 |
-
*
|
435 |
-
* @todo Use `end()` to slightly improve performance on large arrays.
|
436 |
-
*/
|
437 |
function last_child()
|
438 |
{
|
439 |
-
if (
|
440 |
-
return $this->children
|
441 |
}
|
442 |
return null;
|
443 |
}
|
444 |
|
445 |
-
/**
|
446 |
-
* Get next sibling node
|
447 |
-
*
|
448 |
-
* @return object|null The sibling node or null if the current node has no
|
449 |
-
* sibling nodes.
|
450 |
-
*/
|
451 |
function next_sibling()
|
452 |
{
|
453 |
if ($this->parent === null) {
|
454 |
return null;
|
455 |
}
|
456 |
|
457 |
-
$idx =
|
458 |
-
$count = count($this->parent->children);
|
459 |
|
460 |
-
|
461 |
-
|
462 |
}
|
463 |
|
464 |
-
|
465 |
-
return null;
|
466 |
-
}
|
467 |
-
|
468 |
-
return $this->parent->children[$idx];
|
469 |
}
|
470 |
|
471 |
-
/**
|
472 |
-
* Get previous sibling node
|
473 |
-
*
|
474 |
-
* @return object|null The sibling node or null if the current node has no
|
475 |
-
* sibling nodes.
|
476 |
-
*/
|
477 |
function prev_sibling()
|
478 |
{
|
479 |
-
if ($this->parent === null) {
|
|
|
|
|
480 |
|
481 |
-
$idx =
|
482 |
-
$count = count($this->parent->children);
|
483 |
|
484 |
-
|
485 |
-
|
486 |
}
|
487 |
|
488 |
-
|
489 |
-
|
490 |
-
return $this->parent->children[$idx];
|
491 |
}
|
492 |
|
493 |
-
/**
|
494 |
-
* Traverse ancestors to the first matching tag.
|
495 |
-
*
|
496 |
-
* @param string $tag Tag to find
|
497 |
-
* @return object|null First matching node in the DOM tree or null if no
|
498 |
-
* match was found.
|
499 |
-
*
|
500 |
-
* @todo Null is returned implicitly by calling ->parent on the root node.
|
501 |
-
* This behaviour could change at any time, rendering this function invalid.
|
502 |
-
*/
|
503 |
function find_ancestor_tag($tag)
|
504 |
{
|
505 |
global $debug_object;
|
506 |
if (is_object($debug_object)) { $debug_object->debug_log_entry(1); }
|
507 |
|
508 |
-
|
509 |
-
|
|
|
510 |
|
511 |
-
|
|
|
|
|
512 |
if (is_object($debug_object)) {
|
513 |
-
$debug_object->debug_log(2, 'Current tag is: ' . $
|
514 |
}
|
515 |
|
516 |
-
if ($
|
517 |
break;
|
518 |
}
|
519 |
|
520 |
-
$
|
521 |
}
|
522 |
|
523 |
-
return $
|
524 |
}
|
525 |
|
526 |
-
/**
|
527 |
-
* Get node's inner text (everything inside the opening and closing tags)
|
528 |
-
*
|
529 |
-
* @return string
|
530 |
-
*/
|
531 |
function innertext()
|
532 |
{
|
533 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
@@ -547,11 +358,6 @@ class simple_html_dom_node
|
|
547 |
return $ret;
|
548 |
}
|
549 |
|
550 |
-
/**
|
551 |
-
* Get node's outer text (everything including the opening and closing tags)
|
552 |
-
*
|
553 |
-
* @return string
|
554 |
-
*/
|
555 |
function outertext()
|
556 |
{
|
557 |
global $debug_object;
|
@@ -568,9 +374,11 @@ class simple_html_dom_node
|
|
568 |
$debug_object->debug_log(1, 'Innertext of tag: ' . $this->tag . $text);
|
569 |
}
|
570 |
|
571 |
-
if ($this->tag === 'root')
|
|
|
|
|
572 |
|
573 |
-
//
|
574 |
if ($this->dom && $this->dom->callback !== null) {
|
575 |
call_user_func_array($this->dom->callback, array($this));
|
576 |
}
|
@@ -583,29 +391,23 @@ class simple_html_dom_node
|
|
583 |
return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
|
584 |
}
|
585 |
|
586 |
-
|
|
|
587 |
if ($this->dom && $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]) {
|
588 |
$ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup();
|
589 |
-
} else {
|
590 |
-
$ret = '';
|
591 |
}
|
592 |
|
593 |
-
// render inner text
|
594 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
595 |
-
//
|
596 |
-
// may or may not have added.
|
597 |
if ($this->tag !== 'br') {
|
598 |
$ret .= $this->_[HDOM_INFO_INNER];
|
599 |
}
|
600 |
-
}
|
601 |
-
|
602 |
-
|
603 |
-
$ret .= $this->convert_text($n->outertext());
|
604 |
-
}
|
605 |
}
|
606 |
}
|
607 |
|
608 |
-
// render end tag
|
609 |
if (isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END] != 0) {
|
610 |
$ret .= '</' . $this->tag . '>';
|
611 |
}
|
@@ -613,11 +415,6 @@ class simple_html_dom_node
|
|
613 |
return $ret;
|
614 |
}
|
615 |
|
616 |
-
/**
|
617 |
-
* Get node's plain text (everything excluding all tags)
|
618 |
-
*
|
619 |
-
* @return string
|
620 |
-
*/
|
621 |
function text()
|
622 |
{
|
623 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
@@ -644,7 +441,7 @@ class simple_html_dom_node
|
|
644 |
foreach ($this->nodes as $n) {
|
645 |
// Start paragraph after a blank line
|
646 |
if ($n->tag === 'p') {
|
647 |
-
$ret
|
648 |
}
|
649 |
|
650 |
$ret .= $this->convert_text($n->text());
|
@@ -657,14 +454,9 @@ class simple_html_dom_node
|
|
657 |
}
|
658 |
}
|
659 |
}
|
660 |
-
return
|
661 |
}
|
662 |
|
663 |
-
/**
|
664 |
-
* Get node's xml text (inner text as a CDATA section)
|
665 |
-
*
|
666 |
-
* @return string
|
667 |
-
*/
|
668 |
function xmltext()
|
669 |
{
|
670 |
$ret = $this->innertext();
|
@@ -673,7 +465,6 @@ class simple_html_dom_node
|
|
673 |
return $ret;
|
674 |
}
|
675 |
|
676 |
-
// build node's text with tag
|
677 |
function makeup()
|
678 |
{
|
679 |
// text, comment, unknown
|
@@ -717,18 +508,6 @@ class simple_html_dom_node
|
|
717 |
return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>';
|
718 |
}
|
719 |
|
720 |
-
/**
|
721 |
-
* Find elements by CSS selector
|
722 |
-
*
|
723 |
-
* @param string $selector The CSS selector
|
724 |
-
* @param int|null $idx Index of element to return form the list of matching
|
725 |
-
* elements (default: `null` = disabled).
|
726 |
-
* @param bool $lowercase Matches tag names case insensitive (lowercase) if
|
727 |
-
* enabled (default: `false`)
|
728 |
-
* @return array|object|null A list of elements matching the specified CSS
|
729 |
-
* selector or a single element if $idx is specified or null if no element
|
730 |
-
* was found.
|
731 |
-
*/
|
732 |
function find($selector, $idx = null, $lowercase = false)
|
733 |
{
|
734 |
$selectors = $this->parse_selector($selector);
|
@@ -781,19 +560,6 @@ class simple_html_dom_node
|
|
781 |
return (isset($found[$idx])) ? $found[$idx] : null;
|
782 |
}
|
783 |
|
784 |
-
/**
|
785 |
-
* Seek DOM elements by selector
|
786 |
-
*
|
787 |
-
* **Note**
|
788 |
-
* The selector element must be compatible to a selector from
|
789 |
-
* {@see simple_html_dom_node::parse_selector()}
|
790 |
-
*
|
791 |
-
* @param array $selector A selector element
|
792 |
-
* @param array $ret An array of matches
|
793 |
-
* @param bool $lowercase Matches tag names case insensitive (lowercase) if
|
794 |
-
* enabled (default: `false`)
|
795 |
-
* @return void
|
796 |
-
*/
|
797 |
protected function seek($selector, &$ret, $parent_cmd, $lowercase = false)
|
798 |
{
|
799 |
global $debug_object;
|
@@ -825,7 +591,8 @@ class simple_html_dom_node
|
|
825 |
&& $this->parent
|
826 |
&& in_array($this, $this->parent->children)) { // Next-Sibling Combinator
|
827 |
$index = array_search($this, $this->parent->children, true) + 1;
|
828 |
-
$
|
|
|
829 |
} elseif ($parent_cmd === '~'
|
830 |
&& $this->parent
|
831 |
&& in_array($this, $this->parent->children)) { // Subsequent Sibling Combinator
|
@@ -1008,24 +775,6 @@ class simple_html_dom_node
|
|
1008 |
}
|
1009 |
}
|
1010 |
|
1011 |
-
/**
|
1012 |
-
* Match value and pattern for a given CSS expression
|
1013 |
-
*
|
1014 |
-
* **Supported Expressions**
|
1015 |
-
*
|
1016 |
-
* | Expression | Description
|
1017 |
-
* | ---------- | -----------
|
1018 |
-
* | `=` | $value and $pattern must be equal
|
1019 |
-
* | `!=` | $value and $pattern must not be equal
|
1020 |
-
* | `^=` | $value must start with $pattern
|
1021 |
-
* | `$=` | $value must end with $pattern
|
1022 |
-
* | `*=` | $value must contain $pattern
|
1023 |
-
*
|
1024 |
-
* @param string $exp The expression.
|
1025 |
-
* @param string $pattern The pattern
|
1026 |
-
* @param string $value The value
|
1027 |
-
* @value bool True if $value matches $pattern
|
1028 |
-
*/
|
1029 |
protected function match($exp, $pattern, $value, $case_sensitivity)
|
1030 |
{
|
1031 |
global $debug_object;
|
@@ -1071,31 +820,6 @@ class simple_html_dom_node
|
|
1071 |
return false;
|
1072 |
}
|
1073 |
|
1074 |
-
/**
|
1075 |
-
* Parse CSS selector
|
1076 |
-
*
|
1077 |
-
* @param string $selector_string CSS selector string
|
1078 |
-
* @return array List of CSS selectors. The format depends on the type of
|
1079 |
-
* selector:
|
1080 |
-
*
|
1081 |
-
* ```php
|
1082 |
-
*
|
1083 |
-
* array( // list of selectors (each separated by a comma), i.e. 'img, p, div'
|
1084 |
-
* array( // list of combinator selectors, i.e. 'img > p > div'
|
1085 |
-
* array( // selector element
|
1086 |
-
* [0], // (string) The element tag
|
1087 |
-
* [1], // (string) The element id
|
1088 |
-
* [2], // (array<string>) The element classes
|
1089 |
-
* [3], // (array<array<string>>) The list of attributes, each
|
1090 |
-
* // with four elements: name, expression, value, inverted
|
1091 |
-
* [4] // (string) The selector combinator (' ' | '>' | '+' | '~')
|
1092 |
-
* )
|
1093 |
-
* )
|
1094 |
-
* )
|
1095 |
-
* ```
|
1096 |
-
*
|
1097 |
-
* @link https://www.w3.org/TR/selectors/#compound Compound selector
|
1098 |
-
*/
|
1099 |
protected function parse_selector($selector_string)
|
1100 |
{
|
1101 |
global $debug_object;
|
@@ -1187,7 +911,7 @@ class simple_html_dom_node
|
|
1187 |
*/
|
1188 |
if($m[4] !== '') {
|
1189 |
preg_match_all(
|
1190 |
-
"/\[@?(!?[\w:-]+)(?:([!*^$|~]?=)[\"']?(.*?)[\"']?)?(?:\s
|
1191 |
trim($m[4]),
|
1192 |
$attributes,
|
1193 |
PREG_SET_ORDER
|
@@ -1287,8 +1011,6 @@ class simple_html_dom_node
|
|
1287 |
if (isset($this->attr[$name])) { unset($this->attr[$name]); }
|
1288 |
}
|
1289 |
|
1290 |
-
// PaperG - Function to convert the text from one character set to another
|
1291 |
-
// if the two sets are not the same.
|
1292 |
function convert_text($text)
|
1293 |
{
|
1294 |
global $debug_object;
|
@@ -1339,12 +1061,6 @@ class simple_html_dom_node
|
|
1339 |
return $converted_text;
|
1340 |
}
|
1341 |
|
1342 |
-
/**
|
1343 |
-
* Returns true if $string is valid UTF-8 and false otherwise.
|
1344 |
-
*
|
1345 |
-
* @param mixed $str String to be tested
|
1346 |
-
* @return boolean
|
1347 |
-
*/
|
1348 |
static function is_utf8($str)
|
1349 |
{
|
1350 |
$c = 0; $b = 0;
|
@@ -1372,16 +1088,6 @@ class simple_html_dom_node
|
|
1372 |
return true;
|
1373 |
}
|
1374 |
|
1375 |
-
/**
|
1376 |
-
* Function to try a few tricks to determine the displayed size of an img on
|
1377 |
-
* the page. NOTE: This will ONLY work on an IMG tag. Returns FALSE on all
|
1378 |
-
* other tag types.
|
1379 |
-
*
|
1380 |
-
* @author John Schlick
|
1381 |
-
* @version April 19 2012
|
1382 |
-
* @return array an array containing the 'height' and 'width' of the image
|
1383 |
-
* on the page or -1 if we can't figure it out.
|
1384 |
-
*/
|
1385 |
function get_display_size()
|
1386 |
{
|
1387 |
global $debug_object;
|
@@ -1467,7 +1173,82 @@ class simple_html_dom_node
|
|
1467 |
return $result;
|
1468 |
}
|
1469 |
|
1470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1471 |
function getAllAttributes()
|
1472 |
{
|
1473 |
return $this->attr;
|
@@ -1493,6 +1274,44 @@ class simple_html_dom_node
|
|
1493 |
$this->__set($name, null);
|
1494 |
}
|
1495 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1496 |
function getElementById($id)
|
1497 |
{
|
1498 |
return $this->find("#$id", 0);
|
@@ -1561,170 +1380,34 @@ class simple_html_dom_node
|
|
1561 |
|
1562 |
}
|
1563 |
|
1564 |
-
/**
|
1565 |
-
* simple html dom parser
|
1566 |
-
*
|
1567 |
-
* Paperg - in the find routine: allow us to specify that we want case
|
1568 |
-
* insensitive testing of the value of the selector.
|
1569 |
-
*
|
1570 |
-
* Paperg - change $size from protected to public so we can easily access it
|
1571 |
-
*
|
1572 |
-
* Paperg - added ForceTagsClosed in the constructor which tells us whether we
|
1573 |
-
* trust the html or not. Default is to NOT trust it.
|
1574 |
-
*
|
1575 |
-
* @package PlaceLocalInclude
|
1576 |
-
*/
|
1577 |
class simple_html_dom
|
1578 |
{
|
1579 |
-
/**
|
1580 |
-
* The root node of the document
|
1581 |
-
*
|
1582 |
-
* @var object
|
1583 |
-
*/
|
1584 |
public $root = null;
|
1585 |
-
|
1586 |
-
/**
|
1587 |
-
* List of nodes in the current DOM
|
1588 |
-
*
|
1589 |
-
* @var array
|
1590 |
-
*/
|
1591 |
public $nodes = array();
|
1592 |
-
|
1593 |
-
/**
|
1594 |
-
* Callback function to run for each element in the DOM.
|
1595 |
-
*
|
1596 |
-
* @var callable|null
|
1597 |
-
*/
|
1598 |
public $callback = null;
|
1599 |
-
|
1600 |
-
/**
|
1601 |
-
* Indicates how tags and attributes are matched
|
1602 |
-
*
|
1603 |
-
* @var bool When set to **true** tags and attributes will be converted to
|
1604 |
-
* lowercase before matching.
|
1605 |
-
*/
|
1606 |
public $lowercase = false;
|
1607 |
-
|
1608 |
-
/**
|
1609 |
-
* Original document size
|
1610 |
-
*
|
1611 |
-
* Holds the original document size.
|
1612 |
-
*
|
1613 |
-
* @var int
|
1614 |
-
*/
|
1615 |
public $original_size;
|
1616 |
-
|
1617 |
-
/**
|
1618 |
-
* Current document size
|
1619 |
-
*
|
1620 |
-
* Holds the current document size. The document size is determined by the
|
1621 |
-
* string length of ({@see simple_html_dom::$doc}).
|
1622 |
-
*
|
1623 |
-
* _Note_: Using this variable is more efficient than calling `strlen($doc)`
|
1624 |
-
*
|
1625 |
-
* @var int
|
1626 |
-
* */
|
1627 |
public $size;
|
1628 |
|
1629 |
-
/**
|
1630 |
-
* Current position in the document
|
1631 |
-
*
|
1632 |
-
* @var int
|
1633 |
-
*/
|
1634 |
protected $pos;
|
1635 |
-
|
1636 |
-
/**
|
1637 |
-
* The document
|
1638 |
-
*
|
1639 |
-
* @var string
|
1640 |
-
*/
|
1641 |
protected $doc;
|
1642 |
-
|
1643 |
-
/**
|
1644 |
-
* Current character
|
1645 |
-
*
|
1646 |
-
* Holds the current character at position {@see simple_html_dom::$pos} in
|
1647 |
-
* the document {@see simple_html_dom::$doc}
|
1648 |
-
*
|
1649 |
-
* _Note_: Using this variable is more efficient than calling
|
1650 |
-
* `substr($doc, $pos, 1)`
|
1651 |
-
*
|
1652 |
-
* @var string
|
1653 |
-
*/
|
1654 |
protected $char;
|
1655 |
|
1656 |
protected $cursor;
|
1657 |
-
|
1658 |
-
/**
|
1659 |
-
* Parent node of the next node detected by the parser
|
1660 |
-
*
|
1661 |
-
* @var object
|
1662 |
-
*/
|
1663 |
protected $parent;
|
1664 |
protected $noise = array();
|
1665 |
-
|
1666 |
-
/**
|
1667 |
-
* Tokens considered blank in HTML
|
1668 |
-
*
|
1669 |
-
* @var string
|
1670 |
-
*/
|
1671 |
protected $token_blank = " \t\r\n";
|
1672 |
-
|
1673 |
-
/**
|
1674 |
-
* Tokens to identify the equal sign for attributes, stopping either at the
|
1675 |
-
* closing tag ("/" i.e. "<html />") or the end of an opening tag (">" i.e.
|
1676 |
-
* "<html>")
|
1677 |
-
*
|
1678 |
-
* @var string
|
1679 |
-
*/
|
1680 |
protected $token_equal = ' =/>';
|
1681 |
-
|
1682 |
-
/**
|
1683 |
-
* Tokens to identify the end of a tag name. A tag name either ends on the
|
1684 |
-
* ending slash ("/" i.e. "<html/>") or whitespace ("\s\r\n\t")
|
1685 |
-
*
|
1686 |
-
* @var string
|
1687 |
-
*/
|
1688 |
protected $token_slash = " />\r\n\t";
|
1689 |
-
|
1690 |
-
/**
|
1691 |
-
* Tokens to identify the end of an attribute
|
1692 |
-
*
|
1693 |
-
* @var string
|
1694 |
-
*/
|
1695 |
protected $token_attr = ' >';
|
1696 |
|
1697 |
-
// Note that this is referenced by a child node, and so it needs to be
|
1698 |
-
// public for that node to see this information.
|
1699 |
public $_charset = '';
|
1700 |
public $_target_charset = '';
|
1701 |
|
1702 |
-
/**
|
1703 |
-
* Innertext for <br> elements
|
1704 |
-
*
|
1705 |
-
* @var string
|
1706 |
-
*/
|
1707 |
protected $default_br_text = '';
|
1708 |
|
1709 |
-
/**
|
1710 |
-
* Suffix for <span> elements
|
1711 |
-
*
|
1712 |
-
* @var string
|
1713 |
-
*/
|
1714 |
public $default_span_text = '';
|
1715 |
|
1716 |
-
/**
|
1717 |
-
* Defines a list of self-closing tags (Void elements) according to the HTML
|
1718 |
-
* Specification
|
1719 |
-
*
|
1720 |
-
* _Remarks_:
|
1721 |
-
* - Use `isset()` instead of `in_array()` on array elements to boost
|
1722 |
-
* performance about 30%
|
1723 |
-
* - Sort elements by name for better readability!
|
1724 |
-
*
|
1725 |
-
* @link https://www.w3.org/TR/html HTML Specification
|
1726 |
-
* @link https://www.w3.org/TR/html/syntax.html#void-elements Void elements
|
1727 |
-
*/
|
1728 |
protected $self_closing_tags = array(
|
1729 |
'area' => 1,
|
1730 |
'base' => 1,
|
@@ -1741,18 +1424,6 @@ class simple_html_dom
|
|
1741 |
'track' => 1,
|
1742 |
'wbr' => 1
|
1743 |
);
|
1744 |
-
|
1745 |
-
/**
|
1746 |
-
* Defines a list of tags which - if closed - close all optional closing
|
1747 |
-
* elements within if they haven't been closed yet. (So, an element where
|
1748 |
-
* neither opening nor closing tag is omissible consistently closes every
|
1749 |
-
* optional closing element within)
|
1750 |
-
*
|
1751 |
-
* _Remarks_:
|
1752 |
-
* - Use `isset()` instead of `in_array()` on array elements to boost
|
1753 |
-
* performance about 30%
|
1754 |
-
* - Sort elements by name for better readability!
|
1755 |
-
*/
|
1756 |
protected $block_tags = array(
|
1757 |
'body' => 1,
|
1758 |
'div' => 1,
|
@@ -1761,62 +1432,6 @@ class simple_html_dom
|
|
1761 |
'span' => 1,
|
1762 |
'table' => 1
|
1763 |
);
|
1764 |
-
|
1765 |
-
/**
|
1766 |
-
* Defines elements whose end tag is omissible.
|
1767 |
-
*
|
1768 |
-
* * key = Name of an element whose end tag is omissible.
|
1769 |
-
* * value = Names of elements whose end tag is omissible, that are closed
|
1770 |
-
* by the current element.
|
1771 |
-
*
|
1772 |
-
* _Remarks_:
|
1773 |
-
* - Use `isset()` instead of `in_array()` on array elements to boost
|
1774 |
-
* performance about 30%
|
1775 |
-
* - Sort elements by name for better readability!
|
1776 |
-
*
|
1777 |
-
* **Example**
|
1778 |
-
*
|
1779 |
-
* An `li` element’s end tag may be omitted if the `li` element is immediately
|
1780 |
-
* followed by another `li` element. To do that, add following element to the
|
1781 |
-
* array:
|
1782 |
-
*
|
1783 |
-
* ```php
|
1784 |
-
* 'li' => array('li'),
|
1785 |
-
* ```
|
1786 |
-
*
|
1787 |
-
* With this, the following two examples are considered equal. Note that the
|
1788 |
-
* second example is missing the closing tags on `li` elements.
|
1789 |
-
*
|
1790 |
-
* ```html
|
1791 |
-
* <ul><li>First Item</li><li>Second Item</li></ul>
|
1792 |
-
* ```
|
1793 |
-
*
|
1794 |
-
* <ul><li>First Item</li><li>Second Item</li></ul>
|
1795 |
-
*
|
1796 |
-
* ```html
|
1797 |
-
* <ul><li>First Item<li>Second Item</ul>
|
1798 |
-
* ```
|
1799 |
-
*
|
1800 |
-
* <ul><li>First Item<li>Second Item</ul>
|
1801 |
-
*
|
1802 |
-
* @var array A two-dimensional array where the key is the name of an
|
1803 |
-
* element whose end tag is omissible and the value is an array of elements
|
1804 |
-
* whose end tag is omissible, that are closed by the current element.
|
1805 |
-
*
|
1806 |
-
* @link https://www.w3.org/TR/html/syntax.html#optional-tags Optional tags
|
1807 |
-
*
|
1808 |
-
* @todo The implementation of optional closing tags doesn't work in all cases
|
1809 |
-
* because it only consideres elements who close other optional closing
|
1810 |
-
* tags, not taking into account that some (non-blocking) tags should close
|
1811 |
-
* these optional closing tags. For example, the end tag for "p" is omissible
|
1812 |
-
* and can be closed by an "address" element, whose end tag is NOT omissible.
|
1813 |
-
* Currently a "p" element without closing tag stops at the next "p" element
|
1814 |
-
* or blocking tag, even if it contains other elements.
|
1815 |
-
*
|
1816 |
-
* @todo Known sourceforge issue #2977341
|
1817 |
-
* B tags that are not closed cause us to return everything to the end of
|
1818 |
-
* the document.
|
1819 |
-
*/
|
1820 |
protected $optional_closing_tags = array(
|
1821 |
// Not optional, see
|
1822 |
// https://www.w3.org/TR/html/textlevel-semantics.html#the-b-element
|
@@ -1875,7 +1490,6 @@ class simple_html_dom
|
|
1875 |
$this->clear();
|
1876 |
}
|
1877 |
|
1878 |
-
// load html from string
|
1879 |
function load(
|
1880 |
$str,
|
1881 |
$lowercase = true,
|
@@ -1930,7 +1544,6 @@ class simple_html_dom
|
|
1930 |
return $this;
|
1931 |
}
|
1932 |
|
1933 |
-
// load html from file
|
1934 |
function load_file()
|
1935 |
{
|
1936 |
$args = func_get_args();
|
@@ -1942,29 +1555,16 @@ class simple_html_dom
|
|
1942 |
}
|
1943 |
}
|
1944 |
|
1945 |
-
/**
|
1946 |
-
* Set the callback function
|
1947 |
-
*
|
1948 |
-
* @param callable $function_name Callback function to run for each element
|
1949 |
-
* in the DOM.
|
1950 |
-
* @return void
|
1951 |
-
*/
|
1952 |
function set_callback($function_name)
|
1953 |
{
|
1954 |
$this->callback = $function_name;
|
1955 |
}
|
1956 |
|
1957 |
-
/**
|
1958 |
-
* Remove callback function
|
1959 |
-
*
|
1960 |
-
* @return void
|
1961 |
-
*/
|
1962 |
function remove_callback()
|
1963 |
{
|
1964 |
$this->callback = null;
|
1965 |
}
|
1966 |
|
1967 |
-
// save dom as string
|
1968 |
function save($filepath = '')
|
1969 |
{
|
1970 |
$ret = $this->root->innertext();
|
@@ -1972,18 +1572,18 @@ class simple_html_dom
|
|
1972 |
return $ret;
|
1973 |
}
|
1974 |
|
1975 |
-
// find dom node by css selector
|
1976 |
-
// Paperg - allow us to specify that we want case insensitive testing of the value of the selector.
|
1977 |
function find($selector, $idx = null, $lowercase = false)
|
1978 |
{
|
1979 |
return $this->root->find($selector, $idx, $lowercase);
|
1980 |
}
|
1981 |
|
1982 |
-
// clean up memory due to php5 circular references memory leak...
|
1983 |
function clear()
|
1984 |
{
|
1985 |
-
|
1986 |
-
$
|
|
|
|
|
|
|
1987 |
}
|
1988 |
|
1989 |
// This add next line is documented in the sourceforge repository.
|
@@ -1991,7 +1591,8 @@ class simple_html_dom
|
|
1991 |
// use of clear.
|
1992 |
if (isset($this->children)) {
|
1993 |
foreach ($this->children as $n) {
|
1994 |
-
$n->clear();
|
|
|
1995 |
}
|
1996 |
}
|
1997 |
|
@@ -2014,7 +1615,6 @@ class simple_html_dom
|
|
2014 |
$this->root->dump($show_attr);
|
2015 |
}
|
2016 |
|
2017 |
-
// prepare HTML data and init everything
|
2018 |
protected function prepare(
|
2019 |
$str, $lowercase = true,
|
2020 |
$defaultBRText = DEFAULT_BR_TEXT,
|
@@ -2040,11 +1640,6 @@ class simple_html_dom
|
|
2040 |
if ($this->size > 0) { $this->char = $this->doc[0]; }
|
2041 |
}
|
2042 |
|
2043 |
-
/**
|
2044 |
-
* Parse HTML content
|
2045 |
-
*
|
2046 |
-
* @return bool True on success
|
2047 |
-
*/
|
2048 |
protected function parse()
|
2049 |
{
|
2050 |
while (true) {
|
@@ -2066,13 +1661,6 @@ class simple_html_dom
|
|
2066 |
}
|
2067 |
}
|
2068 |
|
2069 |
-
// PAPERG - dkchou - added this to try to identify the character set of the
|
2070 |
-
// page we have just parsed so we know better how to spit it out later.
|
2071 |
-
// NOTE: IF you provide a routine called
|
2072 |
-
// get_last_retrieve_url_contents_content_type which returns the
|
2073 |
-
// CURLINFO_CONTENT_TYPE from the last curl_exec
|
2074 |
-
// (or the content_type header from the last transfer), we will parse THAT,
|
2075 |
-
// and if a charset is specified, we will use it over any other mechanism.
|
2076 |
protected function parse_charset()
|
2077 |
{
|
2078 |
global $debug_object;
|
@@ -2094,6 +1682,7 @@ class simple_html_dom
|
|
2094 |
}
|
2095 |
|
2096 |
if (empty($charset)) {
|
|
|
2097 |
$el = $this->root->find('meta[http-equiv=Content-Type]', 0, true);
|
2098 |
|
2099 |
if (!empty($el)) {
|
@@ -2130,53 +1719,77 @@ class simple_html_dom
|
|
2130 |
}
|
2131 |
}
|
2132 |
|
2133 |
-
// If we couldn't find a charset above, then lets try to detect one
|
2134 |
-
// based on the text we got...
|
2135 |
if (empty($charset)) {
|
2136 |
-
//
|
2137 |
-
|
2138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2139 |
if (function_exists('mb_detect_encoding')) {
|
2140 |
-
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2144 |
);
|
2145 |
|
2146 |
-
if (
|
2147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2148 |
}
|
2149 |
-
}
|
2150 |
|
2151 |
-
|
2152 |
-
|
2153 |
-
|
2154 |
-
|
2155 |
-
|
2156 |
-
$debug_object->debug_log(
|
2157 |
-
2,
|
2158 |
-
'since mb_detect failed - using default of utf-8'
|
2159 |
-
);
|
2160 |
}
|
|
|
|
|
2161 |
|
2162 |
-
|
|
|
|
|
|
|
|
|
2163 |
}
|
2164 |
}
|
2165 |
|
2166 |
// Since CP1252 is a superset, if we get one of it's subsets, we want
|
2167 |
// it instead.
|
2168 |
-
if ((strtolower($charset) ==
|
2169 |
-
|| (strtolower($charset) ==
|
2170 |
-
|| (strtolower($charset) ==
|
2171 |
-
|
2172 |
if (is_object($debug_object)) {
|
2173 |
-
$debug_object->debug_log(
|
2174 |
-
2,
|
2175 |
'replacing ' . $charset . ' with CP1252 as its a superset'
|
2176 |
);
|
2177 |
}
|
2178 |
-
|
2179 |
-
$charset = 'CP1252';
|
2180 |
}
|
2181 |
|
2182 |
if (is_object($debug_object)) {
|
@@ -2186,11 +1799,6 @@ class simple_html_dom
|
|
2186 |
return $this->_charset = $charset;
|
2187 |
}
|
2188 |
|
2189 |
-
/**
|
2190 |
-
* Parse tag from current document position.
|
2191 |
-
*
|
2192 |
-
* @return bool True if a tag was found, false otherwise
|
2193 |
-
*/
|
2194 |
protected function read_tag()
|
2195 |
{
|
2196 |
// Set end position if no further tags found
|
@@ -2469,63 +2077,50 @@ class simple_html_dom
|
|
2469 |
return true;
|
2470 |
}
|
2471 |
|
2472 |
-
/**
|
2473 |
-
* Parse attribute from current document position
|
2474 |
-
*
|
2475 |
-
* @param object $node Node for the attributes
|
2476 |
-
* @param string $name Name of the current attribute
|
2477 |
-
* @param array $space Array for spacing information
|
2478 |
-
* @return void
|
2479 |
-
*/
|
2480 |
protected function parse_attr($node, $name, &$space)
|
2481 |
{
|
2482 |
-
|
2483 |
-
// If the attribute is already defined inside a tag, only pay attention
|
2484 |
-
// to the first one as opposed to the last one.
|
2485 |
-
// https://stackoverflow.com/a/26341866
|
2486 |
-
if (isset($node->attr[$name])) {
|
2487 |
-
return;
|
2488 |
-
}
|
2489 |
|
2490 |
-
//
|
2491 |
-
|
2492 |
|
2493 |
switch ($this->char) {
|
2494 |
-
case '"':
|
2495 |
-
$
|
2496 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2497 |
-
$
|
2498 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2499 |
break;
|
2500 |
-
case '\'':
|
2501 |
-
$
|
2502 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2503 |
-
$
|
2504 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2505 |
break;
|
2506 |
-
default:
|
2507 |
-
$
|
2508 |
-
$
|
2509 |
}
|
|
|
|
|
|
|
2510 |
// PaperG: Attributes should not have \r or \n in them, that counts as
|
2511 |
// html whitespace.
|
2512 |
-
$
|
2513 |
-
$
|
|
|
2514 |
// PaperG: If this is a "class" selector, lets get rid of the preceeding
|
2515 |
// and trailing space since some people leave it in the multi class case.
|
2516 |
if ($name === 'class') {
|
2517 |
-
$
|
|
|
|
|
|
|
|
|
|
|
2518 |
}
|
2519 |
}
|
2520 |
|
2521 |
-
/**
|
2522 |
-
* Link node to parent node
|
2523 |
-
*
|
2524 |
-
* @param object $node Node to link to parent
|
2525 |
-
* @param bool $is_child True if the node is a child of parent
|
2526 |
-
* @return void
|
2527 |
-
*/
|
2528 |
-
// link node's parent
|
2529 |
protected function link_nodes(&$node, $is_child)
|
2530 |
{
|
2531 |
$node->parent = $this->parent;
|
@@ -2535,12 +2130,6 @@ class simple_html_dom
|
|
2535 |
}
|
2536 |
}
|
2537 |
|
2538 |
-
/**
|
2539 |
-
* Add tag as text node to current node
|
2540 |
-
*
|
2541 |
-
* @param string $tag Tag name
|
2542 |
-
* @return bool True on success
|
2543 |
-
*/
|
2544 |
protected function as_text_node($tag)
|
2545 |
{
|
2546 |
$node = new simple_html_dom_node($this);
|
@@ -2551,28 +2140,12 @@ class simple_html_dom
|
|
2551 |
return true;
|
2552 |
}
|
2553 |
|
2554 |
-
/**
|
2555 |
-
* Seek from the current document position to the first occurrence of a
|
2556 |
-
* character not defined by the provided string. Update the current document
|
2557 |
-
* position to the new position.
|
2558 |
-
*
|
2559 |
-
* @param string $chars A string containing every allowed character.
|
2560 |
-
* @return void
|
2561 |
-
*/
|
2562 |
protected function skip($chars)
|
2563 |
{
|
2564 |
$this->pos += strspn($this->doc, $chars, $this->pos);
|
2565 |
$this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2566 |
}
|
2567 |
|
2568 |
-
/**
|
2569 |
-
* Copy substring from the current document position to the first occurrence
|
2570 |
-
* of a character not defined by the provided string.
|
2571 |
-
*
|
2572 |
-
* @param string $chars A string containing every allowed character.
|
2573 |
-
* @return string Substring from the current document position to the first
|
2574 |
-
* occurrence of a character not defined by the provided string.
|
2575 |
-
*/
|
2576 |
protected function copy_skip($chars)
|
2577 |
{
|
2578 |
$pos = $this->pos;
|
@@ -2583,14 +2156,6 @@ class simple_html_dom
|
|
2583 |
return substr($this->doc, $pos, $len);
|
2584 |
}
|
2585 |
|
2586 |
-
/**
|
2587 |
-
* Copy substring from the current document position to the first occurrence
|
2588 |
-
* of any of the provided characters.
|
2589 |
-
*
|
2590 |
-
* @param string $chars A string containing every character to stop at.
|
2591 |
-
* @return string Substring from the current document position to the first
|
2592 |
-
* occurrence of any of the provided characters.
|
2593 |
-
*/
|
2594 |
protected function copy_until($chars)
|
2595 |
{
|
2596 |
$pos = $this->pos;
|
@@ -2600,14 +2165,6 @@ class simple_html_dom
|
|
2600 |
return substr($this->doc, $pos, $len);
|
2601 |
}
|
2602 |
|
2603 |
-
/**
|
2604 |
-
* Copy substring from the current document position to the first occurrence
|
2605 |
-
* of the provided string.
|
2606 |
-
*
|
2607 |
-
* @param string $char The string to stop at.
|
2608 |
-
* @return string Substring from the current document position to the first
|
2609 |
-
* occurrence of the provided string.
|
2610 |
-
*/
|
2611 |
protected function copy_until_char($char)
|
2612 |
{
|
2613 |
if ($this->char === null) { return ''; }
|
@@ -2627,15 +2184,6 @@ class simple_html_dom
|
|
2627 |
return substr($this->doc, $pos_old, $pos - $pos_old);
|
2628 |
}
|
2629 |
|
2630 |
-
/**
|
2631 |
-
* Remove noise from HTML content
|
2632 |
-
*
|
2633 |
-
* Noise is stored to {@see simple_html_dom::$noise}
|
2634 |
-
*
|
2635 |
-
* @param string $pattern The regex pattern used for finding noise
|
2636 |
-
* @param bool $remove_tag True to remove the entire match. Default is false
|
2637 |
-
* to only remove the captured data.
|
2638 |
-
*/
|
2639 |
protected function remove_noise($pattern, $remove_tag = false)
|
2640 |
{
|
2641 |
global $debug_object;
|
@@ -2668,14 +2216,6 @@ class simple_html_dom
|
|
2668 |
}
|
2669 |
}
|
2670 |
|
2671 |
-
/**
|
2672 |
-
* Restore noise to HTML content
|
2673 |
-
*
|
2674 |
-
* Noise is restored from {@see simple_html_dom::$noise}
|
2675 |
-
*
|
2676 |
-
* @param string $text A subset of HTML containing noise
|
2677 |
-
* @return string The same content with noise restored
|
2678 |
-
*/
|
2679 |
function restore_noise($text)
|
2680 |
{
|
2681 |
global $debug_object;
|
@@ -2722,7 +2262,6 @@ class simple_html_dom
|
|
2722 |
return $text;
|
2723 |
}
|
2724 |
|
2725 |
-
// Sometimes we NEED one of the noise elements.
|
2726 |
function search_noise($text)
|
2727 |
{
|
2728 |
global $debug_object;
|
@@ -2756,7 +2295,6 @@ class simple_html_dom
|
|
2756 |
}
|
2757 |
}
|
2758 |
|
2759 |
-
// camel naming conventions
|
2760 |
function childNodes($idx = -1)
|
2761 |
{
|
2762 |
return $this->root->childNodes($idx);
|
@@ -2774,7 +2312,7 @@ class simple_html_dom
|
|
2774 |
|
2775 |
function createElement($name, $value = null)
|
2776 |
{
|
2777 |
-
return @str_get_html("<$name>$value</$name>")->
|
2778 |
}
|
2779 |
|
2780 |
function createTextNode($value)
|
5 |
* Website: http://sourceforge.net/projects/simplehtmldom/
|
6 |
* Additional projects: http://sourceforge.net/projects/debugobject/
|
7 |
* Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
|
|
|
|
|
|
|
|
|
8 |
*
|
9 |
+
* Licensed under The MIT License
|
10 |
+
* See the LICENSE file in the project root for more information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
*
|
12 |
+
* Authors:
|
13 |
+
* S.C. Chen
|
14 |
+
* John Schlick
|
15 |
+
* Rus Carroll
|
16 |
+
* logmanoriginal
|
17 |
*
|
18 |
+
* Contributors:
|
19 |
+
* Yousuke Kumakura
|
20 |
+
* Vadim Voituk
|
21 |
+
* Antcs
|
22 |
*
|
23 |
+
* Version Rev. 1.9 (290)
|
|
|
|
|
|
|
|
|
|
|
24 |
*/
|
25 |
|
|
|
|
|
|
|
|
|
26 |
define('HDOM_TYPE_ELEMENT', 1);
|
27 |
define('HDOM_TYPE_COMMENT', 2);
|
28 |
define('HDOM_TYPE_TEXT', 3);
|
41 |
define('HDOM_INFO_OUTER', 6);
|
42 |
define('HDOM_INFO_ENDSPACE', 7);
|
43 |
|
|
|
44 |
defined('DEFAULT_TARGET_CHARSET') || define('DEFAULT_TARGET_CHARSET', 'UTF-8');
|
|
|
|
|
45 |
defined('DEFAULT_BR_TEXT') || define('DEFAULT_BR_TEXT', "\r\n");
|
|
|
|
|
46 |
defined('DEFAULT_SPAN_TEXT') || define('DEFAULT_SPAN_TEXT', ' ');
|
|
|
|
|
47 |
defined('MAX_FILE_SIZE') || define('MAX_FILE_SIZE', 600000);
|
|
|
|
|
48 |
define('HDOM_SMARTY_AS_TEXT', 1);
|
49 |
|
|
|
|
|
|
|
|
|
50 |
function file_get_html(
|
51 |
$url,
|
52 |
$use_include_path = false,
|
60 |
$defaultBRText = DEFAULT_BR_TEXT,
|
61 |
$defaultSpanText = DEFAULT_SPAN_TEXT)
|
62 |
{
|
|
|
63 |
if($maxLen <= 0) { $maxLen = MAX_FILE_SIZE; }
|
64 |
|
|
|
65 |
$dom = new simple_html_dom(
|
66 |
null,
|
67 |
$lowercase,
|
69 |
$target_charset,
|
70 |
$stripRN,
|
71 |
$defaultBRText,
|
72 |
+
$defaultSpanText
|
73 |
+
);
|
74 |
|
75 |
/**
|
76 |
* For sourceforge users: uncomment the next line and comment the
|
81 |
$use_include_path,
|
82 |
$context,
|
83 |
$offset,
|
84 |
+
$maxLen
|
85 |
+
);
|
|
|
|
|
86 |
// $contents = retrieve_url_contents($url);
|
|
|
87 |
|
88 |
+
if (empty($contents) || strlen($contents) > $maxLen) {
|
89 |
+
$dom->clear();
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
|
93 |
+
return $dom->load($contents, $lowercase, $stripRN);
|
94 |
}
|
95 |
|
|
|
96 |
function str_get_html(
|
97 |
$str,
|
98 |
$lowercase = true,
|
109 |
$target_charset,
|
110 |
$stripRN,
|
111 |
$defaultBRText,
|
112 |
+
$defaultSpanText
|
113 |
+
);
|
114 |
|
115 |
if (empty($str) || strlen($str) > MAX_FILE_SIZE) {
|
116 |
$dom->clear();
|
117 |
return false;
|
118 |
}
|
119 |
|
120 |
+
return $dom->load($str, $lowercase, $stripRN);
|
|
|
121 |
}
|
122 |
|
|
|
123 |
function dump_html_tree($node, $show_attr = true, $deep = 0)
|
124 |
{
|
125 |
$node->dump($node);
|
126 |
}
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
class simple_html_dom_node
|
129 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
public $nodetype = HDOM_TYPE_TEXT;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
public $tag = 'text';
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
public $attr = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
public $children = array();
|
134 |
public $nodes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
public $parent = null;
|
|
|
|
|
136 |
public $_ = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
public $tag_start = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
private $dom = null;
|
139 |
|
|
|
|
|
|
|
|
|
|
|
140 |
function __construct($dom)
|
141 |
{
|
142 |
$this->dom = $dom;
|
153 |
return $this->outertext();
|
154 |
}
|
155 |
|
|
|
156 |
function clear()
|
157 |
{
|
158 |
$this->dom = null;
|
161 |
$this->children = null;
|
162 |
}
|
163 |
|
164 |
+
function dump($show_attr = true, $depth = 0)
|
|
|
165 |
{
|
166 |
+
echo str_repeat("\t", $depth) . $this->tag;
|
|
|
|
|
167 |
|
168 |
if ($show_attr && count($this->attr) > 0) {
|
169 |
echo '(';
|
170 |
foreach ($this->attr as $k => $v) {
|
171 |
+
echo "[$k]=>\"$v\", ";
|
172 |
}
|
173 |
echo ')';
|
174 |
}
|
176 |
echo "\n";
|
177 |
|
178 |
if ($this->nodes) {
|
179 |
+
foreach ($this->nodes as $node) {
|
180 |
+
$node->dump($show_attr, $depth + 1);
|
181 |
}
|
182 |
}
|
183 |
}
|
184 |
|
|
|
|
|
185 |
function dump_node($echo = true)
|
186 |
{
|
187 |
$string = $this->tag;
|
189 |
if (count($this->attr) > 0) {
|
190 |
$string .= '(';
|
191 |
foreach ($this->attr as $k => $v) {
|
192 |
+
$string .= "[$k]=>\"$v\", ";
|
193 |
}
|
194 |
$string .= ')';
|
195 |
}
|
200 |
if (is_array($v)) {
|
201 |
$string .= "[$k]=>(";
|
202 |
foreach ($v as $k2 => $v2) {
|
203 |
+
$string .= "[$k2]=>\"$v2\", ";
|
204 |
}
|
205 |
$string .= ')';
|
206 |
} else {
|
207 |
+
$string .= "[$k]=>\"$v\", ";
|
208 |
}
|
209 |
}
|
210 |
$string .= ')';
|
211 |
}
|
212 |
|
213 |
if (isset($this->text)) {
|
214 |
+
$string .= " text: ({$this->text})";
|
215 |
}
|
216 |
|
217 |
+
$string .= ' HDOM_INNER_INFO: ';
|
218 |
|
219 |
if (isset($node->_[HDOM_INFO_INNER])) {
|
220 |
+
$string .= "'" . $node->_[HDOM_INFO_INNER] . "'";
|
221 |
} else {
|
222 |
$string .= ' NULL ';
|
223 |
}
|
235 |
}
|
236 |
}
|
237 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
function parent($parent = null)
|
239 |
{
|
240 |
// I am SURE that this doesn't work properly.
|
249 |
return $this->parent;
|
250 |
}
|
251 |
|
|
|
|
|
|
|
252 |
function has_child()
|
253 |
{
|
254 |
return !empty($this->children);
|
255 |
}
|
256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
function children($idx = -1)
|
258 |
{
|
259 |
if ($idx === -1) {
|
267 |
return null;
|
268 |
}
|
269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
270 |
function first_child()
|
271 |
{
|
272 |
if (count($this->children) > 0) {
|
275 |
return null;
|
276 |
}
|
277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
function last_child()
|
279 |
{
|
280 |
+
if (count($this->children) > 0) {
|
281 |
+
return end($this->children);
|
282 |
}
|
283 |
return null;
|
284 |
}
|
285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
function next_sibling()
|
287 |
{
|
288 |
if ($this->parent === null) {
|
289 |
return null;
|
290 |
}
|
291 |
|
292 |
+
$idx = array_search($this, $this->parent->children, true);
|
|
|
293 |
|
294 |
+
if ($idx !== false && isset($this->parent->children[$idx + 1])) {
|
295 |
+
return $this->parent->children[$idx + 1];
|
296 |
}
|
297 |
|
298 |
+
return null;
|
|
|
|
|
|
|
|
|
299 |
}
|
300 |
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
function prev_sibling()
|
302 |
{
|
303 |
+
if ($this->parent === null) {
|
304 |
+
return null;
|
305 |
+
}
|
306 |
|
307 |
+
$idx = array_search($this, $this->parent->children, true);
|
|
|
308 |
|
309 |
+
if ($idx !== false && $idx > 0) {
|
310 |
+
return $this->parent->children[$idx - 1];
|
311 |
}
|
312 |
|
313 |
+
return null;
|
|
|
|
|
314 |
}
|
315 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
function find_ancestor_tag($tag)
|
317 |
{
|
318 |
global $debug_object;
|
319 |
if (is_object($debug_object)) { $debug_object->debug_log_entry(1); }
|
320 |
|
321 |
+
if ($this->parent === null) {
|
322 |
+
return null;
|
323 |
+
}
|
324 |
|
325 |
+
$ancestor = $this->parent;
|
326 |
+
|
327 |
+
while (!is_null($ancestor)) {
|
328 |
if (is_object($debug_object)) {
|
329 |
+
$debug_object->debug_log(2, 'Current tag is: ' . $ancestor->tag);
|
330 |
}
|
331 |
|
332 |
+
if ($ancestor->tag === $tag) {
|
333 |
break;
|
334 |
}
|
335 |
|
336 |
+
$ancestor = $ancestor->parent;
|
337 |
}
|
338 |
|
339 |
+
return $ancestor;
|
340 |
}
|
341 |
|
|
|
|
|
|
|
|
|
|
|
342 |
function innertext()
|
343 |
{
|
344 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
358 |
return $ret;
|
359 |
}
|
360 |
|
|
|
|
|
|
|
|
|
|
|
361 |
function outertext()
|
362 |
{
|
363 |
global $debug_object;
|
374 |
$debug_object->debug_log(1, 'Innertext of tag: ' . $this->tag . $text);
|
375 |
}
|
376 |
|
377 |
+
if ($this->tag === 'root') {
|
378 |
+
return $this->innertext();
|
379 |
+
}
|
380 |
|
381 |
+
// todo: What is the use of this callback? Remove?
|
382 |
if ($this->dom && $this->dom->callback !== null) {
|
383 |
call_user_func_array($this->dom->callback, array($this));
|
384 |
}
|
391 |
return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
|
392 |
}
|
393 |
|
394 |
+
$ret = '';
|
395 |
+
|
396 |
if ($this->dom && $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]) {
|
397 |
$ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup();
|
|
|
|
|
398 |
}
|
399 |
|
|
|
400 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
401 |
+
// todo: <br> should either never have HDOM_INFO_INNER or always
|
|
|
402 |
if ($this->tag !== 'br') {
|
403 |
$ret .= $this->_[HDOM_INFO_INNER];
|
404 |
}
|
405 |
+
} elseif ($this->nodes) {
|
406 |
+
foreach ($this->nodes as $n) {
|
407 |
+
$ret .= $this->convert_text($n->outertext());
|
|
|
|
|
408 |
}
|
409 |
}
|
410 |
|
|
|
411 |
if (isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END] != 0) {
|
412 |
$ret .= '</' . $this->tag . '>';
|
413 |
}
|
415 |
return $ret;
|
416 |
}
|
417 |
|
|
|
|
|
|
|
|
|
|
|
418 |
function text()
|
419 |
{
|
420 |
if (isset($this->_[HDOM_INFO_INNER])) {
|
441 |
foreach ($this->nodes as $n) {
|
442 |
// Start paragraph after a blank line
|
443 |
if ($n->tag === 'p') {
|
444 |
+
$ret = trim($ret) . "\n\n";
|
445 |
}
|
446 |
|
447 |
$ret .= $this->convert_text($n->text());
|
454 |
}
|
455 |
}
|
456 |
}
|
457 |
+
return $ret;
|
458 |
}
|
459 |
|
|
|
|
|
|
|
|
|
|
|
460 |
function xmltext()
|
461 |
{
|
462 |
$ret = $this->innertext();
|
465 |
return $ret;
|
466 |
}
|
467 |
|
|
|
468 |
function makeup()
|
469 |
{
|
470 |
// text, comment, unknown
|
508 |
return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>';
|
509 |
}
|
510 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
511 |
function find($selector, $idx = null, $lowercase = false)
|
512 |
{
|
513 |
$selectors = $this->parse_selector($selector);
|
560 |
return (isset($found[$idx])) ? $found[$idx] : null;
|
561 |
}
|
562 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
563 |
protected function seek($selector, &$ret, $parent_cmd, $lowercase = false)
|
564 |
{
|
565 |
global $debug_object;
|
591 |
&& $this->parent
|
592 |
&& in_array($this, $this->parent->children)) { // Next-Sibling Combinator
|
593 |
$index = array_search($this, $this->parent->children, true) + 1;
|
594 |
+
if ($index < count($this->parent->children))
|
595 |
+
$nodes[] = $this->parent->children[$index];
|
596 |
} elseif ($parent_cmd === '~'
|
597 |
&& $this->parent
|
598 |
&& in_array($this, $this->parent->children)) { // Subsequent Sibling Combinator
|
775 |
}
|
776 |
}
|
777 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
778 |
protected function match($exp, $pattern, $value, $case_sensitivity)
|
779 |
{
|
780 |
global $debug_object;
|
820 |
return false;
|
821 |
}
|
822 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
823 |
protected function parse_selector($selector_string)
|
824 |
{
|
825 |
global $debug_object;
|
911 |
*/
|
912 |
if($m[4] !== '') {
|
913 |
preg_match_all(
|
914 |
+
"/\[@?(!?[\w:-]+)(?:([!*^$|~]?=)[\"']?(.*?)[\"']?)?(?:\s+?([iIsS])?)?\]/is",
|
915 |
trim($m[4]),
|
916 |
$attributes,
|
917 |
PREG_SET_ORDER
|
1011 |
if (isset($this->attr[$name])) { unset($this->attr[$name]); }
|
1012 |
}
|
1013 |
|
|
|
|
|
1014 |
function convert_text($text)
|
1015 |
{
|
1016 |
global $debug_object;
|
1061 |
return $converted_text;
|
1062 |
}
|
1063 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1064 |
static function is_utf8($str)
|
1065 |
{
|
1066 |
$c = 0; $b = 0;
|
1088 |
return true;
|
1089 |
}
|
1090 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1091 |
function get_display_size()
|
1092 |
{
|
1093 |
global $debug_object;
|
1173 |
return $result;
|
1174 |
}
|
1175 |
|
1176 |
+
function save($filepath = '')
|
1177 |
+
{
|
1178 |
+
$ret = $this->outertext();
|
1179 |
+
|
1180 |
+
if ($filepath !== '') {
|
1181 |
+
file_put_contents($filepath, $ret, LOCK_EX);
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
return $ret;
|
1185 |
+
}
|
1186 |
+
|
1187 |
+
function addClass($class)
|
1188 |
+
{
|
1189 |
+
if (is_string($class)) {
|
1190 |
+
$class = explode(' ', $class);
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
if (is_array($class)) {
|
1194 |
+
foreach($class as $c) {
|
1195 |
+
if (isset($this->class)) {
|
1196 |
+
if ($this->hasClass($c)) {
|
1197 |
+
continue;
|
1198 |
+
} else {
|
1199 |
+
$this->class .= ' ' . $c;
|
1200 |
+
}
|
1201 |
+
} else {
|
1202 |
+
$this->class = $c;
|
1203 |
+
}
|
1204 |
+
}
|
1205 |
+
} else {
|
1206 |
+
if (is_object($debug_object)) {
|
1207 |
+
$debug_object->debug_log(2, 'Invalid type: ', gettype($class));
|
1208 |
+
}
|
1209 |
+
}
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
function hasClass($class)
|
1213 |
+
{
|
1214 |
+
if (is_string($class)) {
|
1215 |
+
if (isset($this->class)) {
|
1216 |
+
return in_array($class, explode(' ', $this->class), true);
|
1217 |
+
}
|
1218 |
+
} else {
|
1219 |
+
if (is_object($debug_object)) {
|
1220 |
+
$debug_object->debug_log(2, 'Invalid type: ', gettype($class));
|
1221 |
+
}
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
return false;
|
1225 |
+
}
|
1226 |
+
|
1227 |
+
function removeClass($class = null)
|
1228 |
+
{
|
1229 |
+
if (!isset($this->class)) {
|
1230 |
+
return;
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
if (is_null($class)) {
|
1234 |
+
$this->removeAttribute('class');
|
1235 |
+
return;
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
if (is_string($class)) {
|
1239 |
+
$class = explode(' ', $class);
|
1240 |
+
}
|
1241 |
+
|
1242 |
+
if (is_array($class)) {
|
1243 |
+
$class = array_diff(explode(' ', $this->class), $class);
|
1244 |
+
if (empty($class)) {
|
1245 |
+
$this->removeAttribute('class');
|
1246 |
+
} else {
|
1247 |
+
$this->class = implode(' ', $class);
|
1248 |
+
}
|
1249 |
+
}
|
1250 |
+
}
|
1251 |
+
|
1252 |
function getAllAttributes()
|
1253 |
{
|
1254 |
return $this->attr;
|
1274 |
$this->__set($name, null);
|
1275 |
}
|
1276 |
|
1277 |
+
function remove()
|
1278 |
+
{
|
1279 |
+
if ($this->parent) {
|
1280 |
+
$this->parent->removeChild($this);
|
1281 |
+
}
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
function removeChild($node)
|
1285 |
+
{
|
1286 |
+
$nidx = array_search($node, $this->nodes, true);
|
1287 |
+
$cidx = array_search($node, $this->children, true);
|
1288 |
+
$didx = array_search($node, $this->dom->nodes, true);
|
1289 |
+
|
1290 |
+
if ($nidx !== false && $cidx !== false && $didx !== false) {
|
1291 |
+
|
1292 |
+
foreach($node->children as $child) {
|
1293 |
+
$node->removeChild($child);
|
1294 |
+
}
|
1295 |
+
|
1296 |
+
foreach($node->nodes as $entity) {
|
1297 |
+
$enidx = array_search($entity, $node->nodes, true);
|
1298 |
+
$edidx = array_search($entity, $node->dom->nodes, true);
|
1299 |
+
|
1300 |
+
if ($enidx !== false && $edidx !== false) {
|
1301 |
+
unset($node->nodes[$enidx]);
|
1302 |
+
unset($node->dom->nodes[$edidx]);
|
1303 |
+
}
|
1304 |
+
}
|
1305 |
+
|
1306 |
+
unset($this->nodes[$nidx]);
|
1307 |
+
unset($this->children[$cidx]);
|
1308 |
+
unset($this->dom->nodes[$didx]);
|
1309 |
+
|
1310 |
+
$node->clear();
|
1311 |
+
|
1312 |
+
}
|
1313 |
+
}
|
1314 |
+
|
1315 |
function getElementById($id)
|
1316 |
{
|
1317 |
return $this->find("#$id", 0);
|
1380 |
|
1381 |
}
|
1382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1383 |
class simple_html_dom
|
1384 |
{
|
|
|
|
|
|
|
|
|
|
|
1385 |
public $root = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
1386 |
public $nodes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
1387 |
public $callback = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1388 |
public $lowercase = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1389 |
public $original_size;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1390 |
public $size;
|
1391 |
|
|
|
|
|
|
|
|
|
|
|
1392 |
protected $pos;
|
|
|
|
|
|
|
|
|
|
|
|
|
1393 |
protected $doc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1394 |
protected $char;
|
1395 |
|
1396 |
protected $cursor;
|
|
|
|
|
|
|
|
|
|
|
|
|
1397 |
protected $parent;
|
1398 |
protected $noise = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
1399 |
protected $token_blank = " \t\r\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1400 |
protected $token_equal = ' =/>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1401 |
protected $token_slash = " />\r\n\t";
|
|
|
|
|
|
|
|
|
|
|
|
|
1402 |
protected $token_attr = ' >';
|
1403 |
|
|
|
|
|
1404 |
public $_charset = '';
|
1405 |
public $_target_charset = '';
|
1406 |
|
|
|
|
|
|
|
|
|
|
|
1407 |
protected $default_br_text = '';
|
1408 |
|
|
|
|
|
|
|
|
|
|
|
1409 |
public $default_span_text = '';
|
1410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1411 |
protected $self_closing_tags = array(
|
1412 |
'area' => 1,
|
1413 |
'base' => 1,
|
1424 |
'track' => 1,
|
1425 |
'wbr' => 1
|
1426 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1427 |
protected $block_tags = array(
|
1428 |
'body' => 1,
|
1429 |
'div' => 1,
|
1432 |
'span' => 1,
|
1433 |
'table' => 1
|
1434 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1435 |
protected $optional_closing_tags = array(
|
1436 |
// Not optional, see
|
1437 |
// https://www.w3.org/TR/html/textlevel-semantics.html#the-b-element
|
1490 |
$this->clear();
|
1491 |
}
|
1492 |
|
|
|
1493 |
function load(
|
1494 |
$str,
|
1495 |
$lowercase = true,
|
1544 |
return $this;
|
1545 |
}
|
1546 |
|
|
|
1547 |
function load_file()
|
1548 |
{
|
1549 |
$args = func_get_args();
|
1555 |
}
|
1556 |
}
|
1557 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1558 |
function set_callback($function_name)
|
1559 |
{
|
1560 |
$this->callback = $function_name;
|
1561 |
}
|
1562 |
|
|
|
|
|
|
|
|
|
|
|
1563 |
function remove_callback()
|
1564 |
{
|
1565 |
$this->callback = null;
|
1566 |
}
|
1567 |
|
|
|
1568 |
function save($filepath = '')
|
1569 |
{
|
1570 |
$ret = $this->root->innertext();
|
1572 |
return $ret;
|
1573 |
}
|
1574 |
|
|
|
|
|
1575 |
function find($selector, $idx = null, $lowercase = false)
|
1576 |
{
|
1577 |
return $this->root->find($selector, $idx, $lowercase);
|
1578 |
}
|
1579 |
|
|
|
1580 |
function clear()
|
1581 |
{
|
1582 |
+
if (isset($this->nodes)) {
|
1583 |
+
foreach ($this->nodes as $n) {
|
1584 |
+
$n->clear();
|
1585 |
+
$n = null;
|
1586 |
+
}
|
1587 |
}
|
1588 |
|
1589 |
// This add next line is documented in the sourceforge repository.
|
1591 |
// use of clear.
|
1592 |
if (isset($this->children)) {
|
1593 |
foreach ($this->children as $n) {
|
1594 |
+
$n->clear();
|
1595 |
+
$n = null;
|
1596 |
}
|
1597 |
}
|
1598 |
|
1615 |
$this->root->dump($show_attr);
|
1616 |
}
|
1617 |
|
|
|
1618 |
protected function prepare(
|
1619 |
$str, $lowercase = true,
|
1620 |
$defaultBRText = DEFAULT_BR_TEXT,
|
1640 |
if ($this->size > 0) { $this->char = $this->doc[0]; }
|
1641 |
}
|
1642 |
|
|
|
|
|
|
|
|
|
|
|
1643 |
protected function parse()
|
1644 |
{
|
1645 |
while (true) {
|
1661 |
}
|
1662 |
}
|
1663 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1664 |
protected function parse_charset()
|
1665 |
{
|
1666 |
global $debug_object;
|
1682 |
}
|
1683 |
|
1684 |
if (empty($charset)) {
|
1685 |
+
// https://www.w3.org/TR/html/document-metadata.html#statedef-http-equiv-content-type
|
1686 |
$el = $this->root->find('meta[http-equiv=Content-Type]', 0, true);
|
1687 |
|
1688 |
if (!empty($el)) {
|
1719 |
}
|
1720 |
}
|
1721 |
|
|
|
|
|
1722 |
if (empty($charset)) {
|
1723 |
+
// https://www.w3.org/TR/html/document-metadata.html#character-encoding-declaration
|
1724 |
+
if ($meta = $this->root->find('meta[charset]', 0)) {
|
1725 |
+
$charset = $meta->charset;
|
1726 |
+
if (is_object($debug_object)) {
|
1727 |
+
$debug_object->debug_log(2, 'meta charset: ' . $charset);
|
1728 |
+
}
|
1729 |
+
}
|
1730 |
+
}
|
1731 |
+
|
1732 |
+
if (empty($charset)) {
|
1733 |
+
// Try to guess the charset based on the content
|
1734 |
+
// Requires Multibyte String (mbstring) support (optional)
|
1735 |
if (function_exists('mb_detect_encoding')) {
|
1736 |
+
/**
|
1737 |
+
* mb_detect_encoding() is not intended to distinguish between
|
1738 |
+
* charsets, especially single-byte charsets. Its primary
|
1739 |
+
* purpose is to detect which multibyte encoding is in use,
|
1740 |
+
* i.e. UTF-8, UTF-16, shift-JIS, etc.
|
1741 |
+
*
|
1742 |
+
* -- https://bugs.php.net/bug.php?id=38138
|
1743 |
+
*
|
1744 |
+
* Adding both CP1251/ISO-8859-5 and CP1252/ISO-8859-1 will
|
1745 |
+
* always result in CP1251/ISO-8859-5 and vice versa.
|
1746 |
+
*
|
1747 |
+
* Thus, only detect if it's either UTF-8 or CP1252/ISO-8859-1
|
1748 |
+
* to stay compatible.
|
1749 |
+
*/
|
1750 |
+
$encoding = mb_detect_encoding(
|
1751 |
+
$this->doc,
|
1752 |
+
array( 'UTF-8', 'CP1252', 'ISO-8859-1' )
|
1753 |
);
|
1754 |
|
1755 |
+
if ($encoding === 'CP1252' || $encoding === 'ISO-8859-1') {
|
1756 |
+
// Due to a limitation of mb_detect_encoding
|
1757 |
+
// 'CP1251'/'ISO-8859-5' will be detected as
|
1758 |
+
// 'CP1252'/'ISO-8859-1'. This will cause iconv to fail, in
|
1759 |
+
// which case we can simply assume it is the other charset.
|
1760 |
+
if (!@iconv('CP1252', 'UTF-8', $this->doc)) {
|
1761 |
+
$encoding = 'CP1251';
|
1762 |
+
}
|
1763 |
}
|
|
|
1764 |
|
1765 |
+
if ($encoding !== false) {
|
1766 |
+
$charset = $encoding;
|
1767 |
+
if (is_object($debug_object)) {
|
1768 |
+
$debug_object->debug_log(2, 'mb_detect: ' . $charset);
|
1769 |
+
}
|
|
|
|
|
|
|
|
|
1770 |
}
|
1771 |
+
}
|
1772 |
+
}
|
1773 |
|
1774 |
+
if (empty($charset)) {
|
1775 |
+
// Assume it's UTF-8 as it is the most likely charset to be used
|
1776 |
+
$charset = 'UTF-8';
|
1777 |
+
if (is_object($debug_object)) {
|
1778 |
+
$debug_object->debug_log(2, 'No match found, assume ' . $charset);
|
1779 |
}
|
1780 |
}
|
1781 |
|
1782 |
// Since CP1252 is a superset, if we get one of it's subsets, we want
|
1783 |
// it instead.
|
1784 |
+
if ((strtolower($charset) == 'iso-8859-1')
|
1785 |
+
|| (strtolower($charset) == 'latin1')
|
1786 |
+
|| (strtolower($charset) == 'latin-1')) {
|
1787 |
+
$charset = 'CP1252';
|
1788 |
if (is_object($debug_object)) {
|
1789 |
+
$debug_object->debug_log(2,
|
|
|
1790 |
'replacing ' . $charset . ' with CP1252 as its a superset'
|
1791 |
);
|
1792 |
}
|
|
|
|
|
1793 |
}
|
1794 |
|
1795 |
if (is_object($debug_object)) {
|
1799 |
return $this->_charset = $charset;
|
1800 |
}
|
1801 |
|
|
|
|
|
|
|
|
|
|
|
1802 |
protected function read_tag()
|
1803 |
{
|
1804 |
// Set end position if no further tags found
|
2077 |
return true;
|
2078 |
}
|
2079 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2080 |
protected function parse_attr($node, $name, &$space)
|
2081 |
{
|
2082 |
+
$is_duplicate = isset($node->attr[$name]);
|
|
|
|
|
|
|
|
|
|
|
|
|
2083 |
|
2084 |
+
if (!$is_duplicate) // Copy whitespace between "=" and value
|
2085 |
+
$space[2] = $this->copy_skip($this->token_blank);
|
2086 |
|
2087 |
switch ($this->char) {
|
2088 |
+
case '"':
|
2089 |
+
$quote_type = HDOM_QUOTE_DOUBLE;
|
2090 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2091 |
+
$value = $this->copy_until_char('"');
|
2092 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2093 |
break;
|
2094 |
+
case '\'':
|
2095 |
+
$quote_type = HDOM_QUOTE_SINGLE;
|
2096 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2097 |
+
$value = $this->copy_until_char('\'');
|
2098 |
$this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2099 |
break;
|
2100 |
+
default:
|
2101 |
+
$quote_type = HDOM_QUOTE_NO;
|
2102 |
+
$value = $this->copy_until($this->token_attr);
|
2103 |
}
|
2104 |
+
|
2105 |
+
$value = $this->restore_noise($value);
|
2106 |
+
|
2107 |
// PaperG: Attributes should not have \r or \n in them, that counts as
|
2108 |
// html whitespace.
|
2109 |
+
$value = str_replace("\r", '', $value);
|
2110 |
+
$value = str_replace("\n", '', $value);
|
2111 |
+
|
2112 |
// PaperG: If this is a "class" selector, lets get rid of the preceeding
|
2113 |
// and trailing space since some people leave it in the multi class case.
|
2114 |
if ($name === 'class') {
|
2115 |
+
$value = trim($value);
|
2116 |
+
}
|
2117 |
+
|
2118 |
+
if (!$is_duplicate) {
|
2119 |
+
$node->_[HDOM_INFO_QUOTE][] = $quote_type;
|
2120 |
+
$node->attr[$name] = $value;
|
2121 |
}
|
2122 |
}
|
2123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2124 |
protected function link_nodes(&$node, $is_child)
|
2125 |
{
|
2126 |
$node->parent = $this->parent;
|
2130 |
}
|
2131 |
}
|
2132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
2133 |
protected function as_text_node($tag)
|
2134 |
{
|
2135 |
$node = new simple_html_dom_node($this);
|
2140 |
return true;
|
2141 |
}
|
2142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2143 |
protected function skip($chars)
|
2144 |
{
|
2145 |
$this->pos += strspn($this->doc, $chars, $this->pos);
|
2146 |
$this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next
|
2147 |
}
|
2148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2149 |
protected function copy_skip($chars)
|
2150 |
{
|
2151 |
$pos = $this->pos;
|
2156 |
return substr($this->doc, $pos, $len);
|
2157 |
}
|
2158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2159 |
protected function copy_until($chars)
|
2160 |
{
|
2161 |
$pos = $this->pos;
|
2165 |
return substr($this->doc, $pos, $len);
|
2166 |
}
|
2167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2168 |
protected function copy_until_char($char)
|
2169 |
{
|
2170 |
if ($this->char === null) { return ''; }
|
2184 |
return substr($this->doc, $pos_old, $pos - $pos_old);
|
2185 |
}
|
2186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2187 |
protected function remove_noise($pattern, $remove_tag = false)
|
2188 |
{
|
2189 |
global $debug_object;
|
2216 |
}
|
2217 |
}
|
2218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2219 |
function restore_noise($text)
|
2220 |
{
|
2221 |
global $debug_object;
|
2262 |
return $text;
|
2263 |
}
|
2264 |
|
|
|
2265 |
function search_noise($text)
|
2266 |
{
|
2267 |
global $debug_object;
|
2295 |
}
|
2296 |
}
|
2297 |
|
|
|
2298 |
function childNodes($idx = -1)
|
2299 |
{
|
2300 |
return $this->root->childNodes($idx);
|
2312 |
|
2313 |
function createElement($name, $value = null)
|
2314 |
{
|
2315 |
+
return @str_get_html("<$name>$value</$name>")->firstChild();
|
2316 |
}
|
2317 |
|
2318 |
function createTextNode($value)
|
wp-retina-2x.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP Retina 2x
|
4 |
Plugin URI: https://meowapps.com
|
5 |
Description: Make your website look beautiful and crisp on modern displays by creating + displaying retina images.
|
6 |
-
Version: 5.5.
|
7 |
Author: Jordy Meow
|
8 |
Author URI: https://meowapps.com
|
9 |
Text Domain: wp-retina-2x
|
@@ -29,10 +29,10 @@ if ( class_exists( 'Meow_WR2X_Core' ) ) {
|
|
29 |
global $wr2x_picturefill, $wr2x_retinajs, $wr2x_lazysizes,
|
30 |
$wr2x_retina_image, $wr2x_core;
|
31 |
|
32 |
-
$wr2x_version = '5.5.
|
33 |
$wr2x_retinajs = '2.0.0';
|
34 |
$wr2x_picturefill = '3.0.2';
|
35 |
-
$wr2x_lazysizes = '5.1.
|
36 |
$wr2x_retina_image = '1.7.2';
|
37 |
|
38 |
// Admin
|
3 |
Plugin Name: WP Retina 2x
|
4 |
Plugin URI: https://meowapps.com
|
5 |
Description: Make your website look beautiful and crisp on modern displays by creating + displaying retina images.
|
6 |
+
Version: 5.5.7
|
7 |
Author: Jordy Meow
|
8 |
Author URI: https://meowapps.com
|
9 |
Text Domain: wp-retina-2x
|
29 |
global $wr2x_picturefill, $wr2x_retinajs, $wr2x_lazysizes,
|
30 |
$wr2x_retina_image, $wr2x_core;
|
31 |
|
32 |
+
$wr2x_version = '5.5.7';
|
33 |
$wr2x_retinajs = '2.0.0';
|
34 |
$wr2x_picturefill = '3.0.2';
|
35 |
+
$wr2x_lazysizes = '5.1.1';
|
36 |
$wr2x_retina_image = '1.7.2';
|
37 |
|
38 |
// Admin
|