<?php
// tidy_example.php
// Using tiday
// RJM Programming - March, 2022 - Thanks to https://www.php.net/manual/en/function.tidy-warning-count.php

$trstyle="";
$origh="";
$ioff=0;
$incv="tidy_parse_string";
$rest="";
$unrest="";
$twc="";
$tec="";
$lasth="";
$sh4="";
$elecnt=0;
$h4more="";
$there=true;
$scr="<scr" . "ipt type='text/javascript'>
  var wo=null; 
  var ofc=false;
  var lasttitle=' ';
  var lastcont='';
  
  function butplus(thisf) {
    var idof=thisf.innerHTML.split(' id=\"')[1].split('\"')[0];
    if (document.getElementById(idof).value.indexOf('+') != -1) {
      //alert('' + thisf.method + ' ... ' + idof);
      if (('' + thisf.method).toLowerCase() == 'get') {
        location.href=thisf.action + '?' + idof + '=' + encodeURIComponent(document.getElementById(idof).value);
        return false;
      } else if (encodeURIComponent(document.getElementById(idof).value).length <= 800) {
        thisf.method='GET';
        location.href=thisf.action + '?' + idof + '=' + encodeURIComponent(document.getElementById(idof).value);
        return false;
      } else {
        //alert(document.getElementById(idof).value.replace(/\+/g,encodeURIComponent('+')));
        document.getElementById(idof).value=document.getElementById(idof).value.replace(/\+/g,encodeURIComponent('+'));
      }
    }
    return true;
  }
  
  function ntofc() {
    ofc=false;
  }
  
  function tofc() {
    ofc=true;
    setTimeout(ntofc, 500);
  }
  
  function woit(ine) {
    var asttitle='';
    var astcont='';
    var rectis=ine.getBoundingClientRect();
    if (wo) { wo.close(); wo=null; }
    if (('' + ine.type) == 'textarea' && ofc) {
      ofc=true;
    } else {
//    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
//      wo=window.open('','_blank');
//    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
//      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
//    }
    if (('' + ine.outerHTML).indexOf('</h4>') != -1) {
      //alert('0:' + ine.innerHTML);
      if (('' + ine.getAttribute('data-render')) != '') {
      var prefx='';
      var sufx='';
      if (('' + ine.getAttribute('data-render')).replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').indexOf('</body>') == -1) {
      prefx='<html><body>';
      sufx='</body></html>';
      } else if (('' + ine.getAttribute('data-render')).replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').indexOf('</html>') == -1) {
      prefx='<html>';
      sufx='</html>';
      }
      astcont=prefx + ('' + ine.getAttribute('data-render')).replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'') + sufx;
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
      wo=window.open('','_blank');
    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
    }
      wo.document.write(astcont);
      wo.document.title='PHP DOMDocument parsing passed onto web browser rendering';
      lastcont=astcont;
      } else if (ine.innerHTML.indexOf('<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10)) != -1) {
      //alert('1:' + ine.innerHTML.split('<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10))[1]);
      astcont=ine.innerHTML.split('<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10))[1].replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'').replace(/\&\#10067\;\ /g,'');
      asttitle='PHP DOMDocument parsing passed onto web browser rendering';
      //wo.document.write(ine.innerHTML.split('<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10) + '<br>' + String.fromCharCode(10))[1].replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'').replace(/\&\#10067\;\ /g,''));
      if (asttitle != lasttitle || astcont != lastcont) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
      wo=window.open('','_blank');
    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
    }
      wo.document.write(astcont);
      lastcont=astcont;
      }
      } else {
      //alert('2:' + ine.innerHTML);
      astcont=ine.innerHTML.replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'').replace(/\&\#10067\;\ /g,'').replace(/^\ \.\.\.\ /g,'');
      asttitle='PHP DOMDocument parsing passed onto web browser rendering';
      if (asttitle != lasttitle || astcont != lastcont) {
      //wo.document.write(ine.innerHTML.replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'').replace(/\&\#10067\;\ /g,'').replace(/^\ \.\.\.\ /g,''));
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
      wo=window.open('','_blank');
    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
    }
      wo.document.write(astcont);
      lastcont=astcont;
      }
      wo.document.title='PHP DOMDocument parsing passed onto web browser rendering';
      lasttitle='PHP DOMDocument parsing passed onto web browser rendering';
      }
    } else if (('' + ine.type) != 'textarea') {
      //alert(ine.outerHTML.split('</pre>')[0].split('>')[1]);
      //if (('' + ine.outerHTML).indexOf('DOMDocument') != -1) {
      //wo.document.write(ine.outerHTML.split('</pre>')[0].split('>')[1].replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<').replace(/\&\#10004\;\ /g,'').replace(/\&\#10060\;\ /g,'').replace(/\&\#10067\;\ /g,'').replace(/^\ \.\.\.\ /g,''));
      //wo.document.title='PHP DOMDocument parsing passed onto web browser rendering';
      //} else {
      astcont=ine.outerHTML.split('</pre>')[0].split('>')[1].replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<');
      asttitle='PHP tidy module parsing passed onto web browser rendering';
      if (asttitle != lasttitle || astcont != lastcont) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
      wo=window.open('','_blank');
    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
    }
      //wo.document.write(ine.outerHTML.split('</pre>')[0].split('>')[1].replace(/\&gt\;/g,'>').replace(/\&lt\;/g,'<'));
      wo.document.write(astcont);
      lastcont=astcont;
      wo.document.title='PHP tidy module parsing passed onto web browser rendering';
      lasttitle='PHP tidy module parsing passed onto web browser rendering';
      //}
      }
    } else {
      astcont=ine.value;
      if (document.URL.indexOf('localhost') != -1) {
      asttitle='Your proposed HTML passed onto web browser rendering';
      } else {
      asttitle='Your proposed HTML passed onto web browser rendering';
      }
      if (asttitle != lasttitle || astcont != lastcont) {
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { 
      wo=window.open('','_blank');
    } else {
      //alert(('' + ine.type) + ' ... ' + ine.outerHTML);
      wo=window.open('','_blank','left=' + rectis.left + ',top=' + rectis.top + ',width=' + rectis.width + ',height=' + rectis.height);
    }
      //wo.document.write(ine.value);
      wo.document.write(astcont);
      lastcont=astcont;
      if (document.URL.indexOf('localhost') != -1) {
      wo.document.title='Your proposed HTML passed onto web browser rendering';
      lasttitle='Your proposed HTML passed onto web browser rendering';
      } else {
      wo.document.title='Your proposed HTML passed onto web browser rendering';
      lasttitle='Your proposed HTML passed onto web browser rendering';
      }
      }
    }
    }
  }
</scr" . "ipt>";
$htmlin = '<p>first</p>
<p>test</i>
<bogustag>bogus</bogustag>';

if (isset($_GET['yourhtml'])) {
  $incv="tidy_parse_string";
  if (strpos($_GET['yourhtml'], '+') !== false && strpos($_GET['yourhtml'], ' ') === false) {
  $htmlin=str_replace(':plus:','+',str_replace('+',' ',urldecode(str_replace('%2B',':plus:',$_GET['yourhtml']))));
  } else {
  $htmlin=$_GET['yourhtml'];
  }
  //file_put_contents('x.x', $_GET['yourhtml'] . "\n\n" . urldecode($_GET['yourhtml']) . "\n\n" . $htmlin . "\n ... via ...\n" . str_replace('%2B','plus',$_GET['yourhtml']));
  if (strpos(strtolower($htmlin), '<html') === false) { $ioff--; }
  if (strpos(strtolower($htmlin), '<body') === false) { $ioff--; }
} else if (isset($_POST['yourhtml'])) { 
  $incv="tidy_parse_string";
  //$htmlin=str_replace('+',' ',urldecode($_POST['yourhtml']));
  //$htmlin=str_replace('plus','+',str_replace('+',' ',urldecode(str_replace('%2B','plus',$_POST['yourhtml']))));
  if (strpos($_GET['yourhtml'], '+') !== false && strpos($_POST['yourhtml'], ' ') === false) {
  $htmlin=str_replace(':plus:','+',str_replace('+',' ',urldecode(str_replace('%2B',':plus:',$_POST['yourhtml']))));
  } else {
  $htmlin=$_POST['yourhtml'];
  }
  if (strpos(strtolower($htmlin), '<html') === false) { $ioff--; }
  if (strpos(strtolower($htmlin), '<body') === false) { $ioff--; }
}

//file_put_contents('xxx.xxx', $htmlin);
$origh=$htmlin;

function outerHTML($e) {
     global $ioff, $origh;
     $docx = new DOMDocument();
     $docx->appendChild($docx->importNode($e, true));
     $dfx=$docx->saveHTML();
     if ($ioff == -2 && strpos(strtolower($dfx), '<html') !== false) {  return '';   }
     if ($ioff <= -1 && strpos(strtolower($dfx), '<body') !== false) {  return '';   }
     return $dfx;
}

function nodeContent($n, $outer=false) { // thanks to https://stackoverflow.com/questions/5404941/how-to-return-outer-html-of-domdocument
    global $ioff, $origh, $lasth;
    $d = new DOMDocument();
    $b = $d->importNode($n->cloneNode(true),true);
    $d->appendChild($b); 
    $h = $d->saveHTML();
    // remove outter tags
    if (!$outer) {
     $h = substr($h,strpos($h,'>')+1,-(strlen($n->nodeName)+4));
    } else {
     if ($ioff == -2 && strpos(strtolower($h), '<html') !== false) {  return '';   }
     if ($ioff <= -1 && strpos(strtolower($h), '<body') !== false) {  return '';   }
    }
    if (stripos( str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',$origh))))))),str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',('' . $h))))))))  ) !== false) {
      //file_put_contents('xx.xx','' . $h);
      //file_put_contents('xx.xx', str_replace('>','&gt;',str_replace('<','&lt;',str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',('' . $lasth)))))))))) . "\n\n" . str_replace('>','&gt;',str_replace('<','&lt;',str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',('' . $h)))))))))));
      if (strpos(str_replace('>','&gt;',str_replace('<','&lt;',str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',('' . $lasth)))))))))), str_replace('>','&gt;',str_replace('<','&lt;',str_replace('&nbsp;','',str_replace(' ','',str_replace("\n",'',str_replace("\r",'',str_replace("\r\n",'',str_replace("'",'',str_replace('"','',('' . $h))))))))))) !== false) {
        return '&#10067; ' . $h;
      }
      $lasth="";
      return '&#10004; ' . $h;
    } else if (1 == 1) {
      //file_put_contents('x.x','' . $h . "\n" . str_replace('"','',$origh));
      if (stripos($h, '</body>') === false) {
      $lasth='&#10060; ' . $h;
      return $lasth;
      } else {
      $lasth="";
      return '&#10060; ' . $h;
      }
    }
    return '' . $h;
}


if (function_exists($incv)) {
  try {
    $tidy = tidy_parse_string($htmlin);
    $twc='' . tidy_warning_count($tidy) . ' warnings';
    $tec='' . tidy_error_count($tidy) . ' errors<br><pre onclick=woit(this); id=tidyout title="PHP tidy parses HTML to look like below and click here to show web browser rendering" style=background-color:pink;>' . str_replace('>','&gt;',str_replace('<','&lt;',tidy_get_output($tidy))) . '</pre>';
  } catch (Exception $ex) {
    $there=false;
    $tec='No tidy module detected.';
  } 
} else {
  $tec='No tidy module detected.';
  $there=false;
  $doc = new DOMDocument();
  $doc->loadHTML($htmlin);
  //foreach ($doc->childNodes as $itemcn) {
    //if ($rest == "") { $rest = " +++ "; }
    //$rest.=' ' . str_replace('>','&gt;',str_replace('<','&lt;',nodeContent($itemcn, false)));
  //}
  foreach ($doc->getElementsByTagName("*") as $item) {
    $elecnt++;
    if ($rest == "") { $rest = " ... "; }
    //$rest.=' <br>' . str_replace('>','&gt;',str_replace('<','&lt;',outerHTML($item)));
    $h4more=" onclick=woit(this); id=tidyoutdd title='PHP DOMDocument parses HTML to look like below and click here to show web browser rendering'";
    $rest.=' <br>' . str_replace('>','&gt;',str_replace('<','&lt;',nodeContent($item, true)));
    $unrest.=str_replace('&#10004; ','',    str_replace('&#10060; ','',str_replace('&#10067; ','',str_replace('>','&gt;',str_replace('<','&lt;',nodeContent($item, true))))));
  }
  if ($unrest != '') {
    //file_put_contents('x.x',$unrest);
    $sh4="<scr" . "ipt tyle='text/javascript'>
    
    function laterh4() {
      document.getElementById('myh4').setAttribute(\"data-render\", \"" . str_replace("\n","",str_replace("\r\n","",str_replace('"','" + String.fromCharCode(34) + "',$unrest))) . "\");
    }
    
    setTimeout(laterh4, 2000);
    </scr" . "ipt>";
  }
  //if ($rest != '') { $rest.='</pre>'; }
  $twc='Number of elements detected is ' . ($ioff + $elecnt) . $rest;
}

//echo tidy_error_count($tidy) . "\n"; //1
//echo tidy_warning_count($tidy) . "\n"; //5
if (!$there && strpos($_SERVER['SERVER_NAME'], 'localhost') === false) {
echo "<html><head><title>Using tidy</title>" . $scr . "<style> input[type=submit] {  width:40%; height:50px; border-radius:30px;  } </style></head><body onload=\" if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {  for (var ii=1; ii<=4; ii++) { document.getElementById('tr' + ii).style.display='none';  } } \"><h1>Using tidy</h1><h2>RJM Programming - March, 2022 - Thanks to <a target=_blank href=https://www.php.net/manual/en/function.tidy-warning-count.php>https://www.php.net/manual/en/function.tidy-warning-count.php</a><h3>" . $tec . "</h3><h4 id=myh4" . $h4more . ">" . $twc . "</h4><table style=width:95%;><tr id=tr1" . $trstyle . "><th>Mac OS X or macOS MAMP</th></tr><tr id=tr2" . $trstyle . "><td><form onsubmit='return butplus(this);' target=_self method=GET action=HTTP://localhost:8888/tidy_example.php><textarea title='Slow two clicks to show web browser rendering' onfocus=tofc(); onclick=woit(this); style=width:90%;height:160px;background-color:#f0f0f0; id=yourhtml name=yourhtml>" . $htmlin . "</textarea><br><br><input style=background-color:yellow;;color:black; type=submit value=Validate></input></form></td></tr><tr id=tr3" . $trstyle . "><th>Windows MAMP</th></tr><tr id=tr4" . $trstyle . "><td><form onsubmit='return butplus(this);' target=_self method=GET action=HTTP://localhost/tidy_example.php><textarea title='Slow two clicks to show web browser rendering' onfocus=tofc(); onclick=woit(this); style=width:90%;height:160px;background-color:#f0f0f0; id=yourhtml name=yourhtml>" . $htmlin . "</textarea><br><br><input style=background-color:yellow;color:black; type=submit value=Validate></input></form></td><tr><th>PHP DomDocument</th></tr><tr><td><form onsubmit='return butplus(this);' id=myformp method=POST action=./tidy_example.php><textarea title='Slow two clicks to show web browser rendering' onfocus=tofc(); onclick=woit(this); style=width:90%;height:260px;background-color:#f0f0f0; id=yourhtml name=yourhtml>" . $htmlin . "</textarea><br><br><input style=background-color:yellow;color:black; type=submit value=Validate></input></form></td></tr></table>" . $sh4 . "</body></html>";
} else if (!$isthere) {
echo "<html><head><title>Using tidy</title>" . $scr . "<style> input[type=submit] {  width:40%; height:50px; border-radius:30px;  } </style></head><body><h1>Using tidy</h1><h2>RJM Programming - March, 2022 - Thanks to <a target=_blank href=https://www.php.net/manual/en/function.tidy-warning-count.php>https://www.php.net/manual/en/function.tidy-warning-count.php</a><h3>" . $tec . "</h3><h4 id=myh4" . $h4more . ">" . $twc . "</h4><form onsubmit='return butplus(this);' id=myform method=POST action=./tidy_example.php><textarea title='Slow two clicks to show web browser rendering' onfocus=tofc(); onclick=woit(this); style=width:90%;height:260px;background-color:#f0f0f0; id=yourhtml name=yourhtml>" . $htmlin . "</textarea><br><br><input style=background-color:yellow;;color:black; type=submit value=Validate></input></form>" . $sh4 . "</body></html>";
} else {
echo "<html><head><title>Using tidy</title>" . $scr . "<style> input[type=submit] {  width:40%; height:50px; border-radius:30px;  } </style></head><body><h1>Using tidy</h1><h2>RJM Programming - March, 2022 - Thanks to <a target=_blank href=https://www.php.net/manual/en/function.tidy-warning-count.php>https://www.php.net/manual/en/function.tidy-warning-count.php</a><h3>" . $twc . "</h3><h4 id=myh4" . $h4more . ">" . $twc . "</h4><form onsubmit='return butplus(this);' id=myform method=POST action=./tidy_example.php><textarea title='Slow two clicks to show web browser rendering' onfocus=tofc(); onclick=woit(this); style=width:90%;height:260px;background-color:#f0f0f0; id=yourhtml name=yourhtml>" . $htmlin . "</textarea><br><br><input style=background-color:yellow;;color:black; type=submit value=Validate></input></form>" . $sh4 . "</body></html>";
}
?>