...

View Full Version : Mapping out a frameset



JohnKrutsch
01-07-2004, 07:13 AM
I need to build a utility that will map out the framesets for any given site. I have most of the logic worked out but the part I need help with seems like a bit too much. I would think that I could use recursion or something like that but it is late and my brain hurts.

Here is what I am toying with. I just can't help but think this is crap code and there has to be an easier way. Consider this:



flen=top.document.frames.length;

str="";
tab=" ";

for(var i=0; i<flen; i++){
//loop through the top frameset and get the names of all of the frames
get_frames(top.document.frames[i]);
}


function get_frames(obj){
str+=obj.name+"\n";
for(var i=0; i<obj.length; i++){
str+=tab+obj.frames[i].name+"\n";
for(var j=0; j<obj.frames[i].frames.length; j++){
str+=tab+tab+obj.frames[i].frames[j].name+"\n";
for(var k=0; k<obj.frames[i].frames[j].frames.length; k++){
str+=tab+tab+tab+obj.frames[i].frames[j].frames[k].name+"\n";
}
}
}
}

alert(str);



As you can imagine I will never know just how many nested framesets there will be on any given site so continuing to nest the for loops seems futile.

All ideas are welcome

Willy Duitt
01-07-2004, 08:12 AM
If it helps here is a Bookmarklet I picked up somewhere that lists frames.
I split it so I could post it without horizonatal scrolling.

javascript:void(frmsP8F=window.frames);
if(frmsP8F.length==0){
alert('No frames.');
}
else{
strK7J=frmsP8F[0].parent.location.href+' has '+window.length+' frames:\n\n';
for(iQ3MA=0;iQ3MA<frmsP8F.length;iQ3MA++){
try{
if(frmsP8FG[iQ3MA].name!=''){
strK7J+=frmsP8FG[iQ3MA].name;
}
else if(frmsP8FG[iQ3MA].id!=''){
strK7J+=frmsP8FG[iQ3MA].id;
}
else{
strK7J+='(no name or id)';
}
strK7J+='\t'+frmsP8F[iQ3MA].document.location.href;
}
catch(e){
strK7J+='(IFRAME???)';
}
strK7J+='\n';
}
alert(strK7J);
}

I hope you find this useful;
.....Willy

JohnKrutsch
01-07-2004, 08:34 AM
Thanks,

Unfortunately that script gives me a lot less information then the one I am using.

I just need to find a way make the script I posted above more dynamic, meaning I don't know how deep the nested loop needs to go and I would rather have the script find that out.

jkd
01-07-2004, 08:36 AM
Not tested, but maybe something like:



function map(ref, indent) {
var str = indent + ref.name + "\n";
if (ref.frames.length > 0) {
for (var i = 0; i < ref.frames.length; i++)
str += map(ref.frames[i], indent + "\t");
}
return str;
}

var frameMap = map(top, "");

JohnKrutsch
01-07-2004, 09:06 AM
By "map out" I mean I need a snapshot of the whole frameset. Currently I am using a right click set up in IE using the MenuEXT registry settings to launch scripts from any web page.

When I run my script right now it yields something like this:



You launched this script from the CONTENTTOOLFRAME frame.

APPLICATION_FRAME
TOPAPPFRAME
TOOLFRAME
LEFTTOOLFRAME
RIGHTTOOLFRAME
TOPTOOLFRAME
CONTENTTOOLFRAME
APPLET_FRAME
hidden
IMAGEFRAME
CHAT_HIDDEN
WIO_HIDDEN


This gives me a basic understanding of how the framesets are setup on this site.

I tried what JKD posted and it gives me the same data without the indents. I need the indents so I can see how the child framesets are nested so I am just trying to work that out now.

glenngv
01-07-2004, 09:14 AM
Nice job, jkd. that works! :thumbsup:
With due respect to your code, I modified it a bit to exclude the topmost window name (if any) and the excess newline (at the start) and tabs.
And the "if (ref.frames.length > 0)" condition is not necessary.


function map(ref, indent) {
var str = (ref!=top)? indent + ref.name + "\n":"";
for (var i = 0; i < ref.frames.length; i++)
str += map(ref.frames[i], (ref!=top)?indent+"\t":"");
return str;
}



JohnKrutsch, the script jkd posted works for me.

jkd
01-07-2004, 09:16 AM
No indents? I'm assuming because due to issues the "\t". Try replacing that with four spaces or something. Or even "----". But if it prints out the window names in order, then the indenting should work too.

JohnKrutsch
01-07-2004, 09:35 AM
Cool, this is just what I needed.

Thank you much gents!

jkd
01-07-2004, 09:37 AM
Originally posted by glenngv
Nice job, jkd. that works! :thumbsup:
With due respect to your code, I modified it a bit to exclude the topmost window name (if any) and the excess newline (at the start) and tabs.
And the "if (ref.frames.length > 0)" condition is not necessary.


Due to the fact that the newline is appended instead of prepended, there should never be a leading newline (if top.name == "", then it may appear that way however). If you're worried about the trailing newline character, you could simply do it this way:



var newlineChar = "\n";
var indentChar = "\t";

function map(ref, indent) {
var str = indent + ref.name + newlineChar;
for (var i = 0; i < ref.frames.length; i++)
str += map(ref.frames[i], indent + indentChar);
return (arguments.callee.caller == arguments.callee) ? str : str.substr(0, str.length-newlineChar.length);
}

var frameMap = map(top, "");


If I initially call map with say, top.frames[1] instead of top, your comparison using top will fail to prevent the excess whitespace. By checking the execution chain using caller, you can see whether or not it is the top-most caller in the recursion tree.


As for that extraneous if statement... LOL. It was the remnant of my generic recursive call block I always start off with, followed by some bottom-factoring and simplification of the statements:


function recur(args) {
if basecase
return value;
else
operate on individual bits, combine values, return combined
}

:D

glenngv
01-07-2004, 10:14 AM
I ran your latest code but it still has that leading newline and tab. I took the resulting screenshots of your code and my version. In my version, even if I initially pass top.frames[0], the structure is still ok.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum