XML Lint Validation CSS Background Colour Tutorial

XML Lint Validation CSS Background Colour Tutorial

XML Lint Validation CSS Background Colour Tutorial

Onto the recent XML Lint Validation Shared Encoding Tutorial we’d say what could “cheer things up”, shall we say, is to add some colour into the look of the XML Lint Validation web application.

And to do this with inline CSS <style></style> element within the <head></head> non-body part of the webpage. We allow the webpage to keep any of its “style=” specifications within the <body></body> section too, because, personally speaking, if we thought to do it as we were coding, then the chances are, these CSS specification must hold some weight and should stay. Today’s work is an “overall makeover” layer of CSS styling “just for aesthetics”, which is more the way we tend to organize web application CSS styling aesthetics around here. It’s up to you though, obviously, and if you have a dedicated CSS styling employee, then you may roll in a different direction … though Nala and Luna will tell you …

Clockwise is best!

But they would say that! They’ve never travelled north of the Equator!

So what CSS styling got applied?

<?php echo ”

<style>

th[colspan]:not([colspan="1"]) {
background-color: yellow;
}

textarea:nth-child(1) {
background-color: silver;
}

textarea#preincoming {
background-color: silver;
}

textarea:nth-child(2) {
background-color: rgb(245,245,245);
}

textarea#incoming {
background-color: rgb(245,245,245);
}

textarea:nth-child(3) {
background-color: pink !important;
}

textarea#outgoing {
background-color: pink !important;
}

</style>

“; ?>

… in our changed “sixth draft” xmllint_validation.php you might want to try for yourself.


Previous relevant XML Lint Validation Shared Encoding Tutorial is shown below.

XML Lint Validation Shared Encoding Tutorial

XML Lint Validation Shared Encoding Tutorial

There are a lot of web applications we’ve been involved with that …

  1. try to avoid (what we are most “peeved” by, as an issue) gobbledegook when dealing with non-ascii content we try, encoding wise, to corral towards UTF-8 encoding … and today we …
  2. add sharing and collaboration functionality, via email or SMS, to our current XML Lint Validation web application development

… hence the “Shared Encoding” curiosity in our blog posting title … well, you had to be there … today, in the days after yesterday’s XML Lint Validation SelectionChange Tutorial

Fancy a pertinent riddle?

What is always coming but never arrives?

Anyone, anyone?

Yes, Hoagy, do you have an answer?

No Bull Cow No Bull

Well, that’s quite rude and wise all at once, Hoagy! Anybody else? Yes, Edward, your answer …

Rearrange the sycophant!

… has merit too! But wish one of you would enunciate … use your words …
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

You have the answer Tatsumi? Well …

Today

… excellent try! But no, not quite. The answer is …

Tomorrow

But, five points to Hufflepuff, and we add today’s voucher for a cup of tea (no rushing please)!

But, back to business, as far as the encoding issue (of gobbledegook) goes, we mucked around thinking the fault lay with “meta” tags, and such, in the parent, until we relooked at the FileReader arrangements we had going back at a changed client_browsing.htm client side HTML and Javascript inhouse helper. We were always using readAsDataURL() method for this URL call containing “straighttext=” argument pattern, but we found more success starting to use readAsText() method for HTML and XML data inputs. Makes sense really! Now we go


blob.push(file.slice(start, stop + 1));
if (parent.document.getElementById('txtresultout')) {
reader[ij].readAsText(blob[ij]);
} else {
if (document.URL.indexOf('straighttext=') != -1) {
if (window.parent) {
if (parent.document.getElementById('result1') && parent.document.getElementById('result2')) {
reader[ij].readAsText(blob[ij]);
} else {
reader[ij].readAsDataURL(blob[ij]);
}
} else {
reader[ij].readAsDataURL(blob[ij]);
}
} else {

reader[ij].readAsDataURL(blob[ij]);
}
}

as well as


reader[ij].onloadend = (function(mfile) {
return function(evt) {
var dp='', ds=dssuffix, slideshowparent=false, ssuffix='0', nsuffix='2', blnks=' ', xhsf='', zhsfs=[];
var tomt='video/mp4', thext='', ithext=0;
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
if (document.URL.indexOf('straighttext=') != -1) {
if (window.parent) {
if (parent.document.getElementById('result1') && parent.document.getElementById('result2')) {
if (parent.document.getElementById('result1').innerHTML == '') {
parent.document.getElementById('result1').innerHTML=(evt.target.result); // used to use window.atob and .replace('data:application/octet-stream;base64,', '')
} else {
parent.document.getElementById('result2').innerHTML=(evt.target.result); // retest earth_scanner.html
}
}
}
}

// rest of FileReader.DONE code follows
} };
})(files[ij]);

… as a solution to this issue, putting a smile to many an emoji out there.

And as far as our email or SMS sharing goes, we avoided any need for PHP mail ideas by starting to involve hashtagged versions of the incoming XML or HTML input to the XML Lint validator …

<?php echo ”

var ihemail='', ihsms='';

function dohash(isfort) {
//alert('' + isfort);
if (!isfort || 8 == 8) {
var urlis=document.URL.split('?')[0].split('#')[0];
if (('' + document.getElementById('myform').action).indexOf('#') != -1) {
//alert('#' + ('' + document.getElementById('myform').action).split('#')[1]);
document.getElementById('ihid').value='' + ('' + document.getElementById('myform').action).split('#')[1];
document.getElementById('ihid').name='browsecontents';
urlis+='?browsecontents=' + encodeURIComponent(('' + document.getElementById('myform').action).split('#')[1]) + '&' + document.getElementById('myhxfile').name + '=' + encodeURIComponent(document.getElementById('myhxfile').value.replace(/\#/g,'')) + '#' + ('' + document.getElementById('myform').action).split('#')[1] + '&contents=' + encodeURIComponent(document.getElementById('incoming').value);
} else {
//alert('bC = ' + bc);
urlis+='?' + document.getElementById('myhxfile').name + '=' + encodeURIComponent(document.getElementById('myhxfile').value.replace(/\#/g,'')) + '#contents=' + encodeURIComponent(document.getElementById('incoming').value);
}
//alert(urlis);
if (!window.opener || ('' + document.referrer) == '') {
//alert('dref=' + document.referrer + ' urlis=' + urlis);
document.body.style.cursor='progress';
woois=window.open(urlis, '_blank');
} //else {
//alert('top' + document.referrer);
//}
if (1 == 1) {
document.getElementById('myform').target='myif';
ihsms=document.getElementById('dsms').innerHTML;
ihemail=document.getElementById('demail').innerHTML;
document.getElementById('myif').style.position='absolute';
document.getElementById('myif').style.top='0px';
document.getElementById('myif').style.left='0px';
document.getElementById('myif').style.width='100%';
document.getElementById('myif').style.height='100%';
document.getElementById('myif').style.zIndex='100';
document.getElementById('myif').style.display='block';
return true;
} else {
location.href=urlis;
}
return isfort; //false;
}
//alert(87);
return true;
}

function doemail() {
}

function dosms() {
if (document.getElementById('asms').href.indexOf('sms:&') != -1) {
document.getElementById('asms').href=document.getElementById('asms').href.replace('sms:&', 'sms:' + ('' + prompt('Please enter SMS number', '')).replace(/^null/g,'') + '&');
if (document.getElementById('asms').href.indexOf('sms:&') == -1) {
document.getElementById('asms').click();
}
}
}

function checkmyif(iois) {
if (iois != null) {
paconto = (iois.contentWindow || iois.contentDocument);
if (paconto != null) {
if (paconto.document) { paconto = paconto.document; }
if (paconto.body != null && (iois.src.indexOf('?') != -1 || iois.src.indexOf('#') != -1 || ihemail != '')) {
if (('' + document.referrer) == '') {
paconto.body.style.cursor='progress';
}
if (document.getElementById('demail')) {
//alert(document.getElementById('demail').innerHTML);
if (('' + document.referrer) == '') {
paconto.body.style.cursor='progress';
}
if (ihemail != '') {
paconto.document.getElementById('demail').innerHTML=ihemail;
} else {
paconto.document.getElementById('demail').innerHTML=document.getElementById('demail').innerHTML;
}
paconto.document.getElementById('demail').style.display='inline-block';
}
if (document.getElementById('dsms')) {
if (ihsms != '') {
paconto.document.getElementById('demail').innerHTML=ihsms;
} else {
paconto.document.getElementById('dsms').innerHTML=document.getElementById('dsms').innerHTML;
}
paconto.document.getElementById('dsms').style.display='inline-block';
}
}
}
}
}

function maybeshow() {
if (document.getElementById('incoming').value != '') {
var wwoo=window.open('','_blank','top=50,left=50,width=900,height=900');
if (document.getElementById('myhxfile').value != '') {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>' + document.getElementById('myhxfile').value + '</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
} else if (document.getElementById('myhxfile').placeholder.indexOf('Please ') == -1) {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>' + document.getElementById('myhxfile').placeholder + '</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
} else {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>XML Lint Validation incoming XML or HTML</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
}
}
}

“; ?>

… called into play via “a wrapped” HTML form onsubmit event call change

<?php

<form accept-charset="UTF-8" onsubmit=" if (document.getElementById('myhxfile').value == '') { document.getElementById('myhxfile').name='xx'; } return dohash(true);" action=./xmllint_validation.php<?php echo $bc; ?> id=myform method=POST target=_self>

?>

… in our changed “fifth draft” xmllint_validation.php you might want to try for yourself.

Happy sharing!


Previous relevant XML Lint Validation SelectionChange Tutorial is shown below.

XML Lint Validation SelectionChange Tutorial

XML Lint Validation SelectionChange Tutorial

Onto yesterday’s XML Lint Validation Onclick Tutorial‘s …

  • left hand cell hosted pair of textarea element onclick (and ondblclick) event logics … today we think a user could benefit from …
  • right hand cell hosted textarea element SelectionChange (keyboard related) event triggered via the user highlighting that textarea text (containing errors) of interest

… via …

<?php echo ”

var thesel='', reng='';

function prereverseengineer() {
var wasreng=reng;
reng='';
reverseengineer(wasreng);
}

function reverseengineer(what) {
var oury2=0, nexty2=0;
var theheight=eval(eval('' + s2rect.height) / rowseq);
var codelines=s2.value.split(String.fromCharCode(10));
var errdetail='', ierr=0, linenum=0, nums=[];
thergb=redrgb;
var bimg='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)';
var suff=', white)';

if (what.trim() != '') {
nums=what.split(',');
}
if (eval('' + nums.length) > 0) {
window.scrollTo(0,0);
s1.title='' + nums[0]; // + linenum;
s2.title='' + codelines[eval(-1 + eval('' + nums[0]))];
//alert(what);
oury2=eval(eval(-1 + eval('' + nums[0])) * theheight);
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
for (ierr=1; ierr<nums.length; ierr++) {
oury2=eval(eval(-1 + eval('' + nums[ierr])) * theheight);
//bimg+=thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, '; // + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
s1.title+=String.fromCharCode(10) + '' + nums[ierr]; // + linenum;
s2.title+=String.fromCharCode(10) + '' + codelines[eval(-1 + eval('' + nums[ierr]))];
}
if (bimg.indexOf(suff) == -1) { bimg+=suff.substring(1); }
s1.style.backgroundImage='' + bimg;
s2.style.backgroundImage='' + bimg;
document.getElementById('outgoing').title='Highlighted to left are codelines ' + what + ' with errors';
}
}

function decorateleft() {
var jerr=0;
reng=''
if (ourdelim == ':') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].trim() != '') {
if (ourfindsare[jerr].substring(0,1) >= '0' && ourfindsare[jerr].substring(0,1) <= '9') {
if (ourfindsare[jerr].slice(-1) >= '0' && ourfindsare[jerr].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr]; } else { reng+=',' + ourfindsare[jerr]; }
}
}
}
}
}
} else if (ourdelim.trim() != '') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].split(':')[0].trim() != '') {
if (ourfindsare[jerr].split(':')[0].substring(0,1) >= '0' && ourfindsare[jerr].split(':')[0].substring(0,1) <= '9') {
if (ourfindsare[jerr].split(':')[0].slice(-1) >= '0' && ourfindsare[jerr].split(':')[0].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr].split(':')[0]; } else { reng+=',' + ourfindsare[jerr].split(':')[0]; }
}
}
}
}
}
}
if (reng != '') {
setTimeout(prereverseengineer, 9000); // reverseengineer(reng);
}
}

function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
//document.title=(('' + activeElement.id) + activeElement.outerHTML.substring(0,23));
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0 && ('' + activeElement.id) == 'outgoing') {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
ourdelim=':';
ourfindsare=[];
thesel='';
// Do something with your range
if (eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
if (thesel.trim() != '' && thesel.indexOf(':') != -1) {
var floc=thesel.split(':')[0];
if (tfis != '') {
if (eval('' + floc.length) >= eval('' + tfis.length)) {
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
} else {
thesel=thesel.replace(':', tfis + ':');
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
}
} else {
ourfindsare=thesel.split(ourdelim);
}
decorateleft();
}
}
}
}

document.addEventListener('selectionchange', handleSelection);

“; ?>

… in our changed “fourth draft” xmllint_validation.php you might want to try for yourself.


Previous relevant XML Lint Validation Onclick Tutorial is shown below.

XML Lint Validation Onclick Tutorial

XML Lint Validation Onclick Tutorial

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.

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

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 &lt; and > is mapped to &gt; … 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.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.


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.

Posted in eLearning, Event-Driven Programming, Not Categorised, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Xgimi Projector Android TV Web Browser Tutorial

Xgimi Projector Android TV Web Browser Tutorial

Xgimi Projector Android TV Web Browser Tutorial

For some time now, we’ve had no Android phone to test web applications with. This can be like “flying blind” regarding a big sector of the online user cohort.

There are simulators out there, but we thought of another idea early this morning. The recent Projector Viewing Primer Tutorial talked about …

… and we thought that with that word “Android” involved, if the Google Play has an app to support a web browser accessible via the Xgimi projector, then we “might be cooking with gas”.

The second such web browser related app called “Browser”, of many, hit that nail on its head, mentioning in its credentials “Android” in amongst the …


alert('navigator.userAgent=' + ('' + navigator.userAgent)); // via codeline ... // aconto.getElementById('mytable').ondblclick=function(){ alert('navigator.userAgent=' + ('' + navigator.userAgent)); };

… test we conducted for each new Browser app installed.

And using this environment to call our RJM Programming Landing Page links to blog posts like below’s Projector Viewing Primer Tutorial show, at least, two issues …

  1. Landing Page clicks of “those blue backgrounded” thumbnails did not succeed in opening the relevent WordPress Blog post … and …
  2. at that relevant WordPress Blog post clicking the main blog post image failed too

We found, with Android, navigation was friendliest using …


top.location.href=[WordPressBlogPostURL];

… Javascript code arrangements, and in both cases we fell short, with existant code so that we needed to attend to …

  1. Landing Page clicks of “those blue backgrounded” thumbnails did not succeed in opening the relevent WordPress Blog post … was fixed via

    function check_if(iois) {
    if (iois != null) {
    var aconto = (iois.contentWindow || iois.contentDocument);
    if (aconto != null) {
    if (aconto.document) { aconto = aconto.document; }
    if (aconto.body != null) {
    if (navigator.userAgent.match(/Android/i)) {
    aconto.body.innerHTML=aconto.body.innerHTML.replace(/\=one_o_five\;\"/g, "=one_o_five; if (navigator.userAgent.match(/Android/i)) { if (parent.document.getElementById('ibelow')) { top.location.href=('' + this.parentNode.href); } }" + '"');
    }

    var igs=aconto.getElementsByTagName('img');
    for (var jigs=0; jigs<igs.length; jigs++) {
    if (igs[jigs].src.indexOf('?rand') != -1) { igs[jigs].src+='' + Math.floor(Math.random() * 456) + '&x=x'; }
    }
    aconto.getElementById('mytable').style.width='100%';
    aconto.getElementById('mytable').style.backgroundColor='rgba(150,120,250,0.5)';
    //aconto.getElementById('mytable').ondblclick=function(){ alert('navigator.userAgent=' + ('' + navigator.userAgent)); };
    }
    }
    }
    }

    … and …
  2. at that relevant WordPress Blog post clicking the main blog post image failed too … and fixed via TwentyTen theme header.php changes …
    <?php echo ”

    var imgi = document.getElementsByTagName('img');
    for (iyt=0; iyt<imgi.length; iyt++) {
    if (navigator.userAgent.match(/Android/i)) {
    if (iyt == 0) {
    document.getElementById('styleandroid').innerHTML='<sty' + "le> .wp-caption-text { text-decoration: underline; } .wp-caption-text::before { content: '\\01F517 '; } </sty" + 'le>';
    }
    if (imgi[iyt].parentElement) {
    if (imgi[iyt].parentNode.href) {
    imgi[iyt].parentNode.ontouchend=function(event){ top.location.href=event.target.href; };
    //imgi[iyt].ontouchstart=function(evt){ top.location.href=evt.target.parentNode.href; };
    }
    }
    }

    altis = imgi[iyt].alt;
    titleis = imgi[iyt].title;
    if (altis == null) {
    if (titleis != null) {
    if (titleis != '') {
    imgi[iyt].alt = titleis;
    }
    }
    } else if (altis == '') {
    if (titleis != null) {
    if (titleis != '') {
    imgi[iyt].alt = titleis;
    }
    }
    }
    }

    “; ?>

… all possible because of this new Xgimi Google Play and Android TV app called “Browser” (you all might be able to see) on today’s animated GIF presentation showing this install process.


Previous relevant Projector Viewing Primer Tutorial is shown below.

Projector Viewing Primer Tutorial

Projector Viewing Primer Tutorial

Are you interested in swapping out a television viewing system of watching entertainment for a projector based one?

We recently acquired an Xgimi projector, and after setting up the projector with a decent screen to project to, found the setting up of streaming applications through Google Play, via, perhaps, a Gmail account, very easy, to the point we got the usual big players there, as well as the crossover to Apple TV via the Apple ID we had, and no need for the Apple TV hardware! It’s all there ready to go with the one Xgimi projector device (and stand, we found useful).

We’re sure it’s a pros and cons decision for you going this way, or not, but we found …

  • people feel less guilty coming and going from the entertainment viewing when there is no one television screen present (and we saw this as a pro)
  • the viewing screen is naturally big, rather than “damaging to the earth” big, as plasma screens can be
  • there are far fewer leads involved
  • only one remote works everything
  • when not watching (and we’d say, even when watching) the projector system it is not there unnecessarily soaking up attention
  • like back in school, some smart Alec, or stupid Alec, or both, might get to say …

    Down in front!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Hardware, Installers, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

XML Lint Validation Shared Encoding Tutorial

XML Lint Validation Shared Encoding Tutorial

XML Lint Validation Shared Encoding Tutorial

There are a lot of web applications we’ve been involved with that …

  1. try to avoid (what we are most “peeved” by, as an issue) gobbledegook when dealing with non-ascii content we try, encoding wise, to corral towards UTF-8 encoding … and today we …
  2. add sharing and collaboration functionality, via email or SMS, to our current XML Lint Validation web application development

… hence the “Shared Encoding” curiosity in our blog posting title … well, you had to be there … today, in the days after yesterday’s XML Lint Validation SelectionChange Tutorial

Fancy a pertinent riddle?

What is always coming but never arrives?

Anyone, anyone?

Yes, Hoagy, do you have an answer?

No Bull Cow No Bull

Well, that’s quite rude and wise all at once, Hoagy! Anybody else? Yes, Edward, your answer …

Rearrange the sycophant!

… has merit too! But wish one of you would enunciate … use your words …
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

You have the answer Tatsumi? Well …

Today

… excellent try! But no, not quite. The answer is …

Tomorrow

But, five points to Hufflepuff, and we add today’s voucher for a cup of tea (no rushing please)!

But, back to business, as far as the encoding issue (of gobbledegook) goes, we mucked around thinking the fault lay with “meta” tags, and such, in the parent, until we relooked at the FileReader arrangements we had going back at a changed client_browsing.htm client side HTML and Javascript inhouse helper. We were always using readAsDataURL() method for this URL call containing “straighttext=” argument pattern, but we found more success starting to use readAsText() method for HTML and XML data inputs. Makes sense really! Now we go


blob.push(file.slice(start, stop + 1));
if (parent.document.getElementById('txtresultout')) {
reader[ij].readAsText(blob[ij]);
} else {
if (document.URL.indexOf('straighttext=') != -1) {
if (window.parent) {
if (parent.document.getElementById('result1') && parent.document.getElementById('result2')) {
reader[ij].readAsText(blob[ij]);
} else {
reader[ij].readAsDataURL(blob[ij]);
}
} else {
reader[ij].readAsDataURL(blob[ij]);
}
} else {

reader[ij].readAsDataURL(blob[ij]);
}
}

as well as


reader[ij].onloadend = (function(mfile) {
return function(evt) {
var dp='', ds=dssuffix, slideshowparent=false, ssuffix='0', nsuffix='2', blnks=' ', xhsf='', zhsfs=[];
var tomt='video/mp4', thext='', ithext=0;
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
if (document.URL.indexOf('straighttext=') != -1) {
if (window.parent) {
if (parent.document.getElementById('result1') && parent.document.getElementById('result2')) {
if (parent.document.getElementById('result1').innerHTML == '') {
parent.document.getElementById('result1').innerHTML=(evt.target.result); // used to use window.atob and .replace('data:application/octet-stream;base64,', '')
} else {
parent.document.getElementById('result2').innerHTML=(evt.target.result); // retest earth_scanner.html
}
}
}
}

// rest of FileReader.DONE code follows
} };
})(files[ij]);

… as a solution to this issue, putting a smile to many an emoji out there.

And as far as our email or SMS sharing goes, we avoided any need for PHP mail ideas by starting to involve hashtagged versions of the incoming XML or HTML input to the XML Lint validator …

<?php echo ”

var ihemail='', ihsms='';

function dohash(isfort) {
//alert('' + isfort);
if (!isfort || 8 == 8) {
var urlis=document.URL.split('?')[0].split('#')[0];
if (('' + document.getElementById('myform').action).indexOf('#') != -1) {
//alert('#' + ('' + document.getElementById('myform').action).split('#')[1]);
document.getElementById('ihid').value='' + ('' + document.getElementById('myform').action).split('#')[1];
document.getElementById('ihid').name='browsecontents';
urlis+='?browsecontents=' + encodeURIComponent(('' + document.getElementById('myform').action).split('#')[1]) + '&' + document.getElementById('myhxfile').name + '=' + encodeURIComponent(document.getElementById('myhxfile').value.replace(/\#/g,'')) + '#' + ('' + document.getElementById('myform').action).split('#')[1] + '&contents=' + encodeURIComponent(document.getElementById('incoming').value);
} else {
//alert('bC = ' + bc);
urlis+='?' + document.getElementById('myhxfile').name + '=' + encodeURIComponent(document.getElementById('myhxfile').value.replace(/\#/g,'')) + '#contents=' + encodeURIComponent(document.getElementById('incoming').value);
}
//alert(urlis);
if (!window.opener || ('' + document.referrer) == '') {
//alert('dref=' + document.referrer + ' urlis=' + urlis);
document.body.style.cursor='progress';
woois=window.open(urlis, '_blank');
} //else {
//alert('top' + document.referrer);
//}
if (1 == 1) {
document.getElementById('myform').target='myif';
ihsms=document.getElementById('dsms').innerHTML;
ihemail=document.getElementById('demail').innerHTML;
document.getElementById('myif').style.position='absolute';
document.getElementById('myif').style.top='0px';
document.getElementById('myif').style.left='0px';
document.getElementById('myif').style.width='100%';
document.getElementById('myif').style.height='100%';
document.getElementById('myif').style.zIndex='100';
document.getElementById('myif').style.display='block';
return true;
} else {
location.href=urlis;
}
return isfort; //false;
}
//alert(87);
return true;
}

function doemail() {
}

function dosms() {
if (document.getElementById('asms').href.indexOf('sms:&') != -1) {
document.getElementById('asms').href=document.getElementById('asms').href.replace('sms:&', 'sms:' + ('' + prompt('Please enter SMS number', '')).replace(/^null/g,'') + '&');
if (document.getElementById('asms').href.indexOf('sms:&') == -1) {
document.getElementById('asms').click();
}
}
}

function checkmyif(iois) {
if (iois != null) {
paconto = (iois.contentWindow || iois.contentDocument);
if (paconto != null) {
if (paconto.document) { paconto = paconto.document; }
if (paconto.body != null && (iois.src.indexOf('?') != -1 || iois.src.indexOf('#') != -1 || ihemail != '')) {
if (('' + document.referrer) == '') {
paconto.body.style.cursor='progress';
}
if (document.getElementById('demail')) {
//alert(document.getElementById('demail').innerHTML);
if (('' + document.referrer) == '') {
paconto.body.style.cursor='progress';
}
if (ihemail != '') {
paconto.document.getElementById('demail').innerHTML=ihemail;
} else {
paconto.document.getElementById('demail').innerHTML=document.getElementById('demail').innerHTML;
}
paconto.document.getElementById('demail').style.display='inline-block';
}
if (document.getElementById('dsms')) {
if (ihsms != '') {
paconto.document.getElementById('demail').innerHTML=ihsms;
} else {
paconto.document.getElementById('dsms').innerHTML=document.getElementById('dsms').innerHTML;
}
paconto.document.getElementById('dsms').style.display='inline-block';
}
}
}
}
}

function maybeshow() {
if (document.getElementById('incoming').value != '') {
var wwoo=window.open('','_blank','top=50,left=50,width=900,height=900');
if (document.getElementById('myhxfile').value != '') {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>' + document.getElementById('myhxfile').value + '</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
} else if (document.getElementById('myhxfile').placeholder.indexOf('Please ') == -1) {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>' + document.getElementById('myhxfile').placeholder + '</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
} else {
wwoo.document.write('<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>XML Lint Validation incoming XML or HTML</title></head><body><textarea style=width:100%;height:100%;>' + document.getElementById('incoming').value + '</textarea></body></html>');
}
}
}

“; ?>

… called into play via “a wrapped” HTML form onsubmit event call change

<?php

<form accept-charset="UTF-8" onsubmit=" if (document.getElementById('myhxfile').value == '') { document.getElementById('myhxfile').name='xx'; } return dohash(true);" action=./xmllint_validation.php<?php echo $bc; ?> id=myform method=POST target=_self>

?>

… in our changed “fifth draft” xmllint_validation.php you might want to try for yourself.

Happy sharing!


Previous relevant XML Lint Validation SelectionChange Tutorial is shown below.

XML Lint Validation SelectionChange Tutorial

XML Lint Validation SelectionChange Tutorial

Onto yesterday’s XML Lint Validation Onclick Tutorial‘s …

  • left hand cell hosted pair of textarea element onclick (and ondblclick) event logics … today we think a user could benefit from …
  • right hand cell hosted textarea element SelectionChange (keyboard related) event triggered via the user highlighting that textarea text (containing errors) of interest

… via …

<?php echo ”

var thesel='', reng='';

function prereverseengineer() {
var wasreng=reng;
reng='';
reverseengineer(wasreng);
}

function reverseengineer(what) {
var oury2=0, nexty2=0;
var theheight=eval(eval('' + s2rect.height) / rowseq);
var codelines=s2.value.split(String.fromCharCode(10));
var errdetail='', ierr=0, linenum=0, nums=[];
thergb=redrgb;
var bimg='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)';
var suff=', white)';

if (what.trim() != '') {
nums=what.split(',');
}
if (eval('' + nums.length) > 0) {
window.scrollTo(0,0);
s1.title='' + nums[0]; // + linenum;
s2.title='' + codelines[eval(-1 + eval('' + nums[0]))];
//alert(what);
oury2=eval(eval(-1 + eval('' + nums[0])) * theheight);
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
for (ierr=1; ierr<nums.length; ierr++) {
oury2=eval(eval(-1 + eval('' + nums[ierr])) * theheight);
//bimg+=thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, '; // + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
s1.title+=String.fromCharCode(10) + '' + nums[ierr]; // + linenum;
s2.title+=String.fromCharCode(10) + '' + codelines[eval(-1 + eval('' + nums[ierr]))];
}
if (bimg.indexOf(suff) == -1) { bimg+=suff.substring(1); }
s1.style.backgroundImage='' + bimg;
s2.style.backgroundImage='' + bimg;
document.getElementById('outgoing').title='Highlighted to left are codelines ' + what + ' with errors';
}
}

function decorateleft() {
var jerr=0;
reng=''
if (ourdelim == ':') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].trim() != '') {
if (ourfindsare[jerr].substring(0,1) >= '0' && ourfindsare[jerr].substring(0,1) <= '9') {
if (ourfindsare[jerr].slice(-1) >= '0' && ourfindsare[jerr].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr]; } else { reng+=',' + ourfindsare[jerr]; }
}
}
}
}
}
} else if (ourdelim.trim() != '') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].split(':')[0].trim() != '') {
if (ourfindsare[jerr].split(':')[0].substring(0,1) >= '0' && ourfindsare[jerr].split(':')[0].substring(0,1) <= '9') {
if (ourfindsare[jerr].split(':')[0].slice(-1) >= '0' && ourfindsare[jerr].split(':')[0].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr].split(':')[0]; } else { reng+=',' + ourfindsare[jerr].split(':')[0]; }
}
}
}
}
}
}
if (reng != '') {
setTimeout(prereverseengineer, 9000); // reverseengineer(reng);
}
}

function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
//document.title=(('' + activeElement.id) + activeElement.outerHTML.substring(0,23));
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0 && ('' + activeElement.id) == 'outgoing') {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
ourdelim=':';
ourfindsare=[];
thesel='';
// Do something with your range
if (eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
if (thesel.trim() != '' && thesel.indexOf(':') != -1) {
var floc=thesel.split(':')[0];
if (tfis != '') {
if (eval('' + floc.length) >= eval('' + tfis.length)) {
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
} else {
thesel=thesel.replace(':', tfis + ':');
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
}
} else {
ourfindsare=thesel.split(ourdelim);
}
decorateleft();
}
}
}
}

document.addEventListener('selectionchange', handleSelection);

“; ?>

… in our changed “fourth draft” xmllint_validation.php you might want to try for yourself.


Previous relevant XML Lint Validation Onclick Tutorial is shown below.

XML Lint Validation Onclick Tutorial

XML Lint Validation Onclick Tutorial

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.

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

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 &lt; and > is mapped to &gt; … 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.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Google WiFi Mesh LAN Subnet Google Home Tutorial

Google WiFi Mesh LAN Subnet Google Home Tutorial

Google WiFi Mesh LAN Subnet Google Home Tutorial

Since the Google WiFi Mesh Networking Primer Tutorial‘s talk about Google Wifi Mesh networks, well, we stopped worrying about it, we’re guessing, because the product is really good.

Recently though, we’ve got it back into our thinking, not that we pretend to have great expertise on the intricacies of home WiFi networks, just an interest in them serving the purpose of providing speedy and timely connectivity. This new home networking setup involved …

… which begs the questions (for us)

What are the benefits of a LAN connected Google WiFi Mesh subnetwork?
Why does Google Wifi have 2 Ethernet ports?
What is the difference between WAN and LAN ports on Google WiFi?
What can Google Home help setup on a home network?

The end result of this setup was we see two WiFi broadband based networks on our list of networks we can connect to, and the network appears to perform better, as you’d be wanting to be the case.


Previous relevant Google WiFi Mesh Networking Primer Tutorial is shown below.

Google WiFi Mesh Networking Primer Tutorial

Google WiFi Mesh Networking Primer Tutorial

Do you remember when we discussed WiFi mesh networks when we presented Mesh Networking Primer Tutorial? Well, we changed our in-house WiFi arrangements (from the use of a WiFi Router Extender, when we presented Home Network Wireless Wi-Fi Router Extender Tutorial) here at RJM Programming, thanks team. We’ve installed a Google WiFi mesh network we’ve noticed has improved all of …

  • Extended range of good connections around the building
  • Faster response time on the net
  • Faster download and upload test results (you can test for yourself at the Google WiFi mobile app, as required)

We hasten to add here, this did not involve changes to NBN (here in Australia), and so nothing getting to the building has changed, and the NBN router at the top of the building remains as the conduit to the internet. That, quite patently, is not the end of the story regarding getting an overall good result with your online connection speed and productivity. You can improve the in-house network design in multiples of efficiency, we can certainly state after a day of non-buffering and no dropouts on Netflix and Stan in any room of the building. It costs, of course, but hardware is rarely free, and the installation support from Google is excellent, and the Google WiFi “meshers” are kind of cute, even cuter than Godzilla’s nemeses wouldn’t you say?!


Previous relevant Mesh Networking Primer Tutorial is shown below.

Mesh Networking Primer Tutorial

Mesh Networking Primer Tutorial

Here, in Australia, a lot of us are turning our attention to the impacts of the National Broadband Network we are currently undertaking. With this in mind, attention goes towards improving the internal WiFi systems of the residence in question.

And that is where the concept of “mesh networking” comes to the fore. Before we go on, though, we cannot pretend to know more than PC & Tech Authority’s April, 2018 edition’s “Mesh Networking … Your Questions Answered” shows and answers. There they road test the following “mesh networking” systems …

  • Asus Lyra
  • Devolo GigaGate
  • Google WiFi
  • Linksys Velop
  • Netgear Orbi
  • TP-Link Deco M5
  • Ubiquiti AmpliFi HD

… so will leave you to read their article to get those road test results. But this may be “jumping the gun” for many of us. Let’s define, all thanks to PC & Tech Authority’s April, 2018 edition’s “Mesh Networking … Your Questions Answered”

What is “mesh networking”?

“Mesh networking” has the same basic principle as wireless repeaters or extenders (which we have one of in our 9 room house, presently, and as you can read about at Home Network Wireless Wi-Fi Router Extender Tutorial) that sit in rooms a bit away from the router in the WiFi Wireless network within your residence. These wireless repeaters piggyback on the existing wireless network, but “mesh networking” use private radio channels (backhauls) to …

  • create better performance on public network
  • have less contention
  • not standalone like extenders, but form multiple nodes helped out by neighbours rather than needing that connection back to base … and so …
  • easier to extend over larger areas
How much is “mesh networking” going to cost me here in Australia?

Depending on how many nodes, say if it was 2-3 nodes, the price would probably be in the range A$200 to A$650.

Does a “mesh networking” replace existing routers?

Mostly, yes, but doesn’t have to if the router can be switched into modem mode or bridge mode. Obviously if “mesh network” is set up to replace an existing router then you need to have at hand that router’s admin username and password(s) before trying to reconfigure anything.

What coverage per node should you expect with most “mesh networking” systems?

Two or three nodes can often cover 400m2 but this is a bit determinant on the position of fridges and walls.

Are the speedier more expensive “mesh networking” systems overkill?

If an Internet connection of 40Mbits/sec suits your purposes, just about all the products will work for that. “Mesh networking”, though, could well be an investment for the future requirements.

Is it easy to set up “mesh networking”?

Most have a smartphone app to help. The “mesh networking” nodes often talk back to the smartphone app via bluetooth to help the setup also.

Want to do your research online? You could do worse than read Wikipedia’s Wireless Mesh Network webpage, thanks.

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.

Posted in eLearning, Hardware, Installers, iOS, Networking, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

XML Lint Validation SelectionChange Tutorial

XML Lint Validation SelectionChange Tutorial

XML Lint Validation SelectionChange Tutorial

Onto yesterday’s XML Lint Validation Onclick Tutorial‘s …

  • left hand cell hosted pair of textarea element onclick (and ondblclick) event logics … today we think a user could benefit from …
  • right hand cell hosted textarea element SelectionChange (keyboard related) event triggered via the user highlighting that textarea text (containing errors) of interest

… via …

<?php echo ”

var thesel='', reng='';

function prereverseengineer() {
var wasreng=reng;
reng='';
reverseengineer(wasreng);
}

function reverseengineer(what) {
var oury2=0, nexty2=0;
var theheight=eval(eval('' + s2rect.height) / rowseq);
var codelines=s2.value.split(String.fromCharCode(10));
var errdetail='', ierr=0, linenum=0, nums=[];
thergb=redrgb;
var bimg='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)';
var suff=', white)';

if (what.trim() != '') {
nums=what.split(',');
}
if (eval('' + nums.length) > 0) {
window.scrollTo(0,0);
s1.title='' + nums[0]; // + linenum;
s2.title='' + codelines[eval(-1 + eval('' + nums[0]))];
//alert(what);
oury2=eval(eval(-1 + eval('' + nums[0])) * theheight);
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
for (ierr=1; ierr<nums.length; ierr++) {
oury2=eval(eval(-1 + eval('' + nums[ierr])) * theheight);
//bimg+=thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, '; // + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
bimg+=' white ' + oury2 + 'px, ' + thergb + ' ' + oury2 + 'px, ' + thergb + ' ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, white ' + eval(oury2 + eval('' + s1rect.height) / rowseq) + 'px, ';
s1.title+=String.fromCharCode(10) + '' + nums[ierr]; // + linenum;
s2.title+=String.fromCharCode(10) + '' + codelines[eval(-1 + eval('' + nums[ierr]))];
}
if (bimg.indexOf(suff) == -1) { bimg+=suff.substring(1); }
s1.style.backgroundImage='' + bimg;
s2.style.backgroundImage='' + bimg;
document.getElementById('outgoing').title='Highlighted to left are codelines ' + what + ' with errors';
}
}

function decorateleft() {
var jerr=0;
reng=''
if (ourdelim == ':') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].trim() != '') {
if (ourfindsare[jerr].substring(0,1) >= '0' && ourfindsare[jerr].substring(0,1) <= '9') {
if (ourfindsare[jerr].slice(-1) >= '0' && ourfindsare[jerr].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr]; } else { reng+=',' + ourfindsare[jerr]; }
}
}
}
}
}
} else if (ourdelim.trim() != '') {
for (jerr=1; jerr<ourfindsare.length; jerr++) {
if (ourfindsare[jerr].split(':')[0].trim() != '') {
if (ourfindsare[jerr].split(':')[0].substring(0,1) >= '0' && ourfindsare[jerr].split(':')[0].substring(0,1) <= '9') {
if (ourfindsare[jerr].split(':')[0].slice(-1) >= '0' && ourfindsare[jerr].split(':')[0].slice(-1) <= '9') {
if ((',' + reng + ',').indexOf(',' + ourfindsare[jerr].split(':')[0] + ',') == -1) {
if (reng == '') { reng=ourfindsare[jerr].split(':')[0]; } else { reng+=',' + ourfindsare[jerr].split(':')[0]; }
}
}
}
}
}
}
if (reng != '') {
setTimeout(prereverseengineer, 9000); // reverseengineer(reng);
}
}

function handleSelection() { // thanks to https://stackoverflow.com/questions/46651479/reacting-to-selection-changes-in-an-html-textarea
const activeElement = document.activeElement;

// Make sure this is your textarea
//document.title=(('' + activeElement.id) + activeElement.outerHTML.substring(0,23));
if (activeElement && activeElement.outerHTML.indexOf('<textarea') == 0 && ('' + activeElement.id) == 'outgoing') {
const range = {
start: activeElement.selectionStart,
end: activeElement.selectionEnd
};
ourdelim=':';
ourfindsare=[];
thesel='';
// Do something with your range
if (eval('' + range.end) > eval('' + range.start)) {
thesel=(activeElement.value.substring(range.start).substring(0, eval(eval('' + range.end) - eval('' + range.start) )));
if (thesel.trim() != '' && thesel.indexOf(':') != -1) {
var floc=thesel.split(':')[0];
if (tfis != '') {
if (eval('' + floc.length) >= eval('' + tfis.length)) {
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
} else {
thesel=thesel.replace(':', tfis + ':');
ourdelim=tfis + ':';
ourfindsare=thesel.split(ourdelim);
}
} else {
ourfindsare=thesel.split(ourdelim);
}
decorateleft();
}
}
}
}

document.addEventListener('selectionchange', handleSelection);

“; ?>

… in our changed “fourth draft” xmllint_validation.php you might want to try for yourself.


Previous relevant XML Lint Validation Onclick Tutorial is shown below.

XML Lint Validation Onclick Tutorial

XML Lint Validation Onclick Tutorial

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.

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

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 &lt; and > is mapped to &gt; … 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.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

XML Lint Validation Onclick Tutorial

XML Lint Validation Onclick Tutorial

XML Lint Validation Onclick Tutorial

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.

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

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 &lt; and > is mapped to &gt; … 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.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

XML Lint Validation Browsing Tutorial

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 in 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 &lt; and > is mapped to &gt; … 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.

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.

Posted in eLearning, Event-Driven Programming, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

XML Lint Validation Tutorial

XML Lint Validation Tutorial

XML Lint Validation Tutorial

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 …
    1. side by side
    2. 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 …
    3. the left hand textarea contains code line numbers right aligned … to sidle up next to …
    4. 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 …

  1. textarea elements are resizeable
  2. you can simulate “some cockpit action” aligning them vertically … Jim?!


Previous relevant Sanitizer API Primer Tutorial is shown below.

Sanitizer API Primer Tutorial

Sanitizer API Primer Tutorial

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.

Posted in eLearning, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , | Leave a comment