Onto yesterday’s XML Lint Validation Browsing Tutorial XML Lint Validation web application progress, today, we start to add some onclick and ondblclick event logic to those left hand table cell pair of textarea elements …
<?php echo ”
function gcbr() {
if (rowseq != '') {
s1rect=s1.getBoundingClientRect();
s1.onclick=function(event) { s1click(event); };
s1.ondblclick=function(event) { alert('Line ' + s1.title + s1.getAttribute('data-status') + ':' + String.fromCharCode(10) + s2.title); };
s2rect=s2.getBoundingClientRect();
s2.onclick=function(event) { s2click(event); };
s2.ondblclick=function(event) { alert('Line ' + s1.title + s1.getAttribute('data-status') + ':' + String.fromCharCode(10) + s2.title); };
}
if (('' + location.hash).replace(/^null/g,'').replace(/^undefined/g,'').trim() != '') {
if (document.getElementById('myhxfile').value == '') {
document.getElementById('myhxfile').placeholder=decodeURIComponent(('' + location.hash).replace(/^\#/g,''));
var tf=document.getElementById('outgoing').value;
var tfis=tf.split(':')[0];
if (tfis.trim() != '') {
while (tf.indexOf(tfis + ':') != -1) {
tf=tf.replace(tfis + ':', decodeURIComponent(('' + location.hash).replace(/^\#/g,'')) + ':');
}
document.getElementById('outgoing').value=tf;
}
}
}
}
“; ?>
… and though we usually do not associate onclick logic with textarea elements, today we’re preferring that to any alternate use of div element alternative because, today, for the first time, we’re making use of the βsharpβ colour stops mentioned by linear-gradient(), thanks …
<?php echo ”
function s1click(e) {
var theheight=eval(eval('' + s1rect.height) / rowseq);
var codelines=s2.value.split(String.fromCharCode(10));
var errdetail='', ierr=0, linenum=0;
if (e.touches) {
if (e.touches[0].pageX) {
x1=(eval(e.touches[0].pageX + document.body.scrollLeft * 1) * 1);
y1=(eval(e.touches[0].pageY + eval(eval(e.touches[0].pageY % theheight) - theheight) + document.body.scrollTop * 1) * 1);
linenum=Math.floor(eval(1 + eval(eval(e.touches[0].pageY + document.body.scrollTop - s1rect.top) / theheight)));
} else {
x1=(eval(e.touches[0].clientX + document.body.scrollLeft * 1) * 1);
y1=(eval(e.touches[0].clientY + eval(eval(e.touches[0].clientY % theheight) - theheight) + document.body.scrollTop * 1) * 1);
linenum=Math.floor(eval(1 + eval(eval(e.touches[0].clientY + document.body.scrollTop - s1rect.top) / theheight)));
}
} else if (e.clientX || e.clientY) {
x1=(e.clientX + document.body.scrollLeft * 1);
y1=(e.clientY + eval(eval(e.clientY % theheight) - theheight) + document.body.scrollTop * 1);
linenum=Math.floor(eval(1 + eval(eval(e.clientY + document.body.scrollTop - s1rect.top) / theheight)));
} else {
x1=(e.pageX + document.body.scrollLeft * 1);
y1=(e.pageY + eval(eval(e.pageY % theheight) - theheight) + document.body.scrollTop * 1);
linenum=Math.floor(eval(1 + eval(eval(e.pageY + document.body.scrollTop - s1rect.top) / theheight)));
}
//alert('' + linenum + ' ' + y1 + '/' + document.body.scrollTop + ' ... ' + s1.scrollTop + ' ... ' + s1rect.top + '/' + s1rect.y + ' +++ ' + theheight);
var finds=document.getElementById('outgoing').value.split(':' + linenum + ':');
thergb=greenrgb;
s1.setAttribute('data-status', '');
if (eval('' + finds.length) > 1) {
for (ierr=1; ierr<finds.length; ierr++) {
errdetail+=String.fromCharCode(10) + finds[eval(-1 + ierr)].split(':' + linenum + ':')[0].split(String.fromCharCode(10))[eval(-1 + finds[eval(-1 + ierr)].split(':' + linenum + ':')[0].split(String.fromCharCode(10)).length)] + ':' + linenum + ':' + finds[eval(0 + ierr)].split(String.fromCharCode(10))[0];
}
errdetail+=String.fromCharCode(10);
thergb=redrgb;
s1.setAttribute('data-status', ' (has errors ... ' + errdetail + ' ... over to the right)');
}
s1.title='' + linenum;
s2.title='' + codelines[eval(-1 + linenum)];
y1-=eval('' + s1rect.top);
// linear-gradient(to right, yellow, yellow 20%, #009966 20%, #009966 80%, purple 80%, purple);
//alert('linear-gradient(to bottom, white, white ' + y1 + 'px, ' + thergb + ' ' + y1 + 'px, ' + thergb + ' ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white)');
s2.style.backgroundImage='linear-gradient(to bottom, white, white ' + y1 + 'px, ' + thergb + ' ' + y1 + 'px, ' + thergb + ' ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white)';
s1.style.backgroundImage='linear-gradient(to bottom, white, white ' + y1 + 'px, ' + thergb + ' ' + y1 + 'px, ' + thergb + ' ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white ' + eval(y1 + eval('' + s2rect.height) / rowseq) + 'px, white)';
}
function s2click(e) {
var theheight=eval(eval('' + s2rect.height) / rowseq);
var codelines=s2.value.split(String.fromCharCode(10));
var errdetail='', ierr=0, linenum=0;
if (e.touches) {
if (e.touches[0].pageX) {
x2=(eval(e.touches[0].pageX + document.body.scrollLeft * 1) * 1);
y2=(eval(e.touches[0].pageY + eval(eval(e.touches[0].pageY % theheight) - theheight) + document.body.scrollTop * 1) * 1);
linenum=Math.floor(eval(1 + eval(eval(e.touches[0].pageY + document.body.scrollTop - s2rect.top) / theheight)));
} else {
x2=(eval(e.touches[0].clientX + document.body.scrollLeft * 1) * 1);
y2=(eval(e.touches[0].clientY + eval(eval(e.touches[0].clientY % theheight) - theheight) + document.body.scrollTop * 1) * 1);
linenum=Math.floor(eval(1 + eval(eval(e.touches[0].clientY + document.body.scrollTop - s2rect.top) / theheight)));
}
} else if (e.clientX || e.clientY) {
x2=(e.clientX + document.body.scrollLeft * 1);
y2=(e.clientY + eval(eval(e.clientY % theheight) - theheight) + document.body.scrollTop * 1);
linenum=Math.floor(eval(1 + eval(eval(e.clientY + document.body.scrollTop - s2rect.top) / theheight)));
} else {
x2=(e.pageX + document.body.scrollLeft * 1);
y2=(e.pageY + eval(eval(e.pageY % theheight) - theheight) + document.body.scrollTop * 1);
linenum=Math.floor(eval(1 + eval(eval(e.pageY + document.body.scrollTop - s2rect.top) / theheight)));
}
var finds=document.getElementById('outgoing').value.split(':' + linenum + ':');
thergb=greenrgb;
s1.setAttribute('data-status', '');
if (eval('' + finds.length) > 1) {
for (ierr=1; ierr<finds.length; ierr++) {
errdetail+=String.fromCharCode(10) + finds[eval(-1 + ierr)].split(':' + linenum + ':')[0].split(String.fromCharCode(10))[eval(-1 + finds[eval(-1 + ierr)].split(':' + linenum + ':')[0].split(String.fromCharCode(10)).length)] + ':' + linenum + ':' + finds[eval(0 + ierr)].split(String.fromCharCode(10))[0];
}
errdetail+=String.fromCharCode(10);
thergb=redrgb;
s1.setAttribute('data-status', ' (has errors ... ' + errdetail + ' ... over to the right)');
}
s1.title='' + linenum;
s2.title='' + codelines[eval(-1 + linenum)];
y2-=eval('' + s2rect.top);
s2.style.backgroundImage='linear-gradient(to bottom, white, white ' + y2 + 'px, ' + thergb + ' ' + y2 + 'px, ' + thergb + ' ' + eval(y2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(y1 + eval('' + s1rect.height) / rowseq) + 'px, white)';
s1.style.backgroundImage='linear-gradient(to bottom, white, white ' + y2 + 'px, ' + thergb + ' ' + y2 + 'px, ' + thergb + ' ' + eval(y2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(y1 + eval('' + s1rect.height) / rowseq) + 'px, white)';
}
“; ?>
to be able to add colour coding to (the background of) HTML textarea elements.
Also, a hashtagging idea is implemented to aid with bringing over a browsed for file name into the “reporting mix” in our changed “third draft” xmllint_validation.php you might want to try for yourself.
Previous relevant XML Lint Validation Browsing Tutorial is shown below.
Yesterday’s XML Lint Validation Tutorial had us starting out on a discovery tour of XML Lint, yesterday …
- starting with an HTML or XML URL of interest incoming data way … and today, we add onto that …
- a local HTML or XMLfile browsing means of defining your input data into …
… our changed “second draft” xmllint_validation.php you might want to try for yourself, helped out by a tweaked client_browsing.htm client side HTML and Javascript inhouse helper.
Again, we see, into another way to yesterday’s work, how useful is a textarea element, in that it can facilitate the way …
- HTML and XML data can be input via populating the textarea innerHTML attribute … which flows through to a …
- textarea value attribute value where any < is mapped to < and > is mapped to > … ready for …
- an HTML form hosted textarea, given a filled in name attribute be able to share this data to that form’s action attributed value …
<?php
function ronecheck() {
if (document.getElementById('result1').innerHTML != '') {
document.getElementById('incoming').innerHTML=document.getElementById('result1').value;
document.getElementById('result1').innerHTML='';
document.getElementById('result1').value='';
document.getElementById('myhxfile').name='xx';
document.getElementById('mysub').click();
}
}
?>
… (in our case being the same PHP) … - able to be processed by recall PHP interventional code …
<?php
$vsnone='none';
$prefn='Please enter either HTML or XML file to validate ...';
$pth='';
$rn='' .rand(1,78477554);
$results='';
$precontents='';
$contents='';
$fn='';
if (!isset($_GET['htmlfile']) && isset($_GET['content'])) {
$_GET['htmlfile']=$_GET['content'];
}
if (!isset($_POST['htmlfile']) && isset($_POST['content'])) {
$_POST['htmlfile']=$_POST['content'];
}
if (isset($_GET['htmlfile'])) {
if (substr(trim(urldecode($_GET['htmlfile'])) . ' ', 0, 1) == '<') {
$contents=trim(str_replace('+',' ',urldecode($_GET['htmlfile'])));
if (strpos(strtolower(explode('>', $contents)[0]), 'html') !== false) {
$fn='/tmp/html_' . $rn . '.html';
} else if (strpos(strtolower(explode('>', $contents)[0]), 'xml') !== false) {
$fn='/tmp/xml_' . $rn . '.xml';
}
file_put_contents($fn, $contents);
} else {
$fn=str_replace('+',' ',urldecode($_GET['htmlfile']));
}
if ($fn != '') {
if (strpos($fn, 'localhost') !== false) {
$rhs=explode('localhost' . explode('/', explode('localhost', $fn)[1])[0], $fn)[1];
$fn=$_SERVER['DOCUMENT_ROOT'] . $rhs;
$pth='/usr/bin/';
} else if (strpos($fn, 'rjmprogramming.com.au') !== false) {
$rhs=explode('rjmprogramming.com.au' . explode('/', explode('rjmprogramming.com.au', $fn)[1])[0], $fn)[1];
$fn=$_SERVER['DOCUMENT_ROOT'] . $rhs;
} else if (strpos($_SERVER['SERVER_NAME'], 'localhost') !== false) {
$pth='/usr/bin/';
}
}
if (file_exists($fn)) {
if ($contents == '') {
$contents=file_get_contents($fn);
}
$prefn=$fn;
$fn=realpath($fn);
if (strpos(strtolower($fn), '.xml') !== false) {
$vsnone='block';
$results=shell_exec($pth . 'xmllint --valid --noout ' . $fn . ' 2> ' . ' ' . rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
if (file_exists(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err')) {
$results.="\n";
$results.=file_get_contents(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
unlink(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
}
} else if (strpos(strtolower($fn), '.htm') !== false) {
$vsnone='block';
$results=shell_exec($pth . 'xmllint --html --valid --noout ' . $fn . ' 2> ' . ' ' . rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
if (file_exists(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err')) {
$results.="\n";
$results.=file_get_contents(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
unlink(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
}
}
if (strpos($fn, '/tmp/') !== false) { unlink($fn); }
} else {
$contents='';
if (strpos($fn, '/tmp/') !== false) { unlink($fn); }
}
} else if (isset($_POST['htmlfile'])) {
if (substr(trim(urldecode($_POST['htmlfile'])) . ' ', 0, 1) == '<') {
$contents=trim(str_replace('+',' ',urldecode($_POST['htmlfile'])));
if (strpos(strtolower(explode('>', $contents)[0]), 'html') !== false) {
$fn='/tmp/html_' . $rn . '.html';
} else if (strpos(strtolower(explode('>', $contents)[0]), 'xml') !== false) {
$fn='/tmp/xml_' . $rn . '.xml';
}
file_put_contents($fn, $contents);
} else {
$fn=str_replace('+',' ',urldecode($_POST['htmlfile']));
}
if ($fn != '') {
if (strpos($fn, 'localhost') !== false) {
$rhs=explode('localhost' . explode('/', explode('localhost', $fn)[1])[0], $fn)[1];
$fn=$_SERVER['DOCUMENT_ROOT'] . $rhs;
$pth='/usr/bin/';
} else if (strpos($fn, 'rjmprogramming.com.au') !== false) {
$rhs=explode('rjmprogramming.com.au' . explode('/', explode('rjmprogramming.com.au', $fn)[1])[0], $fn)[1];
$fn=$_SERVER['DOCUMENT_ROOT'] . $rhs;
} else if (strpos($_SERVER['SERVER_NAME'], 'localhost') !== false) {
$pth='/usr/bin/';
}
}
if (file_exists($fn)) {
$prefn=$fn;
if ($contents == '') {
$contents=file_get_contents($fn);
}
$fn=realpath($fn);
if (strpos(strtolower($fn), '.xml') !== false) {
$vsnone='block';
$results=shell_exec($pth . 'xmllint --valid --noout ' . $fn . ' 2> ' . ' ' . rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
if (file_exists(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err')) {
$results.="\n";
$results.=file_get_contents(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
unlink(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
}
} else if (strpos(strtolower($fn), '.htm') !== false) {
$vsnone='block';
$results=shell_exec($pth . 'xmllint --html --valid --noout ' . $fn . ' 2> ' . ' ' . rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
if (file_exists(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err')) {
$results.="\n";
$results.=file_get_contents(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
//file_put_contents('xxx.xxx', $results);
unlink(rtrim(dirname(__FILE__), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'xmllint.err');
}
}
if (strpos($fn, '/tmp/') !== false) { unlink($fn); }
} else {
$contents='';
if (strpos($fn, '/tmp/') !== false) { unlink($fn); }
}
}
if ($contents != '') {
$lines=explode("\n", $contents);
for ($ii=1; $ii<=sizeof($lines); $ii++) {
$precontents.='' . $ii . "\n";
}
}
?>
Cute, huh?!
Previous relevant XML Lint Validation Tutorial is shown below.
Do you remember when we discussed the Sanitizer API, talked about at Sanitizer API Primer Tutorial, regarding it as a web application HTML (and more) validation tool?
Well, we’ve based a new “validator” of HTML or XML using the XML Lint web application on what we did then, but this code needing to be …
- under the auspices of a serverside scenario … ie. PHP … for us … calling on …
- underlying operating system call such as (for HTML qsall.htm incoming data file) …
xmllint --html --valid --noout ./qsall.htm
… via … - shell_exec
… there’s not much left of the original HTML and Javascript!
We had a fun time with HTML textarea elements and scrolling with the resultant “first draft” xmllint_validation.php you might want to try for yourself supplying an HTML or XML URL of intetest. Why, in particular? Well, it was the first time that we remember trying to make practically useful …
- a table cell (ie. td element) (the left of two) hosted …
- two textarea element arrangement whereby, ideally. they view …
- side by side
- if one is scrolled the two identically scroll the same amount … (document.body outerHTML) HTML …
<?php echo ”
<body onload="s1 = document.getElementById('preincoming'); s2 = document.getElementById('incoming'); s1.addEventListener('scroll', select_scroll_1, false); s2.addEventListener('scroll', select_scroll_2, false);" data-onload='onl();'>
<h1>XML Lint Validation <!--button onclick='trythis();' title='Try your own'>Usage</button--></h1>
<h3>RJM Programming - June, 2024</h3>
<form action=./xmllint_validation.php method=POST target=_self>
<table style=width:95%; border=5>
<tr><th colspan=2 style=text-align:center;>XML Lint validation of <input style=width:70%; onblur="if (this.value.length > 0) { document.getElementById('mysub').click(); }" name=htmlfile id=myhxfile placeholder='Please enter either HTML or XML file to validate ...' value="<?php echo str_replace('>','>',str_replace('<','<',$prefn)); ?>"></input></th></tr>
<tr><th>Data to validate</th><th>XML Lint results</th></tr>
<tr><td style=vertical-align:top;><textarea style=font-size:8px;display:inline-block;overflow-x:clip;text-wrap:nowrap;text-align:right; id=preincoming><?php echo str_replace('>','>',str_replace('<','<',$precontents)); ?></textarea><textarea onblur="if (this.value.length > 0 && '<?echo $fn; ?>' == '') { document.getElementById('mysub').click(); }" style=font-size:8px;display:inline-block;overflow-x:clip;text-wrap:nowrap; name=content id=incoming><?php echo str_replace('>','>',str_replace('<','<',$contents)); ?></textarea></td><td style=vertical-align:top;><textarea id=outgoing><?php echo str_replace('>','>',str_replace('<','<',$results)); ?></textarea></td></tr>
<tr><td></td><td><input type=submit id=mysub style=display:<?php echo $vsnone; ?> value=Validate></input></td></tr>
</table>
</form>
</body>
“; ?>
… uses Javascript …
<?php echo ”
var s1=null, s2=null;
// Thanks to https://stackoverflow.com/questions/7108270/scrolling-2-different-elements-in-same-time
function select_scroll_1(e) { s2.scrollTop = s1.scrollTop; }
function select_scroll_2(e) { s1.scrollTop = s2.scrollTop; }
“; ?>
… so that … - the left hand textarea contains code line numbers right aligned … to sidle up next to …
- the right hand textarea contains the code (HTML or XML) being validated by xmllint
… while …
- the right hand table cell contains the xmllint validation (of HTML or XML) results
… had us, in practice, thanking our lucky stars that …
- textarea elements are resizeable
- you can simulate “some cockpit action” aligning them vertically … Jim?!
Previous relevant Sanitizer API Primer Tutorial is shown below.
Today we’re roadtesting the Sanitizer API …
The HTML Sanitizer API allow developers to take untrusted strings of HTML and Document or DocumentFragment objects, and sanitize them for safe insertion into a document’s DOM.
… as another validation idea for HTML to add to our previous HTML Online Validation Tidy Errors Tutorial efforts.
Perhaps you’d like to try the “Usage” button of the proof of concept web application below …
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.