Is there anyway i can unload a page that has been loaded inside an iframe? it likely removing the
windows and loading content from other pages into the div?
I am using iframe on my main screen to call a file left_nav.php
<iframe src='left_nav.php' name='left_nav' class="daemon" scrolling="auto" frameborder='0' height='100%' width="100%"></iframe>
In left_nav functions and methods to load content from other pages like main_title.php
Function created in left_nav.php file below
setEncounter(edate, eid, frname) {
if (eid == active_encounter) return;
if (!eid) edate = '<?php xl('None','e'); ?>';
var str = '<b>' + edate + '</b>';
setDivContent('current_encounter', str);
active_encounter = eid;
encounter_locked=isEncounterLocked(active_encounter);
reloadEncounter(frname);
syncRadios();
var encounter_block = $(parent.Title.document.getElementById('current_encounter_block'));
var encounter = $(parent.Title.document.getElementById('current_encounter'));
var estr = ' <b>' + edate + ' (' + eid + ')</b>';
encounter.html( estr );
encounter_block.show();
}
function loadCurrentEncounterFromTitle() {
top.restoreSession();
top.frames[ parent.left_nav.getEncounterTargetFrame('enc') ].location='../patient_file/encounter/encounter_top.php';
}
function getEncounterTargetFrame( name ) {
var bias = <?php echo $primary_docs[ 'enc' ][ 1 ]?>;
var f = document.forms[0];
var r = 'RTop';
if (f.cb_top.checked) {
if ( bias == 2 ) {
r = 'RTop';
}
}
return r;
}
This is a js script in left_nav to load loadFrame2
function loadFrame2(fname, frame, url) {
var usage = fname.substring(3);
if (active_pid == 0 && usage > '0') {
alert('<?php xl('You must first select or add a visitor.','e') ?>');
return false;
}
if (active_encounter == 0 && usage > '1') {
alert('<?php xl('You must first select or create an encounter.','e') ?>');
return false;
}
if (encounter_locked && usage > '1') {
alert('<?php echo xls('This encounter is locked. No new forms can be added.') ?>');
return false;
}
var f = document.forms[0];
top.restoreSession();
var i = url.indexOf('{PID}');
if (i >= 0) url = url.substring(0,i) + active_pid + url.substring(i+5);
if(f.sel_frame) {
var fi = f.sel_frame.selectedIndex;
if (fi == 1) frame = 'RTop'; else if (fi == 2) frame = 'RBot';
}
if (!f.cb_bot.checked) frame = 'RTop';
top.frames[frame].location = '<?php echo "$web_root/interface/" ?>' + url;
if (frame == 'RTop') topName = fname;
return false;
}
Funtions created in main_title.php file.
function toencounter(rawdata) {
document.getElementById('EncounterHistory').selectedIndex=0;
if(rawdata=='') {
return false;
} else if (rawdata=='New Encounter') {
top.window.parent.left_nav.loadFrame2('nen1','RBot','forms/newpatient/new.php? autoloaded=1&calenc=')
return true;
} else if (rawdata=='Past Encounter List') {
top.window.parent.left_nav.loadFrame2('pel1','RBot','patient_file/history/encounters.php')
return true;
}
var parts = rawdata.split("~");
var enc = parts[0];
var datestr = parts[1];
var f = top.window.parent.left_nav.document.forms[0];
frame = 'RBot';
if (!f.cb_bot.checked) {
frame = 'RTop';
}
parent.left_nav.setEncounter(datestr, enc, frame);
top.frames[frame].location.href = '../patient_file/encounter/encounter_top.php?set_encounter=' + enc;
}
In the last line of code where the new iframe source is set, you're using the href attribute instead of the src. Since iframe does not have an href attribute, that would explain the lack of results.
top.frames[frame].src = '../patient_file/encounter/encounter_top.php?set_encounter=' + enc;
Try changing to that and see if it works.
Related
I am trying to get the output of a iframe B in a page A to a div in Page A. I wrote the following code:
function FuncExec() {
todorNamespace = {};
todorNamespace.nan = true;
todorNamespace.i = 0;
todorNamespace.div = document.getElementById("render_frame");
todorNamespace.iframe = document.getElementById('iframe_exec');
var pathArray = window.location.href.split('/');
var protocol = pathArray[0];
var host = pathArray[2];
var url = 'http://' + host;
var src = url + '?q=exec_command';
// div.appendChild(iframe);
todorNamespace.iframe.setAttribute("src", src);
var interval = setInterval(function() {
myPrint()
}, 200, this);
function myPrint() {
var text;
var body = todorNamespace.iframe.contentDocument.body;
if (body != null) {
text = body.innerHTML;
}
if (text != null) {
var logs = text.split("\n");
}
if (logs != undefined) {
if (logs[todorNamespace.i] != "</pre>NaN"
&& logs[todorNamespace.i] != undefined) {
todorNamespace.div.innerHTML = todorNamespace.div.innerHTML
+ logs[todorNamespace.i] + "</br>";
todorNamespace.i++;
} else if (logs[todorNamespace.i] == "</pre>NaN") {
todorNamespace.div.innerHTML = todorNamespace.div.innerHTML
+ "</pre>";
clearInterval(interval);
} else {
}
}
}
}
The problem is that it prints the first line from the iframe and then dies with error :
Uncaught TypeError: Cannot read property 'body' of null at line 19
I checked with the debugger, but after the second start of the function myPrint() the variables todorNamespace.iframe and todorNamespace.div are becoming null. Why is that happening and can i fix the reading problem?
My Iframe B is a php page, which is printing output at rate 2-3 lines per second that is the php code:
while ( # ob_end_flush () )
;
$proc = popen ( "myBashCommand", 'r' );
echo '<pre>';
while ( ! feof ( $proc ) ) {
echo fread ( $proc, 4096 );
# flush ();
}
echo '</pre>';
# flush ();
echo 'NaN';
Which suggests that I cannot wait until the page is generated once and then print the output, but need it in "real time", hence that iteration with setInterval to get the text from the iframe. Any ideas how to implement it?
I don't have all that much experience with Prototype and I've been working with jQuery to get things working properly on our site found here. Today I've added a jQuery based script for session handling. The problem I'm having is that even though I've gotten so far today in terms of functionality, I can't seem to get the change event fired via jQuery.
I'm using the following code currently, but it isn't working properly (you can test it on the site.. as soon as you change the year using your mouse, the AJAX is triggered and a Make can be selected)...
var yearSelected = jQuery.jStorage.get("yearSelected");
console.log(yearSelected);
// Set the vars...
if ((jQuery("div.amfinder-horizontal td:nth-child(1) select").val() == "0")) {
jQuery("div.amfinder-horizontal td:nth-child(1) select option").each(function() { this.selected = (this.text == "2003"); });
jQuery("div.amfinder-horizontal td:nth-child(1) select").trigger('change');
console.log('Set the year!');
}
The following code is the Prototype script controlling this and I need to fire off the change event, and would love to do it via jQuery if at all possible.
var amFinder = new Class.create();
amFinder.prototype = {
initialize: function(containerId, ajaxUrl, loadingText, isNeedLast, autoSubmit)
{
this.containerId = containerId;
this.ajaxUrl = ajaxUrl;
this.autoSubmit = Number(autoSubmit);
this.loadingText = loadingText;
this.isNeedLast = Number(isNeedLast);
this.selects = new Array();
//possible bug if select order in the HTML will be different
$$('#' + this.containerId + ' select').each(function(select){
select.observe('change', this.onChange.bindAsEventListener(this));
this.selects[this.selects.length] = select;
}.bind(this));
},
onChange: function(event)
{
var select = Event.element(event);
var parentId = select.value;
var dropdownId = 0;
/* should load next element's options only if current is not the last one */
for (var i = 0; i < this.selects.length; i++){
if (this.selects[i].id == select.id && i != this.selects.length-1){
var selectToReload = this.selects[i + 1];
if (selectToReload){
dropdownId = selectToReload.id.substr(selectToReload.id.search('--') + 2);
}
break;
}
}
this.clearAllBelow(select);
if (0 != parentId && dropdownId){
var postData = 'dropdown_id=' + dropdownId + '&parent_id=' + parentId;
new Ajax.Request(this.ajaxUrl, {
method: 'post',
postBody : postData,
evalJSON : 'force',
onLoading: function(){
this.showLoading(selectToReload);
}.bind(this),
onSuccess: function(transport) {
if (transport.responseJSON){
this.clearSelectOptions(selectToReload);
var itemsFound = false;
transport.responseJSON.each(function(item){
itemsFound = true;
var option = document.createElement('option');
option.value = item.value;
option.text = item.label;
option.label = item.label;
$(selectToReload).appendChild(option);
});
if (itemsFound){
$(selectToReload).disabled = false;
}
}
}.bind(this)
});
}
},
isLast: function(select)
{
return (this.selects[this.selects.length-1].id == select.id);
},
isFirst: function(select)
{
return (this.selects[0].id == select.id);
},
clearSelectOptions: function(select)
{
$(select).descendants().each(function(option){
option.remove();
});
},
clearAllBelow: function(select)
{
var startClearing = false;
for (var i = 0; i < this.selects.length; i++){
if (startClearing){
this.clearSelectOptions(this.selects[i]);
$(this.selects[i]).disabled = true;
}
if (this.selects[i].id == select.id){
startClearing = true;
}
}
var type = (((this.isLast(select) && !this.isNeedLast) && select.value > 0) || ((this.isNeedLast) && ((select.value > 0) || (!this.isFirst(select))))) ? 'block' : 'none';
if ('block' == type && this.autoSubmit && this.isLast(select))
{
$$('#' + this.containerId + ' .amfinder-buttons button')[0].form.submit();
} else {
$$('#' + this.containerId + ' .amfinder-buttons')[0].style.display = type;
}
},
showLoading: function(selectToReload)
{
var option = document.createElement('option');
option.value = 0;
option.text = this.loadingText;
option.label = this.loadingText;
$(selectToReload).appendChild(option);
},
};
I had the same problem. Here is solution. When you create : amfinder-horizontal the html goes something like this
<div class="amfinder-horizontal" id="amfinder_5333ffb212b09Container">
...
</div>
Look at id element : amfinder_5333ffb212b09 Container, bold part is also the name of variable that is amfinder object (created from prototype). It's a random name. This is from the extension source :
<?php $finderId = 'amfinder_' . uniqid(); ?>
...
<script type="text/javascript">
var <?php echo $finderId ?> = new amFinder(
'<?php echo $finderId ?>Container',
'<?php echo $this->getAjaxUrl() ?>',
'<?php echo $this->__('Loading...')?>',
'<?php echo Mage::getStoreConfig('amfinder/general/partial_search')?>',
<?php echo intval(Mage::getStoreConfig('amfinder/general/auto_submit')) ?>
);
</script>
So on every page refresh there is different name. var <?php echo $finderId ?>
Steps :
// Find the name for amfinder object.
var objName = jQuery("div.amfinder-horizontal").attr('id').replace('Container','');
// set Value to that select - copied from your code
jQuery("div.amfinder-horizontal td:nth-child(1) select option").each(function() { this.selected = (this.text == "2003"); });
// call the change event of that object
var targetObj = {
target : jQuery("div.amfinder-horizontal td:nth-child(1) select")[0]
};
window[objName].onChange(targetObj);
Hello Auto completion is not working well in my application.When we type a name it displays only a blank list[ Screenshots attached ].
Controller Code
public function list_UserByName($letters)
{
if(strpos($letters, ","))
{
$letters1 = explode(",",$letters);
$lecount = count($letters1);
$letters = $letters1[$lecount-1];
}
$letters = preg_replace("/[^a-z0-9 ]/si","",$letters);
$response=$this->user_model->getAutoUserList($letters);
}
Model Code
public function getAutoUserList($letters)
{
$letters = preg_replace("/[^a-z0-9 ]/si","",$letters);
//AND user_type='C' AND user_status='A'
$query="select * from gm_users where uname Like '%$letters%'";
$result_query =$this->db->query($query);
foreach($result_query->result() as $result)
{
//echo "###".$result."|";
//$pinlevel =$this->functions->get_pinlevel($result->pinLevel);
//echo $result->userId."###".$result->uname." [ ".$pinlevel." ] "."|";
echo $result->userId."###".$result->uname."".$result->address." ".$result->city."|";
}
}
billing.php
<input type="text" autocomplete="off" size="20" name="txtname" id="txtname" onkeyup="ajax_showOptions(this,'getCountriesByLetters',event);" value=""/>
ajax-dynamic-list.js
/************************************************************************************************************
(C) www.dhtmlgoodies.com, April 2006
This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.
Terms of use:
You are free to use this script as long as the copyright message is kept intact. However, you may not
redistribute, sell or repost it without our permission.
Thank you!
www.dhtmlgoodies.com
Alf Magne Kalleland
************************************************************************************************************/
var ajaxBox_offsetX = 25;
var ajaxBox_offsetY = 5;
var ajax_list_externalFile = site_url+'/catalog/list_UserByName'; // Path to external file
var minimumLettersBeforeLookup = 1; // Number of letters entered before a lookup is performed.
var ajax_list_objects = new Array();
var ajax_list_cachedLists = new Array();
var ajax_list_activeInput = false;
var ajax_list_activeItem;
var ajax_list_optionDivFirstItem = false;
var ajax_list_currentLetters = new Array();
var ajax_optionDiv = false;
var ajax_optionDiv_iframe = false;
var ajax_list_MSIE = false;
if(navigator.userAgent.indexOf('MSIE')>=0 && navigator.userAgent.indexOf('Opera')<0)ajax_list_MSIE=true;
var currentListIndex = 0;
function ajax_getTopPos(inputObj)
{
var returnValue = inputObj.offsetTop;
while((inputObj = inputObj.offsetParent) != null){
returnValue += inputObj.offsetTop;
}
return returnValue;
}
function ajax_list_cancelEvent()
{
return false;
}
function ajax_getLeftPos(inputObj)
{
var returnValue = inputObj.offsetLeft;
while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
return returnValue;
}
// Edited
function ajax_option_setValue_bkp(e,inputObj)
{
if(!inputObj)inputObj=this;
var tmpValue = inputObj.innerHTML;
//alert(inputObj.id);
document.getElementById('saleUserId').value=inputObj.id;
if(ajax_list_MSIE)tmpValue = inputObj.innerText;else tmpValue = inputObj.textContent;
if(!tmpValue)tmpValue = inputObj.innerHTML;
val = ajax_list_activeInput.value.split(',');
vals = '';
count = val.length - 1;
for(i=0;i<count;i++)
{
vals = vals + val[i] + ',';
}
ajax_list_activeInput.value = vals + tmpValue;
if(document.getElementById(ajax_list_activeInput.name + '_hidden'))document.getElementById(ajax_list_activeInput.name + '_hidden').value = inputObj.id;
ajax_options_hide();
}
function ajax_option_setValue(e,inputObj)
{
if(!inputObj)inputObj=this;
var tmpValue = inputObj.innerHTML;
//alert(inputObj.id);
document.getElementById('saleUserId').value=inputObj.id;
if(ajax_list_MSIE)tmpValue = inputObj.innerText;else tmpValue = inputObj.textContent;
if(!tmpValue)tmpValue = inputObj.innerHTML;
ajax_list_activeInput.value = tmpValue;
if(document.getElementById(ajax_list_activeInput.name + '_hidden'))document.getElementById(ajax_list_activeInput.name + '_hidden').value = inputObj.id;
ajax_options_hide();
}
function ajax_options_hide()
{
if(ajax_optionDiv)ajax_optionDiv.style.display='none';
if(ajax_optionDiv_iframe)ajax_optionDiv_iframe.style.display='none';
}
function ajax_options_rollOverActiveItem(item,fromKeyBoard)
{
if(ajax_list_activeItem)ajax_list_activeItem.className='optionDiv';
item.className='optionDivSelected';
ajax_list_activeItem = item;
if(fromKeyBoard){
if(ajax_list_activeItem.offsetTop>ajax_optionDiv.offsetHeight){
ajax_optionDiv.scrollTop = ajax_list_activeItem.offsetTop - ajax_optionDiv.offsetHeight + ajax_list_activeItem.offsetHeight + 2 ;
}
if(ajax_list_activeItem.offsetTop<ajax_optionDiv.scrollTop)
{
ajax_optionDiv.scrollTop = 0;
}
}
}
function ajax_option_list_buildList(letters,paramToExternalFile)
{
ajax_optionDiv.innerHTML = '';
ajax_list_activeItem = false;
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length<=1){
ajax_options_hide();
return;
}
ajax_list_optionDivFirstItem = false;
var optionsAdded = false;
for(var no=0;no<ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length;no++){
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()][no].length==0)continue;
optionsAdded = true;
var div = document.createElement('DIV');
var items = ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()][no].split(/###/gi);
if(ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()].length==1 && ajax_list_activeInput.value == items[0]){
ajax_options_hide();
return;
}
div.innerHTML = items[items.length-1];
div.id = items[0];
div.className='optionDiv';
div.onmouseover = function(){ ajax_options_rollOverActiveItem(this,false) }
div.onclick = ajax_option_setValue;
if(!ajax_list_optionDivFirstItem)ajax_list_optionDivFirstItem = div;
ajax_optionDiv.appendChild(div);
}
if(optionsAdded){
ajax_optionDiv.style.display='block';
if(ajax_optionDiv_iframe)ajax_optionDiv_iframe.style.display='';
ajax_options_rollOverActiveItem(ajax_list_optionDivFirstItem,true);
}
}
function ajax_option_list_showContent(ajaxIndex,inputObj,paramToExternalFile,whichIndex)
{
if(whichIndex!=currentListIndex)return;
var letters = inputObj.value;
var content = ajax_list_objects[ajaxIndex].response;
var elements = content.split('|');
//alert(content);
ajax_list_cachedLists[paramToExternalFile][letters.toLowerCase()] = elements;
ajax_option_list_buildList(letters,paramToExternalFile);
}
function ajax_option_resize(inputObj)
{
ajax_optionDiv.style.top = (ajax_getTopPos(inputObj) + inputObj.offsetHeight + ajaxBox_offsetY) + 'px';
ajax_optionDiv.style.left = (ajax_getLeftPos(inputObj) + ajaxBox_offsetX) + 'px';
if(ajax_optionDiv_iframe){
ajax_optionDiv_iframe.style.left = ajax_optionDiv.style.left;
ajax_optionDiv_iframe.style.top = ajax_optionDiv.style.top;
}
}
function ajax_showOptions(inputObj,paramToExternalFile,e)
{
document.getElementById('saleUserId').value='';
if(e.keyCode==13 || e.keyCode==9)return;
if(ajax_list_currentLetters[inputObj.name]==inputObj.value)return;
if(!ajax_list_cachedLists[paramToExternalFile])ajax_list_cachedLists[paramToExternalFile] = new Array();
ajax_list_currentLetters[inputObj.name] = inputObj.value;
if(!ajax_optionDiv){
ajax_optionDiv = document.createElement('DIV');
ajax_optionDiv.id = 'ajax_listOfOptions';
document.body.appendChild(ajax_optionDiv);
if(ajax_list_MSIE){
ajax_optionDiv_iframe = document.createElement('IFRAME');
ajax_optionDiv_iframe.border='0';
ajax_optionDiv_iframe.style.width = ajax_optionDiv.clientWidth + 'px';
ajax_optionDiv_iframe.style.height = ajax_optionDiv.clientHeight + 'px';
ajax_optionDiv_iframe.id = 'ajax_listOfOptions_iframe';
document.body.appendChild(ajax_optionDiv_iframe);
}
var allInputs = document.getElementsByTagName('INPUT');
for(var no=0;no<allInputs.length;no++){
if(!allInputs[no].onkeyup)allInputs[no].onfocus = ajax_options_hide;
}
var allSelects = document.getElementsByTagName('SELECT');
for(var no=0;no<allSelects.length;no++){
allSelects[no].onfocus = ajax_options_hide;
}
var oldonkeydown=document.body.onkeydown;
if(typeof oldonkeydown!='function'){
document.body.onkeydown=ajax_option_keyNavigation;
}else{
document.body.onkeydown=function(){
oldonkeydown();
ajax_option_keyNavigation() ;}
}
var oldonresize=document.body.onresize;
if(typeof oldonresize!='function'){
document.body.onresize=function() {ajax_option_resize(inputObj); };
}else{
document.body.onresize=function(){oldonresize();
ajax_option_resize(inputObj) ;}
}
}
if(inputObj.value.length<minimumLettersBeforeLookup){
ajax_options_hide();
return;
}
ajax_optionDiv.style.top = (ajax_getTopPos(inputObj) + inputObj.offsetHeight + ajaxBox_offsetY) + 'px';
ajax_optionDiv.style.left = (ajax_getLeftPos(inputObj) + ajaxBox_offsetX) + 'px';
if(ajax_optionDiv_iframe){
ajax_optionDiv_iframe.style.left = ajax_optionDiv.style.left;
ajax_optionDiv_iframe.style.top = ajax_optionDiv.style.top;
}
ajax_list_activeInput = inputObj;
ajax_optionDiv.onselectstart = ajax_list_cancelEvent;
currentListIndex++;
if(ajax_list_cachedLists[paramToExternalFile][inputObj.value.toLowerCase()]){
ajax_option_list_buildList(inputObj.value,paramToExternalFile,currentListIndex);
}else{
var tmpIndex=currentListIndex/1;
ajax_optionDiv.innerHTML = '';
var ajaxIndex = ajax_list_objects.length;
ajax_list_objects[ajaxIndex] = new sack();
var search_key = inputObj.value.replace(" ","+");
//search_key1 = search_key.replace(",",",");
var url = ajax_list_externalFile + '/' +search_key;
ajax_list_objects[ajaxIndex].requestFile = url; // Specifying which file to get
ajax_list_objects[ajaxIndex].onCompletion = function(){ ajax_option_list_showContent(ajaxIndex,inputObj,paramToExternalFile,tmpIndex); }; // Specify function that will be executed after file has been found
ajax_list_objects[ajaxIndex].runAJAX(); // Execute AJAX function
}
}
function wordcount(string) {
var a = string.split(/\s+/g); // split the sentence into an array of words
return a.length;
}
function ajax_option_keyNavigation(e)
{
if(document.all)e = event;
if(!ajax_optionDiv)return;
if(ajax_optionDiv.style.display=='none')return;
if(e.keyCode==38){ // Up arrow
if(!ajax_list_activeItem)return;
if(ajax_list_activeItem && !ajax_list_activeItem.previousSibling)return;
ajax_options_rollOverActiveItem(ajax_list_activeItem.previousSibling,true);
}
if(e.keyCode==40){ // Down arrow
if(!ajax_list_activeItem){
ajax_options_rollOverActiveItem(ajax_list_optionDivFirstItem,true);
}else{
if(!ajax_list_activeItem.nextSibling)return;
ajax_options_rollOverActiveItem(ajax_list_activeItem.nextSibling,true);
}
}
/*if(e.keyCode==13 || e.keyCode==9){ // Enter key or tab key
if(ajax_list_activeItem && ajax_list_activeItem.className=='optionDivSelected')ajax_option_setValue(false,ajax_list_activeItem);
if(e.keyCode==13)return false; else return true;
}
if(e.keyCode==27){ // Escape key
ajax_options_hide();
}*/
}
//document.documentElement.onclick = autoHideList;
function autoHideList(e)
{
if(document.all)e = event;
if (e.target) source = e.target;
else if (e.srcElement) source = e.srcElement;
if (source.nodeType == 3) // defeat Safari bug
source = source.parentNode;
if(source.tagName.toLowerCase()!='input' && source.tagName.toLowerCase()!='textarea')ajax_options_hide();
}
Am a beginner in php as well as Codeigniter
Just echo your data in your controller
change
$response=$this->user_model->getAutoUserList($letters);
To
echo $this->user_model->getAutoUserList($letters);
change
onkeyup="ajax_showOptions(this,'getCountriesByLetters',event);
to
onkeyup="ajax_showOptions(this,'list_UserByName',event);
there is a question on this topic on stackoverflow, but an entire different process.
My Codeigniter autocomplete with ajax
We're being asked to host a number of iframe buster scripts on our site - they allow ads which are served from external domains into iframes to expand outside of them into the host page. Our hosting provider's warned us to watch out for security holes in these scripts. Specifically, they say some of them create cross-site scripting holes by allowing a piece of Javascript to be loaded into our site from any URL.
To implement the script, you host an HTML page on your site. I'm looking at an example from the ad provider Atlas. In this case the URL is like http://domain.com/atlas/atlas_rm.htm. That page contains a script tag with src at an external URL, and here's the JS it includes:
var ARMIfbLib = function () {
function documentWrite(htmlString) {
document.write(htmlString);
}
function writeIframeBustingScript() {
var imgSrvPath = getTlDirectoryFromQueryString(getParameterString());
if (imgSrvPath != "") {
var scriptURL = imgSrvPath + getScriptFileName();
ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");
}
}
return {
WriteIframeBustingScript: writeIframeBustingScript,
DocumentWrite: documentWrite
}
}();
function getValueFromDelimitedString(paramKey, delimiter, queryString) {
if (paramKey == "imgSrv")
return getValueFromProperties();
var re = new RegExp(paramKey + "=" + "(.*?)" + "(" + delimiter + "|$)");
var matchArray = queryString.match(re);
if (matchArray == null)
return "";
else
return matchArray[1];
}
function getValueFromProperties() {
var iframename = unescape(self.name);
if (iframename.indexOf("<form") >= 0) {
var params = iframename.split("<input ");
for (var i = 1; i < params.length; i++) {
var parts = params[i].split(" ");
for (var j = 0; j < parts.length; j++) {
var param = parts[j].split("=");
if (param[0].indexOf("name") >= 0 && param[1].indexOf("TL_files_path") >= 0) {
param = parts[j + 1].split("=");
if (param[0].indexOf("value") >= 0) {
var value = param[1].substr(1, param[1].indexOf(">"));
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return unescape(value);
}
}
}
}
}
else if (iframename.indexOf("adparamdelim") >= 0) {
var params = iframename.split("adparamdelim");
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0].indexOf("TL_files_path") >= 0) {
var value = param[1];
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
}
}
}
else if (/^\{.*\}$/.test(iframename)) {
try {
eval('var results = ' + iframename);
var value = results.TL_files_path;
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
} catch (e) {
return "";
}
} else {
var params = iframename.split("&");
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0].indexOf("TL_files_path") >= 0) {
var value = unescape(param[1]);
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
}
}
}
return "";
}
function getTlDirectoryFromQueryString(sLocation) {
var queryVar = getValueFromDelimitedString("imgSrv", "a4edelim", sLocation);
var temp = queryVar.substr(0, queryVar.lastIndexOf("/"));
var tlDir = temp.substr(0, temp.lastIndexOf("/") + 1);
return tlDir;
}
function getDocumentQueryString() {
return window.location.search;
}
function getIframeParameterString() {
var ret = "";
var qs = getDocumentQueryString();
if (qs.length > 0)
ret = qs.substring(1);
return ret;
}
function getScriptParameterString() {
var ret = "";
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var scriptSrc = scripts[i].src;
if (scriptSrc.toLowerCase().indexOf("newiframescript") != -1 && scriptSrc.indexOf("?") != -1) {
ret = scriptSrc.substr(scriptSrc.indexOf("?") + 1);
break;
}
}
return ret;
}
function getParameterString() {
var qs = getIframeParameterString();
if (qs.length > 0 && qs.indexOf("a4edelim") > 0)
return qs;
return getScriptParameterString();
}
function getScriptFileName() {
var armdelim = ",";
var fileName = "ifb.0";
var queryString = getParameterString();
var parmValue = "";
if (queryString.length > 0) {
parmValue = getValueFromDelimitedString("armver", "a4edelim", queryString);
}
if (parmValue.length > 0) {
var fileNames = parmValue.split(armdelim);
for (var i = 0; i < fileNames.length; i++) {
if (fileNames[i].toLowerCase().indexOf("ifb") != -1) {
fileName = fileNames[i];
break;
}
}
}
return fileName + ".js";
}
if (typeof(armTestMode) == "undefined") {
ARMIfbLib.WriteIframeBustingScript();
}
I've spent a couple of hours studying this to try and work out what it's doing, but I've got bogged down in the different function calls. It seems to be grabbing a query string parameter or else a value from the name of an iframe, presumably the iframe the contains the ad.
Can anyone understand what this JS is doing? Does it look fairly safe from a XSS point of view?
=========================================
EDIT
In case useful to anybody else, we mentioned this concern to the providers, and their response was:
The iframe buster page will only work if it is in an iframe
The code in the ftlocal.html file will only work if the domain of the iframe is already the same as the domain of the parent page – So any code would already have access to the parent page anyway
The the JS script creates a dynamically generated script tag in your page.
ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");
If you dig into where scriptURL comes from, it appears to be a parameter passed to window.location.search (the query string).
From what I can see this effectively allows any script to be passed to your page on the query string rendering it vulnerable to DOM XSS, unless it is effectively secured to allow the domain to be set by the frame name in your page. I'd do some testing using your own domains and passing the query string variables that are searched for (the string literals in the JS).
I was using the code from Kejun's Blog .
I want to parse a .lrc (which is basically a lyrics file) so as to get the time variable as well as the string(read lyrics) . I tried out this code and could not seem to get the output .
<html>
<head>
<script src="jquery-1.7.1.js"></script>
<script>
$(document).ready(function () {
$.ajax({
type: "GET",
url: "a.txt",
dataType: "text",
success: function (data) {
parseLyric(data);
}
});
});
var _current_lyric = new Array();
function convertLRCLyric(inf) {
inf += "n";
var lyric = inf.match(/([(d{2}:d{2}(.d{1,2}){0,1})]){1,}W*n|([(d{2}:d{2}:d{2}(.d{1,2}){0,1})]){1,}W*n/ig);
var l_s = '',
l_tt, l_ww, l_i, l_ii;
if (!lyric || !lyric.length) {
return;
}
for (l_i = 0; l_i < lyric.length; l_i++) {
l_tt = lyric[l_i].match(/([d{2}:d{2}(.d{1,2}){0,1}])|([d{2}:d{2}:d{2}(.d{1,2}){0,1}])/ig);
l_ww = lyric[l_i].replace(/[S+]/ig, '').replace(/n{1,}/ig, '');
for (l_ii = 0; l_ii < l_tt.length; l_ii++) {
l_tt[l_ii] = l_tt[l_ii].replace(/[/,'').replace(/]/, '');
if (l_tt[l_ii].search(/d{2}:d{2}:d{2}.d{2}/g) >= 0) {
_current_lyric[l_tt[l_ii].substring(0, l_tt[l_ii].length - 1)] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}:d{2}.d{1}/g) >= 0) {
_current_lyric[l_tt[l_ii]] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}:d{2}/g) >= 0) {
_current_lyric[l_tt[l_ii] + ".0"] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}.d{2}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii].substring(0, l_tt[l_ii].length - 1)] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}.d{1}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii]] = l_ww;
} else if (l_tt[l_ii].search(/d{2}:d{2}/g) >= 0) {
_current_lyric["00:" + l_tt[l_ii] + ".0"] = l_ww;
}
}
}
}
function parseLyric(allText) {
_current_lyric = [];
convertLRCLyric(allText);
var ly = "";
for (var time in _current_lyric) {
ly += time + "--" + _current_lyric[time] + "n";
}
alert(ly);
}
</script>
</head>
<body>
</body>
</html>
But i keep getting a blank alert . Any help would be great . Thanks in advance .
Answer :
Ok so i built my own parser ,Here is the code
var contents = " " ;
function readMultipleFiles(evt) {
//Retrieve all the files from the FileList object
var files = evt.target.files;
if (files) {
for (var i = 0, f; f = files[i]; i++) {
var r = new FileReader();
r.onload = (function (f) {
return function (e) {
contents = e.target.result;
processData(contents);
};
})(f);
r.readAsText(f);
}
} else {
alert("Failed to load files");
}
}
document.getElementById('fileinput').addEventListener('change', readMultipleFiles, false);
var allTextLines = " ";
var lyrics = [];
var tim = [] ;
var line = " ";
// parsing the Lyrics
function processData(allText) { // This will only divide with respect to new lines
allTextLines = allText.split(/\r\n|\n/);
next();
}
function next()
{
for (i=0;i<allTextLines.length;i++)
{
if (allTextLines[i].search(/^(\[)(\d*)(:)(.*)(\])(.*)/i)>=0 )// any line without the prescribed format wont enter this loop
{
line = allTextLines[i].match(/^(\[)(\d*)(:)(.*)(\])(.*)/i);
tim[i] = (parseInt(line[2])*60)+ parseInt(line[4]); // will give seconds
lyrics[i]= line[6] ;//will give lyrics
}
}
}
Code php : with format
public function get_lrc_song($song) {
$lyrics_file = $song ['lyrics_file'];
$json = curlClass::getInstance ( true )->fetchURL ( $lyrics_file );
$content = explode ( "\n", $json );
$regix = "$\][^>]+$";
$result = "";
foreach ( $content as $item ) {
$isHas = preg_match ( $regix, $item, $data );
$dt = str_replace ( "]", "", $data[0] );
if ($dt != ""){
$result .= $dt . "\n";
}
}
echo $result;
}
I've made an plugin related to this which you can find here
There is an tutorial on how to use this and also i think this is most probably the simplest one I've seen while researching about this topic.
there is another lrc-parser for this purpose, I've tried it but, it lack some features like playing on command and other necessary features.
So i made them all
the code looks like this:
//view the tutorial of this usage on https://multimentality.000webhostapp.com/others
var lyricPlayer = {
"set_divval":function(){var all_lyrics = "";var mose;if(lyricPlayer.Mode=="Long"){mose="block"}else if(lyricPlayer.Mode=="Line"){mose="none"}else{alert("mode property: undefined value. lyricPlayer.Mode has two values 'Long' and 'Line'");mose="block"}for(let y=lyricPlayer.countt;y<lyricPlayer.lyrics.length;y++){all_lyrics+=`<span id='lyricsItem_${lyricPlayer.tim[y]}' class='lyricsItem_class' style='display:${mose};'>${lyricPlayer.lyrics[y]}</span>`;lyricPlayer.tmp_count=lyricPlayer.countt;lyricPlayer.main_dict[lyricPlayer.tim[y]]=lyricPlayer.tmp_count;lyricPlayer.tmp_count++;}document.getElementById('lyrics_playerMain').innerHTML=all_lyrics;},
"processData":function(allText){lyricPlayer.allTextLines = allText.split(/\r\n|\n/);lyricPlayer.next();},
"next":function()
{for (i=0;i<lyricPlayer.allTextLines.length;i++){if (lyricPlayer.allTextLines[i].search(/^(\[)(\d*)(:)(.*)(\])(.*)/i)>=0 ){lyricPlayer.line = lyricPlayer.allTextLines[i].match(/^(\[)(\d*)(:)(.*)(\])(.*)/i);lyricPlayer.tim[i] = (parseInt(lyricPlayer.line[2])*60)+ parseInt(lyricPlayer.line[4]);lyricPlayer.lyrics[i]= lyricPlayer.line[6] ;}else{lyricPlayer.countt++;}}lyricPlayer.set_divval();},
"set_scview":function(id){if(lyricPlayer.Mode=="Long"){var classes = document.getElementsByClassName("lyricsItem_class");for(let u=0;u<classes.length;u++){classes[u].style.color=lyricPlayer.Tcolor;}document.getElementById(`lyricsItem_${id}`).style.color=lyricPlayer.Scolor;var element = document.getElementById(`lyricsItem_${id}`);element.scrollIntoView({behavior: 'smooth',block: 'start'});}if(lyricPlayer.Mode=="Line"){var classes = document.getElementsByClassName("lyricsItem_class");
for(let u=0;u<classes.length;u++){
classes[u].style.display="none";
classes[u].style.color=lyricPlayer.Tcolor;}document.getElementById(`lyricsItem_${id}`).style.color=lyricPlayer.Scolor;document.getElementById(`lyricsItem_${id}`).style.display="block";}},
"change_lrc":function(elem){var time = parseInt(elem.currentTime);if(lyricPlayer.main_dict[time]!=undefined){lyricPlayer.set_scview(time)}},
"allTextLines":"",
"lyrics":[],
"tim":[],
"main_dict":{},
"h_lyrics":"",
"countt":0,
"Scolor":"white",
"line":"",
"tmp_count":0,
"Mode":"Long",
"Tcolor":document.getElementById("lyrics_playerMain").style.color,
"setLyrics":function(val){lyricPlayer.h_lyrics=val;lyricPlayer.main_dict={};lyricPlayer.countt=0;lyricPlayer.tim=[];lyricPlayer.lyrics=[];lyricPlayer.allTextLines="";lyricPlayer.processData(lyricPlayer.h_lyrics);lyricPlayer.tmp_count=lyricPlayer.countt;}
}
this works totally fine and perfect