|
var FrameLocator = FrameLocator || {}; |
|
|
|
(function(module) { |
|
|
|
var TAG_TYPE = 'iframe'; |
|
|
|
// Returns the root window that is within the same domain of the given [window_]. |
|
module.getSafeTop = function(window_) { |
|
var child_ = window_; |
|
var parent_ = window_; |
|
|
|
while(true) { |
|
try { |
|
// Attempt to get ancestor (might be cross-domain) |
|
parent_ = module.getParent(child_); |
|
} |
|
catch(e) { |
|
// TODO catch a certain exception? |
|
console.warn(e); |
|
break; |
|
} |
|
|
|
// Have we reached the top? |
|
if (parent_ === null || parent_ === child_) { |
|
break; |
|
} |
|
|
|
// Next. |
|
child_ = parent_; |
|
} |
|
|
|
return parent_; |
|
} |
|
|
|
// Returns all children of a given [window_]. |
|
module.getChildren = function(window_) { |
|
var children = []; |
|
var initialChildren = module.getImmediateChildren(window_); |
|
|
|
initialChildren.forEach(function(child) { |
|
// Add the immediate child |
|
children.push(child); |
|
|
|
// Recursively add the grand(+)children |
|
module.getChildren(child).forEach(function(grandchild){ |
|
children.push(grandchild); |
|
}); |
|
}) |
|
|
|
return children; |
|
} |
|
|
|
// Returns first level of children of a given [window_]. |
|
module.getImmediateChildren = function(window_) { |
|
var elementCollection = window_.document.getElementsByTagName(TAG_TYPE); |
|
var children = []; |
|
|
|
// Map HTMLCollection items to array of window objects |
|
for(var n = 0; n < elementCollection.length; n++) { |
|
children.push(elementCollection.item(n).contentWindow); |
|
} |
|
|
|
return children; |
|
} |
|
|
|
// Returns the immediate parent of the [window_]. |
|
module.getParent = function(window_) { |
|
var parent_ = window_.parent; |
|
|
|
if (parent_ === undefined) { |
|
parent_ = null; // use `null` over `undefined` |
|
} |
|
|
|
return parent_; |
|
} |
|
|
|
// Returns all the siblings of the [window_]. |
|
module.getSiblings = function(window_) { |
|
var parent_ = module.getParent(window_); |
|
|
|
if (parent_) { |
|
return module.getImmediateChildren(parent_); |
|
} |
|
else { |
|
return []; |
|
} |
|
} |
|
|
|
// Returns the child of a given [name] with respect to the provided [window_] |
|
module.findChildrenByName = function(window_, name) { |
|
var children = module.getChildren(window_); |
|
var name_lc = name.toLowerCase(); // make search case insensitive |
|
var matches = []; |
|
|
|
for(var n = 0; n < children.length; n++) { |
|
var child = children[n]; |
|
|
|
if (child.name.toLowerCase() === name_lc) { |
|
matches.push(child); |
|
} |
|
} |
|
|
|
return matches; |
|
} |
|
|
|
// Returns the windows of a given [name] with respect to the safe top of given [window_]. |
|
module.findWindowsByName = function(window_, name) { |
|
var top_ = module.getSafeTop(window_); |
|
return module.findChildrenByName(top_, name); |
|
} |
|
|
|
// Enumerate tree starting from [window_] and print it out all pretty-like |
|
module.printTree = function(window_, level) { |
|
level = level || 0; |
|
|
|
// Construct indentation |
|
var indent = ""; |
|
|
|
for(var n = 0; n < level; n++) { |
|
indent = indent + " "; |
|
} |
|
|
|
// Print this node |
|
console.log(indent + (window_.name || window_.location)); |
|
|
|
// Print children recursively |
|
var children = module.getImmediateChildren(window_); |
|
children.forEach(function(child) { |
|
module.printTree(child, level + 1); |
|
}); |
|
} |
|
|
|
})(FrameLocator); |