Last active
November 12, 2020 06:26
-
-
Save marcus-at-localhost/d6f17b84406b3c8e0409c80c57656740 to your computer and use it in GitHub Desktop.
[Move inline scripts in HTML DOM to the bottom of the document] Sandbox: http://ideone.com/pDCedR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// test code | |
// http://ideone.com/pDCedR | |
$html = <<<HTML | |
<html> | |
<head> | |
</head> | |
<body> | |
<script class="keep"> | |
// will noit be moved | |
console.log('I stay'); | |
</script> | |
<script> | |
// will be moved at the end of the document | |
$('h1').addClass('header'); | |
</script> | |
<h1>DOMDocument</h1> | |
<p>Text<p> | |
<script src="jquery.js"></script> | |
<!-- inline php should appear below --> | |
</body> | |
</html> | |
HTML; | |
echo move_script($html); | |
function move_script($html) | |
{ | |
// in case we have some mangled special chars in the output, | |
// use this. <https://davidwalsh.name/domdocument-utf8-problem> | |
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'); | |
$dom = new DOMDocument(); | |
$dom->recover = true; | |
//$dom->substituteEntities = true; | |
$dom->formatOutput = true; | |
$dom->preserveWhiteSpace = true; | |
// set error level | |
// uncomment to suspress warnings that happen with embedded SVG, duplicate ids | |
// and raw entities like & instead of & | |
//$internalErrors = libxml_use_internal_errors(true); | |
// load HTML | |
// LIBXML_HTML_NODEFDTD | |
// keeps linebreaks after <script> tags being rearranged | |
// http://stackoverflow.com/a/32028596/814031 | |
// http://stackoverflow.com/a/29499398/814031 | |
$dom->loadHTML($html, LIBXML_HTML_NODEFDTD); | |
// collect the suspressed warnings/errors and print them out | |
//$errors = libxml_get_errors(); | |
//var_dump($errors); | |
// Restore error level | |
//libxml_use_internal_errors($internalErrors); | |
$xpath = new DOMXPath($dom); | |
// grab all inline script tags in <body> that not referencing a file or have the class="keep" attached | |
$script_tags = $xpath->query('//body//script[not(@src)][not(@class="keep")]'); | |
$mainBody = @$dom->getElementsByTagName('body')->item(0); | |
foreach ($script_tags as $tag) { | |
$mainBody->appendChild($tag->cloneNode(true)); | |
$tag->parentNode->removeChild($tag); | |
} | |
return $dom->saveHTML(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment