mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-26 09:04:28 +00:00
This commit is contained in:
@@ -80,7 +80,7 @@ $save_vorschlag_error=false;
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1" />
|
||||
<link href="../../../skin/cis.css" rel="stylesheet" type="text/css" />
|
||||
<script language="Javascript">
|
||||
//Vorschau anzeigen
|
||||
@@ -310,7 +310,7 @@ if($frage->frage_id!='')
|
||||
echo "<form method='POST' action='$PHP_SELF?gebiet_id=$gebiet_id&nummer=$nummer&gruppe_kurzbz=$gruppe_kurzbz&frage_id=$frage->frage_id'>";
|
||||
echo "<table>";
|
||||
//Bei Aenderungen im Textfeld werden diese sofort in der Vorschau angezeigt
|
||||
echo "<tr><td colspan='2'>\n<textarea name='text' id='text' cols='30' rows='8' oninput='preview()'><![CDATA[$frage->text]]></textarea>\n</td></tr>";
|
||||
echo "<tr><td colspan='2'>\n<textarea name='text' id='text' cols='40' rows='20' oninput='preview()'><![CDATA[$frage->text]]></textarea>\n</td></tr>";
|
||||
echo "<tr><td>Demo <input type='checkbox' name='demo' ".($frage->demo?'checked="true"':'')." />
|
||||
Loesung <input type='text' name='loesung' value='$frage->loesung' size='1' /></td>
|
||||
<td align='right'><input type='submit' value='Speichern' name='submitdata' /></td>";
|
||||
@@ -345,7 +345,7 @@ if($frage->frage_id!='')
|
||||
echo "<td>Antwort</td><td><input type='text' size='1' name='antwort' value='$vorschlag->antwort' /></td>";
|
||||
echo '</tr>';
|
||||
echo '<tr>';
|
||||
echo '<td>Text:</td><td>\n<textarea name="text" id="text" rows="5" cols="30" oninput="preview()">'.$vorschlag->text."</textarea>\n</td>";
|
||||
echo '<td>Text:</td><td><textarea name="text" id="text" rows="20" cols="40" oninput="preview()"><![CDATA['.$vorschlag->text."]]></textarea>\n</td>";
|
||||
echo '</tr><tr valign="top">';
|
||||
//Upload Feld fuer Bild
|
||||
echo "<td>Bild:</td><td><input type='file' name='bild' /></td>";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+89
-82
@@ -19,6 +19,9 @@
|
||||
* Andreas Oesterreicher <[email protected]> and
|
||||
* Rudolf Hangl <[email protected]>.
|
||||
*/
|
||||
|
||||
header("Content-type: application/xhtml+xml");
|
||||
|
||||
// Formular zum beantworten der Fragen
|
||||
require_once('../config.inc.php');
|
||||
require_once('../../include/functions.inc.php');
|
||||
@@ -36,65 +39,69 @@ if(!$conn = pg_pconnect(CONN_STRING))
|
||||
|
||||
if(isset($_GET['gebiet_id']))
|
||||
$gebiet_id = $_GET['gebiet_id'];
|
||||
else
|
||||
else
|
||||
die('Gebiet muss uebergeben werden');
|
||||
|
||||
if(isset($_GET['frage_id']))
|
||||
$frage_id = $_GET['frage_id'];
|
||||
else
|
||||
else
|
||||
$frage_id = '';
|
||||
|
||||
$MAX_VORSCHLAEGE_PRO_ZEILE=4;
|
||||
|
||||
?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link href="../../skin/cis.css" rel="stylesheet" type="text/css">
|
||||
<script language="Javascript">
|
||||
function count_down(zeit)
|
||||
{
|
||||
if(zeit<=0)
|
||||
{
|
||||
document.location.href='gebietfertig.php';
|
||||
//alert('finish');
|
||||
}
|
||||
else
|
||||
{
|
||||
zeit = zeit-1;
|
||||
minuten = parseInt((zeit/60));
|
||||
if(minuten<10)
|
||||
minuten = '0'+minuten;
|
||||
sekunden = zeit-minuten*60;
|
||||
if(sekunden<10)
|
||||
sekunden = '0'+sekunden;
|
||||
document.getElementById('counter').innerHTML = minuten+':'+sekunden;
|
||||
window.setTimeout('count_down('+zeit+')',1000);
|
||||
}
|
||||
}
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/xsl" href="mathml.xsl"?>
|
||||
|
||||
function checkantwort()
|
||||
{
|
||||
val = document.getElementById('antwort').value;
|
||||
if(val.length>1)
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml; charset=iso-8859-1" />
|
||||
<link href="../../skin/cis.css" rel="stylesheet" type="text/css" />
|
||||
<script language="Javascript" type="text/javascript">
|
||||
//<![CDATA[
|
||||
function count_down(zeit)
|
||||
{
|
||||
alert('Antwort darf nur 1 Buchstabe sein');
|
||||
return false;
|
||||
if(zeit<=0)
|
||||
{
|
||||
document.location.href='gebietfertig.php';
|
||||
//alert('finish');
|
||||
}
|
||||
else
|
||||
{
|
||||
zeit = zeit-1;
|
||||
minuten = parseInt((zeit/60));
|
||||
if(minuten<10)
|
||||
minuten = '0'+minuten;
|
||||
sekunden = zeit-minuten*60;
|
||||
if(sekunden<10)
|
||||
sekunden = '0'+sekunden;
|
||||
document.getElementById('counter').innerHTML = minuten+':'+sekunden;
|
||||
window.setTimeout('count_down('+zeit+')',1000);
|
||||
}
|
||||
}
|
||||
if(val.length==0)
|
||||
return true;
|
||||
if(val.toUpperCase()<'A' || val.toUpperCase>'Z')
|
||||
|
||||
function checkantwort()
|
||||
{
|
||||
alert('Antwort darf nur ein Buchstabe von A-Z sein');
|
||||
return false;
|
||||
val = document.getElementById('antwort').value;
|
||||
if(val.length>1)
|
||||
{
|
||||
alert('Antwort darf nur 1 Buchstabe sein');
|
||||
return false;
|
||||
}
|
||||
if(val.length==0)
|
||||
return true;
|
||||
if(val.toUpperCase()<'A' || val.toUpperCase>'Z')
|
||||
{
|
||||
alert('Antwort darf nur ein Buchstabe von A-Z sein');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
//]]>
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -111,12 +118,12 @@ if($result = pg_query($conn, $qry))
|
||||
{
|
||||
$gruppe = $row->gruppe_kurzbz;
|
||||
}
|
||||
else
|
||||
else
|
||||
die('Pruefling wurde nicht gefunden');
|
||||
}
|
||||
else
|
||||
else
|
||||
die('Pruefling wurde nicht gefunden');
|
||||
|
||||
|
||||
//Start des Pruefungsvorganges
|
||||
if(isset($_GET['start']))
|
||||
{
|
||||
@@ -141,22 +148,22 @@ if(isset($_POST['submitantwort']) && isset($_GET['frage_id']))
|
||||
{
|
||||
if(!$antwort->load($_POST['antwort_id']))
|
||||
die('Antwort konnte nicht geladen werden');
|
||||
else
|
||||
else
|
||||
{
|
||||
$antwort->new = false;
|
||||
$antwort->antwort_id = $_POST['antwort_id'];
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
$antwort->new = true;
|
||||
|
||||
|
||||
$antwort->frage_id = $_GET['frage_id'];
|
||||
$antwort->pruefling_id = $_SESSION['pruefling_id'];
|
||||
$antwort->antwort = trim(strtoupper($_POST['antwort']));
|
||||
$antwort->endtime = date('Y-m-d H:i:s');
|
||||
if(!$antwort->save())
|
||||
die('Fehler beim Speichern');
|
||||
else
|
||||
else
|
||||
{
|
||||
$frage = new frage($conn);
|
||||
$frage_id = $frage->getNextFrage($gebiet_id, $gruppe, $frage_id);
|
||||
@@ -175,16 +182,16 @@ if($result = pg_query($conn, $qry))
|
||||
//Hat bereits Fragen beantwortet -> Frage anzeigen
|
||||
$demo=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
else
|
||||
{
|
||||
//Demo anzeigen
|
||||
$demo=true;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
die('error');
|
||||
}
|
||||
else
|
||||
else
|
||||
die('error');
|
||||
|
||||
//Zeit des Gebietes holen
|
||||
@@ -198,12 +205,12 @@ if(!$row = pg_fetch_object($result))
|
||||
list($stunde, $minute, $sekunde) = split(':',$row->zeit);
|
||||
|
||||
if($demo)
|
||||
{
|
||||
{
|
||||
//Wenn es sich um ein Demobeispiel handelt, dann wird die Maximale Gesamtzeit angezeigt
|
||||
echo $minute.':'.$sekunde.' Minuten ';
|
||||
echo "<input type=\"button\" value=\"Start\" onclick=\"document.location.href='$PHP_SELF?gebiet_id=$gebiet_id&start=true'\">";
|
||||
echo "<input type=\"button\" value=\"Start\" onclick=\"document.location.href='$PHP_SELF?gebiet_id=$gebiet_id&start=true'\" />";
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
//Wenn es sich um eine Testfrage handelt, dann wird die verbleibende Zeit angezeigt
|
||||
$qry = "SELECT '$row->zeit'-(now()-min(begintime)) as time FROM testtool.tbl_antwort JOIN testtool.tbl_frage USING(frage_id) WHERE gebiet_id='".addslashes($gebiet_id)."' AND pruefling_id='".addslashes($_SESSION['pruefling_id'])."'";
|
||||
@@ -219,7 +226,7 @@ else
|
||||
$zeit = $zeit*-1;
|
||||
}
|
||||
|
||||
echo '<span id="counter"></span> Minuten';
|
||||
echo '<span id="counter"></span> Minuten';
|
||||
echo "<script>count_down($zeit)</script>";
|
||||
}
|
||||
echo '</td></tr>';
|
||||
@@ -232,7 +239,7 @@ if($frage_id!='') //Frage wurde uebergeben
|
||||
{
|
||||
$frage->load($frage_id);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if($demo) //Demofrage wird angezeigt
|
||||
{
|
||||
@@ -254,7 +261,7 @@ else
|
||||
if($frage->frage_id!='')
|
||||
{
|
||||
$frage_id = $frage->frage_id;
|
||||
|
||||
|
||||
if(!$demo)
|
||||
{
|
||||
//Nachschauen ob diese Frage bereits angesehen wurde
|
||||
@@ -271,12 +278,12 @@ if($frage->frage_id!='')
|
||||
echo 'Fehler beim Speichern der Erstansicht';
|
||||
}
|
||||
}
|
||||
echo '<br><br><center>';
|
||||
echo '<br/><br/><center>';
|
||||
//Bild und Text der Frage anzeigen
|
||||
if($frage->bild!='')
|
||||
echo "<img src='bild.php?src=frage&frage_id=$frage->frage_id'><br><br>\n";
|
||||
echo "$frage->text<br><br>\n";
|
||||
|
||||
echo "<img src='bild.php?src=frage&frage_id=$frage->frage_id' /><br/><br/>\n";
|
||||
echo "$frage->text<br/><br/>\n";
|
||||
|
||||
//Vorschlaege laden
|
||||
$vs = new vorschlag($conn);
|
||||
$vs->getVorschlag($frage->frage_id);
|
||||
@@ -286,20 +293,20 @@ if($frage->frage_id!='')
|
||||
//Vorschlaege anzeigen
|
||||
foreach ($vs->result as $vorschlag)
|
||||
{
|
||||
echo "\n<td align=center>";
|
||||
echo "$vorschlag->antwort<br>";
|
||||
echo "\n<td align='center'>";
|
||||
echo "$vorschlag->antwort<br/>";
|
||||
if($vorschlag->bild!='')
|
||||
echo "<img src='bild.php?src=vorschlag&vorschlag_id=$vorschlag->vorschlag_id'><br>";
|
||||
echo "<img src='bild.php?src=vorschlag&vorschlag_id=$vorschlag->vorschlag_id' /><br/>";
|
||||
if($vorschlag->text!='')
|
||||
echo $vorschlag->text.'<br>';
|
||||
echo $vorschlag->text.'<br/>';
|
||||
echo "</td>";
|
||||
$anzahl++;
|
||||
|
||||
|
||||
if($anzahl>$MAX_VORSCHLAEGE_PRO_ZEILE)
|
||||
{
|
||||
echo '</tr><tr>';
|
||||
$anzahl=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '</tr></table>';
|
||||
//Antwort laden falls bereits vorhanden
|
||||
@@ -307,12 +314,12 @@ if($frage->frage_id!='')
|
||||
$antwort->getAntwort($_SESSION['pruefling_id'],$frage->frage_id);
|
||||
if(!$demo)
|
||||
{
|
||||
echo "<form action=\"$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$frage->frage_id\" method=\"POST\">";
|
||||
echo "<input type=\"hidden\" name=\"antwort_id\" value=\"$antwort->antwort_id\">";
|
||||
echo "Antwort: <input type=\"text\" size=\"1\" id=\"antwort\" name=\"antwort\" value=\"".htmlentities(addslashes($antwort->antwort))."\"> <input type=\"submit\" name=\"submitantwort\" onclick=\"return checkantwort()\" value=\"Speichern\">";
|
||||
echo "<form action=\"$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$frage->frage_id\" method=\"POST\">";
|
||||
echo "<input type=\"hidden\" name=\"antwort_id\" value=\"$antwort->antwort_id\" />";
|
||||
echo "Antwort: <input type=\"text\" size=\"1\" id=\"antwort\" name=\"antwort\" value=\"".htmlentities(addslashes($antwort->antwort))."\" /> <input type=\"submit\" name=\"submitantwort\" onclick=\"return checkantwort()\" value=\"Speichern\" />";
|
||||
echo "</form>";
|
||||
}
|
||||
echo '<br><br><br>';
|
||||
echo '<br/><br/><br/>';
|
||||
//Fusszeile mit Weiter Button und Sprung direkt zu einer Frage
|
||||
if(!$demo)
|
||||
{
|
||||
@@ -325,29 +332,29 @@ if($frage->frage_id!='')
|
||||
if($row->frage_id==$frage_id)
|
||||
echo " <u>$row->nummer</u> -";
|
||||
else
|
||||
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$row->frage_id' class='Item'>$row->nummer</a> -";
|
||||
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$row->frage_id' class='Item'>$row->nummer</a> -";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Naechste Frage holen und Weiter-Button anzeigen
|
||||
$frage = new frage($conn);
|
||||
$nextfrage = $frage->getNextFrage($gebiet_id, $gruppe, $frage_id, $demo);
|
||||
if($nextfrage)
|
||||
{
|
||||
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$nextfrage' class='Item'>Weiter >></a>";
|
||||
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$nextfrage' class='Item'>Weiter >></a>";
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
//Wenns der letzte Eintrag ist, wieder zum ersten springen
|
||||
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id' class='Item'>Weiter >></a>";
|
||||
}
|
||||
|
||||
|
||||
echo '</center>';
|
||||
}
|
||||
else
|
||||
{
|
||||
//Wenn kein Demo vorhanden ist
|
||||
echo "<br><br><br><center><b>Start drücken um zu beginnen</b></center>";
|
||||
echo "<br/><br/><br/><center><b>Start drücken um zu beginnen</b></center>";
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:fns="http://www.w3.org/2002/Math/preference" xmlns:mml="http://www.w3.org/1998/Math/MathML" extension-element-prefixes="msxsl fns">
|
||||
|
||||
<!--
|
||||
Copyright David Carlisle 2001, 2002.
|
||||
|
||||
Use and distribution of this code are permitted under the terms of the <a
|
||||
href="http://www.w3.org/Consortium/Legal/copyright-software-19980720"
|
||||
>W3C Software Notice and License</a>.
|
||||
-->
|
||||
|
||||
<xsl:include href="ctop.xsl"/>
|
||||
<xsl:include href="pmathml.xsl"/>
|
||||
|
||||
<xsl:output/>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:choose>
|
||||
<xsl:when test="system-property('xsl:vendor')='Transformiix'">
|
||||
<xsl:apply-templates mode="c2p"/>
|
||||
</xsl:when>
|
||||
<!-- not working, currently
|
||||
<xsl:when test="system-property('xsl:vendor')='Microsoft' and /*/@fns:renderer='css'">
|
||||
<xsl:variable name="pmml">
|
||||
<xsl:apply-templates mode="c2p"/>
|
||||
</xsl:variable>
|
||||
<xsl:apply-templates select="msxsl:node-set($pmml)/node()"/>
|
||||
</xsl:when>
|
||||
-->
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
@@ -0,0 +1,597 @@
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:h="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:fns="http://www.w3.org/2002/Math/preference" xmlns:doc="http://www.dcarlisle.demon.co.uk/xsldoc" xmlns:ie5="http://www.w3.org/TR/WD-xsl" exclude-result-prefixes="h ie5 fns msxsl fns doc" extension-element-prefixes="msxsl fns doc">
|
||||
|
||||
<!--
|
||||
$Id: pmathml.xsl,v 1.8 2003/06/23 14:46:44 davidc Exp $
|
||||
|
||||
Copyright David Carlisle 2001, 2002.
|
||||
|
||||
Use and distribution of this code are permitted under the terms of the <a
|
||||
href="http://www.w3.org/Consortium/Legal/copyright-software-19980720"
|
||||
>W3C Software Notice and License</a>.
|
||||
-->
|
||||
|
||||
<!-- MathPlayer mpdialog code for contributed by
|
||||
Jack Dignan and Robert Miner, both of Design Science.
|
||||
-->
|
||||
|
||||
<xsl:output method="xml" omit-xml-declaration="yes"/>
|
||||
|
||||
<ie5:if doc:id="iehack" test=".">
|
||||
<ie5:eval no-entities="t">'<!--'</ie5:eval>
|
||||
</ie5:if>
|
||||
|
||||
|
||||
<fns:x name="mathplayer" o="MathPlayer.Factory.1">
|
||||
<object id="mmlFactory" classid="clsid:32F66A20-7614-11D4-BD11-00104BD3F987">
|
||||
</object>
|
||||
<?import namespace="mml" implementation="#mmlFactory"?>
|
||||
</fns:x>
|
||||
|
||||
<fns:x name="techexplorer" o="techexplorer.AxTchExpCtrl.1">
|
||||
<object id="mmlFactory" classid="clsid:0E76D59A-C088-11D4-9920-002035EFB1A4">
|
||||
</object>
|
||||
<?import namespace="mml" implementation="#mmlFactory"?>
|
||||
</fns:x>
|
||||
|
||||
|
||||
<!-- SCRIPT not script due to weird mozilla bug
|
||||
http://bugzilla.mozilla.org/show_bug.cgi?id=158457
|
||||
-->
|
||||
|
||||
<fns:x name="css" o="Microsoft.FreeThreadedXMLDOM">
|
||||
<SCRIPT for="window" event="onload">
|
||||
var xsl = new ActiveXObject("Microsoft.FreeThreadedXMLDOM");
|
||||
xsl.async = false;
|
||||
xsl.validateOnParse = false;
|
||||
xsl.load("pmathmlcss.xsl");
|
||||
var xslTemplate = new ActiveXObject("MSXML2.XSLTemplate.3.0");
|
||||
xslTemplate.stylesheet=xsl.documentElement;
|
||||
var xslProc = xslTemplate.createProcessor();
|
||||
xslProc.input = document.XMLDocument;
|
||||
xslProc.transform();
|
||||
var str = xslProc.output;
|
||||
<!-- work around bug in IE6 under Win XP, RM 6/5/2002 -->
|
||||
var repl = "replace";
|
||||
if (window.navigator.appVersion.match(/Windows NT 5.1/)) { repl = ""; }
|
||||
var newDoc = document.open("text/html", repl);
|
||||
newDoc.write(str);
|
||||
</SCRIPT>
|
||||
</fns:x>
|
||||
|
||||
|
||||
<h:p>
|
||||
in mpdialog mode, we just write out some JavaScript to display
|
||||
dialog to the reader asking whether they want to install MathPlayer
|
||||
Depending on the response we get, we then instantiate an XSL processor
|
||||
and reprocess the doc, passing $secondpass according to the
|
||||
reader response.
|
||||
</h:p>
|
||||
<h:p>Using d-o-e is fairly horrible, but this code is only for IE
|
||||
anyway, and we need to force HTML semantics in this case.</h:p>
|
||||
|
||||
<xsl:variable name="mpdialog">
|
||||
var cookieName = "MathPlayerInstall=";
|
||||
function MPInstall(){
|
||||
var showDialog=true;
|
||||
var c = document.cookie;
|
||||
var i = c.indexOf(cookieName);
|
||||
if (i >= 0) {
|
||||
if ( c.substr(i + cookieName.length, 1) >= 2) { showDialog=false; }
|
||||
}
|
||||
if (showDialog) {
|
||||
MPDialog();
|
||||
c = document.cookie;
|
||||
i = c.indexOf(cookieName);
|
||||
}
|
||||
if (i >= 0) return c.substr(i + cookieName.length, 1);
|
||||
else return null;
|
||||
}
|
||||
|
||||
function MPDialog() {
|
||||
var vArgs="";
|
||||
var sFeatures="dialogWidth:410px;dialogHeight:190px;help:off;status:no";
|
||||
var text = "";
|
||||
text += "javascript:document.write('"
|
||||
text += '<script>'
|
||||
text += 'function fnClose(v) { '
|
||||
text += 'var exp = new Date();'
|
||||
text += 'var thirtyDays = exp.getTime() + (30 * 24 * 60 * 60 * 1000);'
|
||||
text += 'exp.setTime(thirtyDays);'
|
||||
text += 'var cookieProps = ";expires=" + exp.toGMTString();'
|
||||
text += 'if (document.forms[0].dontask.checked) v+=2;'
|
||||
text += 'document.cookie="' + cookieName + '"+v+cookieProps;'
|
||||
text += 'window.close();'
|
||||
text += '}'
|
||||
text += '</' + 'script>'
|
||||
text += '<head><title>Install MathPlayer?</title></head>'
|
||||
text += '<body bgcolor="#D4D0C8"><form>'
|
||||
text += '<table cellpadding=10 style="font-family:Arial;font-size:10pt" border=0 width=100%>'
|
||||
text += '<tr><td align=left>This page requires Design Science\\\'s MathPlayer&trade;.<br>'
|
||||
text += 'Do you want to download and install MathPlayer?</td></tr>';
|
||||
text += '<tr><td align=center><input type="checkbox" name="dontask">'
|
||||
text += 'Don\\\'t ask me again</td></tr>'
|
||||
text += '<tr><td align=center><input id=yes type="button" value=" Yes "'
|
||||
text += ' onClick="fnClose(1)">&nbsp;&nbsp;&nbsp;'
|
||||
text += '<input type="button" value=" No " onClick="fnClose(0)"></td></tr>'
|
||||
text += '</table></form>';
|
||||
text += '</body>'
|
||||
text += "')"
|
||||
window.showModalDialog( text , vArgs, sFeatures );
|
||||
}
|
||||
|
||||
function WaitDialog() {
|
||||
var vArgs="";
|
||||
var sFeatures="dialogWidth:510px;dialogHeight:150px;help:off;status:no";
|
||||
var text = "";
|
||||
text += "javascript:document.write('"
|
||||
text += '<script>'
|
||||
text += 'window.onload=fnLoad;'
|
||||
text += 'function fnLoad() {document.forms[0].yes.focus();}'
|
||||
text += 'function fnClose(v) { '
|
||||
text += 'window.returnValue=v;'
|
||||
text += 'window.close();'
|
||||
text += '}'
|
||||
text += '</' + 'script>'
|
||||
text += '<head><title>Wait for Installation?</title></head>'
|
||||
text += '<body bgcolor="#D4D0C8" onload="fnLoad()"><form><'
|
||||
text += 'table cellpadding=10 style="font-family:Arial;font-size:10pt" border=0 width=100%>'
|
||||
text += '<tr><td align=left>Click OK once MathPlayer is installed '
|
||||
text += 'to refresh the page.<br>'
|
||||
text += 'Click Cancel to view the page immediately without MathPlayer.</td></tr>';
|
||||
text += '<tr><td align=center><input id=yes type="button" '
|
||||
text += 'value=" OK " onClick="fnClose(1)">&nbsp;&nbsp;&nbsp;'
|
||||
text += '<input type="button" value="Cancel" onClick="fnClose(0)"></td></tr>'
|
||||
text += '</table></form>';
|
||||
text += '</body>'
|
||||
text += "')"
|
||||
return window.showModalDialog( text , vArgs, sFeatures );
|
||||
}
|
||||
|
||||
var result = MPInstall();
|
||||
|
||||
var action = "fallthrough";
|
||||
if (result == 1 || result == 3) {
|
||||
window.open("http://www.dessci.com/webmath/mathplayer");
|
||||
var wait = WaitDialog();
|
||||
if ( wait == 1) {
|
||||
action = "install";
|
||||
document.location.reload();
|
||||
|
||||
}
|
||||
}
|
||||
if (action == "fallthrough") {
|
||||
var xsl = new ActiveXObject("Microsoft.FreeThreadedXMLDOM");
|
||||
xsl.async = false;
|
||||
xsl.validateOnParse = false;
|
||||
xsl.load("pmathmlcss.xsl");
|
||||
var xslTemplate = new ActiveXObject("MSXML2.XSLTemplate.3.0");
|
||||
xslTemplate.stylesheet=xsl.documentElement;
|
||||
var xslProc = xslTemplate.createProcessor();
|
||||
xslProc.input = document.XMLDocument;
|
||||
|
||||
xslProc.transform();
|
||||
var str = xslProc.output;
|
||||
<!-- work around bug in IE6 under Win XP, RM 6/5/2002 -->
|
||||
var repl = "replace";
|
||||
if (window.navigator.appVersion.match(/Windows NT 5.1/)) { repl = ""; }
|
||||
var newDoc = document.open("text/html", repl);
|
||||
newDoc.write(str);
|
||||
document.close();
|
||||
}
|
||||
</xsl:variable>
|
||||
|
||||
<fns:x name="mathplayer-dl">mathplayer-dl</fns:x>
|
||||
|
||||
<fns:x name="techexplorer-plugin">techexplorer-plugin</fns:x>
|
||||
|
||||
<xsl:variable name="root" select="/"/>
|
||||
|
||||
|
||||
|
||||
<xsl:param name="activex">
|
||||
<xsl:choose>
|
||||
<xsl:when test="/*/@fns:renderer='techexplorer-plugin'">techexplorer-plugin</xsl:when>
|
||||
<xsl:when test="system-property('xsl:vendor')!='Microsoft'"/>
|
||||
<xsl:otherwise>
|
||||
<xsl:variable name="docpref" select="document('')/*/fns:x[@name=$root/*/@fns:renderer][1]"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$docpref='mathplayer-dl'">mathplayer-dl</xsl:when>
|
||||
<xsl:when test="$docpref and fns:isinstalled(string($docpref/@o))='true'">
|
||||
<xsl:copy-of select="$docpref/node()"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:copy-of select="(document('')/*/fns:x[fns:isinstalled(string(@o))='true'])[1]/node()"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:param>
|
||||
|
||||
<h:div doc:ref="iehack">
|
||||
<h:h3>IE5 hacks</h:h3>
|
||||
<h:p>This code will be ignored by an XSLT engine as a top level
|
||||
element in a foreign namespace. It will be executed by an IE5XSL
|
||||
engine and insert <!-- into the output stream, ie the start of a
|
||||
comment. This will comment out all the XSLT code which will be copied
|
||||
to the output. A similar clause below will close this comment, it is
|
||||
then followed by the IE5XSL templates to be executed.</h:p>
|
||||
<h:p>This trick is due to Jonathan Marsh of Microsoft, and used in
|
||||
<h:a href="http://www.w3.org/TR/2001/WD-query-datamodel-20010607/xmlspec-ie-dm.xsl">the stylesheet for
|
||||
the XPath 2 data model draft</h:a>.</h:p>
|
||||
</h:div>
|
||||
|
||||
<h:h2>XSLT stylesheet</h:h2>
|
||||
<h:h3>MSXSL script block</h:h3>
|
||||
|
||||
<h:p>The following script block implements an extension function that
|
||||
tests whether a specified ActiveX component is known to the client.
|
||||
This is used below to test for the existence of MathML rendering
|
||||
components.</h:p>
|
||||
<msxsl:script language="JScript" implements-prefix="fns">
|
||||
function isinstalled(ax)
|
||||
{
|
||||
try {
|
||||
var ActiveX = new ActiveXObject(ax);
|
||||
return "true";
|
||||
} catch (e) {
|
||||
return "false";
|
||||
}
|
||||
}
|
||||
</msxsl:script>
|
||||
|
||||
<h:p>The main bulk of this stylesheet is an identity transformation so...</h:p>
|
||||
<xsl:template match="*|comment()">
|
||||
<xsl:copy>
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<h:p>XHTML elements are copied sans prefix (XHTML is default namespace
|
||||
here, so these elements will still be in XHTML namespace</h:p>
|
||||
<xsl:template match="h:*">
|
||||
<xsl:element name="{local-name(.)}">
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
<h:p>IE's treatment of XHTML as HTML needs a little help here...</h:p>
|
||||
<xsl:template match="h:br|h:hr">
|
||||
<xsl:choose>
|
||||
<xsl:when test="system-property('xsl:vendor')='Microsoft'">
|
||||
<xsl:value-of disable-output-escaping="yes" select="concat('<',local-name(.))"/>
|
||||
<xsl:apply-templates mode="verb" select="@*"/>
|
||||
<xsl:text disable-output-escaping="yes">></xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:element name="{local-name(.)}">
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<h:p>This just ensures the mathml prefix declaration isn't copied from
|
||||
the source at this stage, so that the system will use the mml prefix
|
||||
coming from this stylesheet</h:p>
|
||||
<xsl:template match="h:html|html">
|
||||
<html>
|
||||
<xsl:copy-of select="@*[not(namespace-uri(.)='http://www.w3.org/2002/Math/preference')]"/>
|
||||
<xsl:apply-templates/>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<h:p>We modify the head element to add code to specify a Microsoft
|
||||
"Behaviour" if the behaviour component is known to the system.</h:p>
|
||||
<h:span doc:ref="mp">Test for MathPlayer (Design Science)</h:span>
|
||||
<h:span doc:ref="te">Test for Techexplorer (IBM)</h:span>
|
||||
<h:span doc:ref="ms"><h:div>Test for Microsoft. In this case we just
|
||||
output a small HTML file that executes a script that will re-process
|
||||
the source docuument with a different stylesheet. Doing things this
|
||||
way avoids the need to xsl:import the second stylesheet, which would
|
||||
very much increase the processing overhead of running this
|
||||
stylesheet.</h:div></h:span>
|
||||
<h:span doc:ref="other">Further tests (eg for netscape/mozilla) could
|
||||
be added here if necessary</h:span>
|
||||
<xsl:template match="h:head|head">
|
||||
<head>
|
||||
|
||||
<!-- new if for IE frames bug -->
|
||||
<xsl:if test="system-property('xsl:vendor')='Microsoft'">
|
||||
<xsl:if test="name(msxsl:node-set($activex)/*)=''">
|
||||
<object id="mmlFactory" classid="clsid:32F66A20-7614-11D4-BD11-00104BD3F987">
|
||||
</object>
|
||||
<xsl:processing-instruction name="import">
|
||||
namespace="mml" implementation="#mmlFactory"
|
||||
</xsl:processing-instruction>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when doc:id="mp" test="$activex='mathplayer-dl'">
|
||||
<xsl:if test="fns:isinstalled('MathPlayer.Factory.1')='false'">
|
||||
<SCRIPT for="window" event="onload">
|
||||
<xsl:value-of select="$mpdialog" disable-output-escaping="yes"/>
|
||||
</SCRIPT>
|
||||
</xsl:if>
|
||||
<xsl:copy-of select="document('')/*/fns:x[@name='mathplayer']"/>
|
||||
</xsl:when>
|
||||
<xsl:when doc:id="mp" test="not($activex='techexplorer-plugin') and system-property('xsl:vendor')='Microsoft'">
|
||||
<xsl:copy-of select="$activex"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise doc:id="other">
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:apply-templates/>
|
||||
</head>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="mml:math" priority="22">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$activex='techexplorer-plugin'">
|
||||
<embed width="300" height="75" type="text/mathml">
|
||||
<xsl:attribute name="mmldata">
|
||||
<xsl:apply-templates mode="verb" select="."/>
|
||||
</xsl:attribute>
|
||||
</embed>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:element name="mml:{local-name(.)}">
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- squash annotation elements -->
|
||||
|
||||
|
||||
|
||||
<h:p>Somewhat bizarrely in an otherwise namespace aware system,
|
||||
Microsoft behaviours are defined to trigger off the
|
||||
<h:em>prefix</h:em> not the <h:em>Namespace</h:em>. In the code above
|
||||
we associated a MathML rendering behaviour (if one was found) with the
|
||||
prefix <h:code>mml:</h:code> so here we ensure that this is the prefix
|
||||
that actually gets used in the output.</h:p>
|
||||
<xsl:template match="mml:*">
|
||||
<xsl:element name="mml:{local-name(.)}">
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
<h:p>Copy semantics element through in IE (so mathplayer gets to see
|
||||
mathplayer annotations, otherwise use first child or a presentation annotation.</h:p>
|
||||
<xsl:template match="mml:semantics">
|
||||
<xsl:choose>
|
||||
<xsl:when test="system-property('xsl:vendor')='Microsoft'">
|
||||
<xsl:element name="mml:{local-name(.)}">
|
||||
<xsl:copy-of select="@*"/>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:element>
|
||||
</xsl:when>
|
||||
<xsl:when test="mml:annotation-xml[@encoding='MathML-Presentation']">
|
||||
<xsl:apply-templates select="mml:annotation-xml[@encoding='MathML-Presentation']/node()"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates select="*[1]"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- a version of my old verb.xsl -->
|
||||
|
||||
<!-- non empty elements and other nodes. -->
|
||||
<xsl:template mode="verb" match="*[*]|*[text()]|*[comment()]|*[processing-instruction()]">
|
||||
<xsl:value-of select="concat('<',local-name(.))"/>
|
||||
<xsl:apply-templates mode="verb" select="@*"/>
|
||||
<xsl:text>></xsl:text>
|
||||
<xsl:apply-templates mode="verb"/>
|
||||
<xsl:value-of select="concat('</',local-name(.),'>')"/>
|
||||
</xsl:template>
|
||||
|
||||
<!-- empty elements -->
|
||||
<xsl:template mode="verb" match="*">
|
||||
<xsl:value-of select="concat('<',local-name(.))"/>
|
||||
<xsl:apply-templates mode="verb" select="@*"/>
|
||||
<xsl:text>/></xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<!-- attributes
|
||||
Output always surrounds attribute value by "
|
||||
so we need to make sure no literal " appear in the value -->
|
||||
<xsl:template mode="verb" match="@*">
|
||||
<xsl:value-of select="concat(' ',local-name(.),'=')"/>
|
||||
<xsl:text>"</xsl:text>
|
||||
<xsl:call-template name="string-replace">
|
||||
<xsl:with-param name="from" select="'"'"/>
|
||||
<xsl:with-param name="to" select="'&quot;'"/>
|
||||
<xsl:with-param name="string" select="."/>
|
||||
</xsl:call-template>
|
||||
<xsl:text>"</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<!-- pis -->
|
||||
<xsl:template mode="verb" match="processing-instruction()"/>
|
||||
|
||||
<!-- only works if parser passes on comment nodes -->
|
||||
<xsl:template mode="verb" match="comment()"/>
|
||||
|
||||
|
||||
<!-- text elements
|
||||
need to replace & and < by entity references-->
|
||||
<xsl:template mode="verb" match="text()">
|
||||
<a name="{generate-id(.)}"/>
|
||||
<xsl:call-template name="string-replace">
|
||||
<xsl:with-param name="to" select="'&gt;'"/>
|
||||
<xsl:with-param name="from" select="'>'"/>
|
||||
<xsl:with-param name="string">
|
||||
<xsl:call-template name="string-replace">
|
||||
<xsl:with-param name="to" select="'&lt;'"/>
|
||||
<xsl:with-param name="from" select="'<'"/>
|
||||
<xsl:with-param name="string">
|
||||
<xsl:call-template name="string-replace">
|
||||
<xsl:with-param name="to" select="'&amp;'"/>
|
||||
<xsl:with-param name="from" select="'&'"/>
|
||||
<xsl:with-param name="string" select="."/>
|
||||
</xsl:call-template>
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- end verb mode -->
|
||||
|
||||
<!-- replace all occurences of the character(s) `from'
|
||||
by the string `to' in the string `string'.-->
|
||||
<xsl:template name="string-replace">
|
||||
<xsl:param name="string"/>
|
||||
<xsl:param name="from"/>
|
||||
<xsl:param name="to"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($string,$from)">
|
||||
<xsl:value-of select="substring-before($string,$from)"/>
|
||||
<xsl:value-of select="$to"/>
|
||||
<xsl:call-template name="string-replace">
|
||||
<xsl:with-param name="string" select="substring-after($string,$from)"/>
|
||||
<xsl:with-param name="from" select="$from"/>
|
||||
<xsl:with-param name="to" select="$to"/>
|
||||
</xsl:call-template>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$string"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- end of verb.xsl -->
|
||||
|
||||
|
||||
|
||||
<h:h2>IE5XSL stylesheet</h:h2>
|
||||
<h:p>In a rare fit of sympathy for users of
|
||||
<h:em>the-language-known-as-XSL-in-IE5</h:em> this file incorporates a
|
||||
version of the above code designed to work in the Microsoft dialect.
|
||||
This is needed otherwise users of a MathML rendering behaviour would
|
||||
have to make a choice whether they wanted to use this stylesheet
|
||||
(keeping their source documents conforming XHTML+MathML) or to use
|
||||
the explicit Microsoft Object code, which is less portable, but would
|
||||
work in at least IE5.5.</h:p>
|
||||
|
||||
<h:p>This entire section of code, down to the end of the stylesheet is
|
||||
contained within this ie5:if. Thus XSLT sees it as a top level element
|
||||
from a foreign namespace and silently ignores it. IE5XSL sees it as
|
||||
"if true" and so executes the code.</h:p>
|
||||
|
||||
|
||||
<h:p doc:ref="closecomment">First close the comment started at the beginning. This ensures
|
||||
that the bulk of the XSLT code, while being copied to the result tree
|
||||
by the IE5XSL engine, will not be rendered in the browser.</h:p>
|
||||
|
||||
<h:span doc:ref="eval">Lacking attribute value templates in
|
||||
xsl:element, and the local-name() function, we resort to constructing
|
||||
the start and end tags in strings in javascript, then using
|
||||
no-entities attribute which is the IE5XSL equivalent of disable-output-encoding</h:span>
|
||||
<ie5:if test=".">
|
||||
|
||||
<ie5:eval doc:id="closecomment" no-entities="t">'-->'</ie5:eval>
|
||||
|
||||
<ie5:apply-templates select=".">
|
||||
|
||||
|
||||
<ie5:script>
|
||||
function mpisinstalled()
|
||||
{
|
||||
try {
|
||||
var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
|
||||
return "true";
|
||||
} catch (e) {
|
||||
return "false";
|
||||
}
|
||||
}
|
||||
</ie5:script>
|
||||
|
||||
<ie5:template match="/">
|
||||
<ie5:apply-templates/>
|
||||
</ie5:template>
|
||||
|
||||
<ie5:template match="head|h:head"/>
|
||||
|
||||
<ie5:template match="text()">
|
||||
<ie5:value-of select="."/>
|
||||
</ie5:template>
|
||||
|
||||
<ie5:template match="*|@*">
|
||||
<ie5:copy>
|
||||
<ie5:apply-templates select="*|text()|@*"/>
|
||||
</ie5:copy>
|
||||
</ie5:template>
|
||||
|
||||
|
||||
<ie5:template match="mml:*">
|
||||
<ie5:eval no-entities="t" doc:id="eval">'<mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1)</ie5:eval>
|
||||
<ie5:for-each select="@*">
|
||||
<ie5:eval no-entities="t">' ' + this.nodeName</ie5:eval>="<ie5:value-of select="."/>"
|
||||
</ie5:for-each>
|
||||
<ie5:eval no-entities="t">'>'</ie5:eval>
|
||||
<ie5:apply-templates select="*|text()"/>
|
||||
<ie5:eval no-entities="t">'</mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + '>'</ie5:eval>
|
||||
</ie5:template>
|
||||
|
||||
|
||||
<ie5:template match="mml:math">
|
||||
<ie5:if expr="mpisinstalled()=='false'">
|
||||
<embed width="300" height="75" type="text/mathml">
|
||||
<ie5:attribute name="mmldata">
|
||||
<ie5:eval doc:id="eval" no-entities="t">'<math>'</ie5:eval>
|
||||
<ie5:apply-templates/>
|
||||
<ie5:eval doc:id="eval" no-entities="t">'</math>'</ie5:eval>
|
||||
</ie5:attribute>
|
||||
</embed>
|
||||
</ie5:if>
|
||||
<ie5:if expr="mpisinstalled()=='true'">
|
||||
<ie5:eval doc:id="eval" no-entities="t">'<mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1)</ie5:eval>
|
||||
<ie5:for-each select="@*">
|
||||
<ie5:eval no-entities="t">' ' + this.nodeName</ie5:eval>="<ie5:value-of select="."/>"
|
||||
</ie5:for-each>
|
||||
<ie5:eval no-entities="t">'>'</ie5:eval>
|
||||
<ie5:apply-templates select="*|text()"/>
|
||||
<ie5:eval no-entities="t">'</mml:' + this.nodeName.substring(this.nodeName.indexOf(":")+1) + '>'</ie5:eval>
|
||||
</ie5:if>
|
||||
</ie5:template>
|
||||
|
||||
<ie5:template match="html|h:html">
|
||||
<html xmlns:mml="http://www.w3.org/1998/Math/MathML">
|
||||
<head>
|
||||
<ie5:if expr="mpisinstalled()=='true'">
|
||||
<object id="mmlFactory" classid="clsid:32F66A20-7614-11D4-BD11-00104BD3F987">
|
||||
</object>
|
||||
<ie5:pi name="IMPORT">
|
||||
namespace="mml" implementation="#mmlFactory"
|
||||
</ie5:pi>
|
||||
</ie5:if>
|
||||
<ie5:apply-templates select="h:head/*|head/*"/>
|
||||
</head>
|
||||
<body>
|
||||
<ie5:apply-templates select="body|h:body"/>
|
||||
</body>
|
||||
</html>
|
||||
</ie5:template>
|
||||
|
||||
</ie5:apply-templates>
|
||||
|
||||
|
||||
</ie5:if>
|
||||
|
||||
|
||||
</xsl:stylesheet>
|
||||
Reference in New Issue
Block a user