Serving page as xhtml with original script

Where, oh where, is our heading? It’s not even rendered as text!

As you well know, Mozilla is quite merciless when it renders a page as application/xhtml+xml. The culprit here is external.js, specifically the innerHTML property, which, just like the document.write method, has been deprecated in XML.

We work around this problem by having two JavaScript files: one for browsers that handle the application/xhtml+xml MIME type correctly and another for browsers that don’t. To the code in the previous example we add a variable, $is_xml, the value of which is determined by what a browser accepts in the HTTP_ACCEPT header:

<?

if (isset($_SERVER["HTTP_ACCEPT"]) && stristr($_SERVER["HTTP_ACCEPT"], 'application/xhtml+xml')) {
  header('Content-Type: application/xhtml+xml; charset=ISO-8859-1');
  $is_xml = true;
} else {
  header('Content-Type: text/html; charset=ISO-8859-1');
  $is_xml = false;
}

?>

To call the appropriate script within <head>:

<?

if ($is_xml) {
  echo "<script type=\"text/javascript\" src=\"/external_moz.js\"></script>\n";
} else {
  echo "<script type=\"text/javascript\" src=\"/external.js\"></script>\n";
}

?>

Now Mozilla will look for external_moz.js, which is a modified version of external.js. First off, replace:

pasteHTML = '';

if(href != '' || thisid != '') {
  pasteHTML += '<a';
}
			
if(href != '') {
  pasteHTML += ' href="'+href+'"';
}

if(thisid != '') {
  pasteHTML += ' id="'+thisid+'"';
}

if(href != '' || thisid != '') {
  pasteHTML += '>';
}

pasteHTML += '<img class="'+current_element+'" id="'+current_element+'_'+i+'" name="'+current_element+'_'+i+'" src="'+path+'generate.php?action=display&w='+settings[current_element]["w"]+'&h='+settings[current_element]["h"]+'&padding='+settings[current_element]["padding"]+'&transparentbg='+settings[current_element]["transparentbg"]+'&bgcolor='+settings[current_element]["bgcolor"]+'&font_color='+settings[current_element]["font_color"]+'&shadow_color='+settings[current_element]["shadow_color"]+'&font_file='+settings[current_element]["font_file"]+'&font_size='+settings[current_element]["font_size"]+'&antialias='+settings[current_element]["antialias"]+'&text='+settings[current_element]["text"]+'" title="'+unescape(settings[current_element]["text"])+'" alt="'+unescape(settings[current_element]["text"])+'"  />';

if(href != '' || thisid != '') {
  pasteHTML += '</a>';
}

c.innerHTML = pasteHTML;

with:

url = ''+path+'generate.php?action=display&w='+settings[current_element]["w"]+'&h='+settings[current_element]["h"]+'&padding='+settings[current_element]["padding"]+'&transparentbg='+settings[current_element]["transparentbg"]+'&bgcolor='+settings[current_element]["bgcolor"]+'&font_color='+settings[current_element]["font_color"]+'&shadow_color='+settings[current_element]["shadow_color"]+'&font_file='+settings[current_element]["font_file"]+'&font_size='+settings[current_element]["font_size"]+'&antialias='+settings[current_element]["antialias"]+'&text='+settings[current_element]["text"]+'';
alt = ''+unescape(settings[current_element]["text"])+''
idname = ''+current_element+'_'+i+'';

if (href != '' || thisid != '') {
  var pastelink = document.createElement("a");
  if (href != '') {
    pastelink.setAttribute("href", href);
  }
  if (thisid != '') {
    pastelink.setAttribute("id", thisid);
  }
  c.appendChild(pastelink);
}

var pasteHTML = document.createElement("img");
pasteHTML.setAttribute("class", "'+current_element+'");
pasteHTML.setAttribute("id", idname);
pasteHTML.setAttribute("name", idname);
pasteHTML.setAttribute("src", url);
pasteHTML.setAttribute("alt", alt);
pasteHTML.setAttribute("title", alt);

if (href != '' || thisid != '') {
  pastelink.appendChild(pasteHTML);
} else {
  c.appendChild(pasteHTML);
}

Look for the variable path. If you’re into the habit of setting the base href tag in your pages, set the value of path relative to the value of base href; leave it empty otherwise. If all you get on the served page is the alt text instead of an image, click Tools>Page Info>Media to check the image URL and tweak the value of path accordingly.

That done, we fix that thing about tags between targeted elements being rendered as text. (We also tweak SIIR_get_href and SIIR_get_id because they’re a tad too greedy.) In both files, replace:

function SIIR_get_href(txt) {
 var text = txt;
 var thishref = text.replace(/<a(.*)href=\"/gi,'');
 thishref = thishref.replace(/\">(.*)/gi,'');
 return thishref;
}

function SIIR_get_id(txt) {
 var text = txt;
 var thisid = text.replace(/<a(.*)id=\"/gi,'');
 thisid = thisid.replace(/\">(.*)/gi,'');
 return thisid;
}

function SIIR_get_text(txt) {
  var text = txt;
  var txt = text.replace(/<\/a>/gi,'');
  txt = txt.replace(/<a(.*)>/gi,'');
  return txt;
}

with:

function SIIR_get_href(txt) {
 var text = txt;
 var thishref = /<a.*href=\"([^\"]+).*/gi;
 thishref = text.replace(thishref,"$1");
 return thishref;
}

function SIIR_get_id(txt) {
 var text = txt;
 var thisid = /<a.*id=\"([^\"]+).*/gi;
 thisid = text.replace(thisid,"$1");
 return thisid;
}

function SIIR_get_text(txt) {
  var text = txt;
  var txt = text.replace(/<\/.*?>/gi,'');
  txt = txt.replace(/<.*?>/gi,'');
  return txt;
}

And that’s it for our JavaScript tweaks. Now open generate.php and right after this line:

$this->text = html_entity_decode($this->text);

add:

/* Convert unicode characters (code from Stewart Rosenberger's Dynamic Text Replacement Script) */
$matches = null;
preg_match_all('/%u([0-9A-F]{4})/i', $this->text, $matches);
  if (!empty($matches)) 
    for ($i = 0; $i < sizeof($matches[0]); $i++)
      $this->text = str_replace($matches[0][$i], '&#'.hexdec($matches[1][$i]).';', $this->text);

Now let’s hold our breath and see if it runs.

SIIR Test: About | As text/html