Reputation: 10211
With the help of the following php
function:
<?php
if (!function_exists('wrapAds')) {
function wrapAds($current_banner_name){
$STRING_EMPTY = "";
$openExprResult = array();
$closeExpreResult = array();
$openExpr = "/(<div[^>]*>)/";
$closeExpr = "/(<\/div>)/";
$banner = tsp_get_banner($current_banner_name);
$result = '<pre data-script-reference>'
.htmlspecialchars($banner)
.'</pre>';
return $result;
}
}
?>
I am rendering the following markup
:
<pre data-script-reference="1"><!--- s: middle-box-sidebar -->
<div class="ads middle-box-sidebar"><script type="text/javascript">
var FW_type = "4w";
var FW_code = "18xxxx;95xxx;70xxx;0";
var FW_dimension = "300x250";
var FW_category = "gossip";
</script>
<script src="//optimized-by.4wnetwork.com/simply_loader.js?4wvideo=true" type="text/javascript"></script></div>
<!--- e: middle-box-sidebar --></pre>
Now I am tring to postpone the encoded script execution later with the following script:
<script type="text/javascript">
[].slice.call(document.querySelectorAll('pre[data-script-reference]'))
.forEach(function(item){
var txt = document.createElement("textarea");
txt.innerHTML = item.innerHTML;
var parentNode = item.parentNode;
var p0 = txt.innerText;
// parentNode.removeChild(item);
parentNode.innerHTML += p0;
</script>
seems that decoded script isn't executed at all, what I am doing wrong?
Upvotes: 0
Views: 127
Reputation: 10211
After a trillion of useless code executions, I just noted a curious statement inside a long list of warnings:
"Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.". I googled around this message and I found a nice question.
The only not accepted answer suggest postscribe.js
Asynchronously write javascript, even with document.write.
Remote scripts, especially ads, block the page from doing anything else while they load. They contribute a large % to load times which affects your bottom line. Asynchronous ads do not block the page and can be delivered after core content - Async FTW.Why is it so hard to deliver ads asynchronously? Because they may contain calls to document.write, which expects to be handled synchronously. PostScribe lets you deliver a synchronous ad asynchronously without modifying the ad code.
So, since I have to manage both ads in the body and in the sidebar, I made a little refactoring, moving the php function in the functions.php:
/**
* redefine and get the legacy ads block from base library by name
* render as encoded plain text inside a *pre* wrapper
*/
function tsp_get_banner($current_banner_name){
$STRING_EMPTY = "";
// https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags
$openExpr = "/(<div[^>]*>)/";
$closeExpr = "/(<\/div>)/";
$openExprResult = $closeExpreResult = array();
$banner = original_tsp_get_banner($current_banner_name);
preg_match($openExpr, $banner, $openExprResult);
$banner = preg_replace($openExpr, $STRING_EMPTY, $banner);
preg_match($closeExpr, $banner, $closeExpreResult);
$banner = preg_replace($closeExpr, $STRING_EMPTY, $banner);
return wrapAdsSnippet($banner, $openExprResult[0], $closeExpreResult[0]);
}
function wrapAdsSnippet($source, $prefix, $postfix){
$result = '<pre data-script-reference style="display:none;">'
.htmlspecialchars($source)
.'</pre>';
if(isset($prefix) && isset($postfix)){
$result = $prefix.$result.$postfix;
}
return $result;
}
then I changed the inclusion of the block:
so that I don't need to change anything.
<?php
echo tsp_get_banner("middle-box-sidebar");
echo renderAds("middle-box-sidebar");
?>
I have just to change the final script to include in the footer.php:
var MyCompanyLab;
(function (MyCompanyLab) {
"use strict";
var Ads;
(function (Ads) {
var Optimization;
(function (Optimization) {
var PostProcessor = (function () {
function PostProcessor() {
}
PostProcessor.postponeAdsExecution = function () {
$("pre[data-script-reference]").each(function (idx, item) {
var parentNode = item.parentNode;
postscribe(parentNode, $('<textarea />').html(item.innerHTML).text(), {
done: function () { },
error: function () { },
releaseAsync: true,
});
parentNode.removeChild(item);
});
};
return PostProcessor;
}());
Optimization.PostProcessor = PostProcessor;
})(Optimization = Ads.Optimization || (Ads.Optimization = {}));
})(Ads = MyCompanyLab.Ads || (MyCompanyLab.Ads = {}));
})(MyCompanyLab|| (MyCompanyLab= {}));
<script type="text/javascript">
...
MyCompanyLab.Ads.Optimization.PostProcessor.postponeAdsExecution();
...
</script>
Upvotes: 1