Years back I wrote some code to automatically include some javascript code inside html pages delivered by an http server. The approach is documented here in a blog entry and in this StackOverflow question. The solution served me well over the last years.
The approach in two sentences:
- for every full html page delivered by the http server some placeholder is added to the bottom of the page by means of server side substitution
- that placeholder again is replaced by the javascript code to be included by means of server side inclusion
Now I wanted to extend that solution and apply the same logic to pages based on SVG instead of HTML as document format. Note: not SVGs included in html pages, but pages in SVG format to be directly referenced by links.
The extension itself was not an issue, the javascript code is included inside the SVG markup. The issue is that the code is not executed. Unfortunately I have little knowledge of scripting in SVG which is why I am somewhat lost. Maybe someone can give me a hint what is wrong here :-)
The filter chain as included in various apache vhosts definitions:
# ----------
# internal requests to include the piwik tracking code at the bottom of every html page
FilterDeclare PIWIK_token
FilterProvider PIWIK_token SUBSTITUTE resp=Content-Type $text/html
SUBSTITUTE 's|^\s*</body>|<!--#include virtual="/piwik"--></body>|iq'
FilterProvider PIWIK_token SUBSTITUTE resp=Content-Type $image/svg+xml
SUBSTITUTE 's|^\s*</svg>|<!--#include virtual="/piwik"--></svg>|iq'
FilterDeclare PIWIK_code
FilterProvider PIWIK_code INCLUDES resp=Content-Type $text/html
FilterProvider PIWIK_code INCLUDES resp=Content-Type $image/svg+xml
FilterChain PIWIK_token PIWIK_code
# map virtual request to the file system
Alias /piwik /srv/www/internal/piwik.php
# all that is left for the virtual host is to do two things:
# SetEnv PIWIK_ID 15
# Include /etc/apache2/vhosts.d/_internal.inc
# note: the '15' above is an example piwik site id
The javascript code to be included is a slightly modified version of the piwik tracking snippet:
<?php
define('piwikBase','https://some.domain.xxx/stats/');
define('piwikSite',apache_getenv('PIWIK_ID'));
if(is_numeric(piwikSite)){
?>
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(["trackPageView"]);
_paq.push(["enableLinkTracking"]);
(function() {
var u="<?= piwikBase ?>";
_paq.push(["setTrackerUrl", u+"piwik.php"]);
_paq.push(["setSiteId", "<?= piwikSite ?>"]);
var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
})();
</script>
<?php } else { ?>
<!-- invalid piwik site id: <?php echo piwikSite;?> -->
<?php } ?>
As said: the extension works, the javascript code is successfully included into the SVG documents. However it is apparently not activated and I failed to see the cause for that...
The final SVG as delivered looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.2"
width="100%"
height="100%"
viewBox="0 0 640 400"
docname="somedocument.svg">
[... content of the SVG ...]
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(["trackPageView"]);
_paq.push(["enableLinkTracking"]);
(function() {
var u="https://some.domain.xxx/stats/";
_paq.push(["setTrackerUrl", u+"piwik.php"]);
_paq.push(["setSiteId", "15"]);
var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
})();
</script>
</svg>
Just guess, but I'd try to change the code so dynamic script injection is replaced with inline script tag with
xlink:href
(I've tested doing it dynamically as your code does with seemingly "more correct"createAttibuteNS('xlink','href','...')
but result wasn't executed either)Resulting code would look like this (haven't tested in real environment, so wath for typos):
I'm not sure about those
defer
andasync
stuff, whether it has any imact in SVG. I've tested this with simple datauri sample and it seemed to work well.Notes:
xmlns:xlink="http://www.w3.org/1999/xlink"
on the script or some of it's parent is necessary, but most probably your SVG has it alreadyCDATA
aren't necessary in this case, but if you plan to use<
or&
there in future … you know what.