X-Git-Url: http://juplo.de/gitweb/?a=blobdiff_plain;f=openx.js;h=76e994bcec718316c5ceeed9ffe4f58203d2af82;hb=d95742f4f780bc45f7f091fb256251e332f41753;hp=b916e78934b3807904f775b27b66cb58c0d0dd56;hpb=56aef196f70f2949706ac865e1e19395e7549b7e;p=openx diff --git a/openx.js b/openx.js index b916e78..76e994b 100644 --- a/openx.js +++ b/openx.js @@ -1,156 +1,205 @@ -/** Optimized methods for fetching ad-banners via OpenX */ - -/** see: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/ */ +/* + * (C) Copyright 2012 juplo (http://juplo.de/). + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public License + * (LGPL) version 3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.html + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * Contributors: + * - Kai Moritz + */ (function( openx, $, undefined ) { - var body = document.getElementsByTagName('body')[0]; + var - var id; - var node; + domain, id, node, - var count = 0; - var slots = {}; - var ads = []; + count = 0, + slots = {}, + queue = [], + ads = [], + output = []; openx.show_ads = function(server, zones) { - document.write = render; - document.writeln = render; - - var domain = document.location.protocol == 'https:' ? 'https://' + server + ':8443':'http://' + server; + domain = document.location.protocol == 'https:' ? 'https://' + server + ':8443':'http://' + server; - var spc = document.createElement('script'); + var + name, + src = domain; - spc.type = 'text/javascript'; - spc.async = false; - spc.defer = false; + /** + * Without this option, jQuery appends an timestamp to every URL, that + * is fetched via $.getScript(). This can mess up badly written + * third-party-ad-scripts, that assume that the called URL's are not + * altered. + */ + $.ajaxSetup({ cache: true }); - spc.src = domain; - spc.src += "/www/delivery/spc.php?zones="; + src += "/www/delivery/spc.php?zones="; /** Only fetch banners, that are really included in this page */ - $('.oa').each(function() { - var node = $(this); - for(var name in zones) { + for(name in zones) { + $('.oa').each(function() { + var + node = $(this), + id; if (node.hasClass(name)) { - var id = 'oa_' + ++count; + id = 'oa_' + ++count; slots[id] = node; - spc.src += escape(id + '=' + zones[name] + "|"); + queue.push(id); + src += escape(id + '=' + zones[name] + "|"); } - } - }); - - spc.src += "&nz=1&source=" + escape(OA_source); - spc.src += "&r=" + Math.floor(Math.random()*99999999); - spc.src += "&block=1&charset=UTF-8"; - - if (window.location) spc.src += "&loc=" + escape(window.location); - if (document.referrer) spc.src += "&referer=" + escape(document.referrer); - - spc.onload = init_ads; + }); + } - body.appendChild(spc); + if (typeof OA_source !== 'undefined') + src += "&source=" + escape(OA_source); + src += "&nz=1&r=" + Math.floor(Math.random()*99999999); + src += "&block=1&charset=UTF-8"; + if (window.location) src += "&loc=" + escape(window.location); + if (document.referrer) src += "&referer=" + escape(document.referrer); - var fl = document.createElement('script'); + $.getScript(src, load_flash); - fl.type = 'text/javascript'; - fl.async = false; - fl.defer = false; + } - fl.src = domain + '/www/delivery/fl.js'; + function load_flash() { - body.appendChild(fl); + $.getScript(domain + '/www/delivery/fl.js', init_ads); } function init_ads() { - for (var id in slots) { + var i, id; + for (i=0; i 0) { - id = ads.pop(); - node = slots[id]; - - // node.append(id + ": " + node.attr('class')); - - var result; - var script; - var src; - var inline; - - while ((result = /" from OA_output[id] */ - OA_output[id] = OA_output[id].slice(result[0].length,OA_output[id].length); - result = /src\s*=\s*['"]([^'"]*)['"]/i.exec(src); - if (result == null) { - /** script-tag with inline-code: execute inline-code! */ - eval(inline); - } - else { - /** script-tag with src-URL! */ - script = document.createElement('script'); - script.type = 'text/javascript'; - script.async = false; - script.defer = false; - script.src = result[1]; - script.onload = render_ad; - /** The banner might not be rendered fully, or include more calls to document.write(). */ - ads.push(id); - /** Load the script and halt all work until the script is loaded and executed... */ - body.appendChild(script); // << The onload-event is only fired when appendChild is used! - return; + var result, src, inline, i; + + id = ads.shift(); + node = slots[id]; + + node.slideDown(); + + // node.append(id + ": " + node.attr('class')); + + /** + * If output was added via document.write(), this output must be + * rendered before other banner-code from the OpenX-server is rendered! + */ + insert_output(); + + while ((result = /" from OA_output[id] */ + OA_output[id] = OA_output[id].slice(result[0].length,OA_output[id].length); + result = /src\s*=\s*['"]?([^'"]*)['"]?\s/i.exec(src); + if (result == null) { + /** script-tag with inline-code: execute inline-code! */ + result = /^\s*<.*$/m.exec(inline); + if (result != null) { + /** Remove leading HTML-comments, because IE will stumble otherwise */ + inline = inline.slice(result[0].length,inline.length); + } + $.globalEval(inline); + insert_output(); // << The executed inline-code might have called document.write()! + } + else { + /** script-tag with src-URL! */ + if (OA_output[id].length > 0) + /** The banner-code was not rendered completely yet! */ + ads.unshift(id); + /** Load the script and halt all work until the script is loaded and executed... */ + $.getScript(result[1], render_ads); // << jQuery.getScript() generates onload-Handler for _all_ browsers ;) + return; + } + } } + + node.append(OA_output[id]); + OA_output[id] = ""; } - node.append(OA_output[id]); - OA_output[id] = ""; - /** This statement will only reached, when no script-element was rendered! */ - render_ad(); + /** All entries from OA_output were rendered */ + id = undefined; + node = undefined; } - function render() { + /** This function is used to overwrite document.write and document.writeln */ + function document_write() { if (id == undefined) return; - var str = ""; - for (var i=0; i < arguments.length; i++) - str += arguments[i]; + for (var i=0; i 0) { + output.push(OA_output[id]); + OA_output[id] = ""; + for (i=0; i