Sizzling Code Sizzling Code - 5 months ago 68
Javascript Question

PHP | DOMDocument - get script text from within body

What i am trying to do is get scripts from body tag but only scripts that have text not script links

e-g

<script type="text/javascript">console.log("for a test run");</script>


not the scripts that have file src.

and want to place those scripts to end of page before

this is so far i have

echo "<pre>";
echo "reaches 1 <br />";
//work for inpage scripts
$mainBody = @$dom->getElementsByTagName('body')->item(0);
foreach (@$dom->getElementsByTagName('body') as $head) {
echo "reaches 2";

foreach (@$head->childNodes as $node) {

echo "reaches 3";
var_dump($node);
if ($node instanceof DOMComment) {
if (preg_match('/<script/i', $node->nodeValue)){
$src = $node->nodeValue;
echo "its a node";
var_dump($node);
}
}
if ($node->nodeName == 'script' && $node->attributes->getNamedItem('type')->nodeValue == 'text/javascript') {
if (@$src = $node->attributes->getNamedItem('src')->nodeValue) {
// yay - $src was true, so we don't do anything here
} else {
$src = $node->nodeValue;
}
echo "its a node2";
var_dump($node);
}
if (isset($src)) {
$move = ($this->params->get('exclude')) ? true : false;
foreach ($omit as $omitit) {
if (preg_match($omitit, $src) == 1) {
$move = ($this->params->get('exclude')) ? false : true;
break;
}
}
if ($move)
$moveme[] = $node;
unset($src);
}
}
}
foreach ($moveme as $moveit) {
echo "Moving";
print_r($moveit);
$mainBody->appendChild($moveit->cloneNode(true));
if ($pretty) {
$mainBody->appendChild($newline->cloneNode(false));
}
$moveit->parentNode->removeChild($moveit);
}
$mainBody = $xhtml ? $dom->saveXML() : $dom->saveHTML();

JResponse::setBody($sanitize?preg_replace($this->sanitizews['search'],$this->sanitizews['replace'],$mainBody):$mainBody);


=-=-=-=-=-=-=-=-

Update 1:

The problem is can also be in div or can be in nested divs.
so as using foreach @$head->childNodes only gets the top html tags and do not scan the inner tags that may contain tags.
i dont understand how to get all required script tags.

and no there is no error but there also has no script tags on top nodes.

=-=-=-=-=-=-=
after an answer of xpath. thanks for the answer. there is some progress in task. but now after moving of scripts to footer,i cant delete/remove original script tags.

here is the updated code i have so far.

echo "<pre>3";
// echo "reaches 1 <br />";
//work for inpage scripts
$xpath = new DOMXPath($dom);
$script_tags = $xpath->query('//body//script[not(@src)]');

foreach ($script_tags as $tag) {
// var_dump($tag->nodeValue);
$moveme[] = $tag;
}
$mainBody = @$dom->getElementsByTagName('body')->item(0);
foreach ($moveme as $moveItScript) {

print_r($moveItScript->cloneNode(true));
$mainBody->appendChild($moveItScript->cloneNode(true));
// var_dump($moveItScript->parentNode);
// $moveItScript->parentNode->removeChild($moveItScript);
/* try{
$mainBody->appendChild($moveit->cloneNode(true));
if ($pretty) {
$body->appendChild($newline->cloneNode(false));
}
$moveit->parentNode->removeChild($moveit);
}catch (Exception $ex){
var_dump($ex);
}*/
}
echo "</pre>";

Answer

In order to get ONLY the <script> nodes that dont have the src attribute you better use the DOMXPath:

$xpath = new DOMXPath($dom);
$script_tags = $xpath->query('//body//script[not(@src)]');

The variable $script_tags is now a DOMNodeList object that contains all of your script tags. You can now loop over the DOMNodeList to get all the nodes and do whatever you would like to do with them:

foreach ($script_tags as $tag) {
    var_dump($tag->nodeValue);
    $moveme[] = $tag;
}