blob: 832350f1deb76fb267ad76bcbecaff41ed738732 [file] [log] [blame]
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
/**
* @fileoverview Atoms for frame handling.
*
*/
goog.provide('bot.frame');
goog.require('bot');
goog.require('bot.Error');
goog.require('bot.ErrorCode');
goog.require('bot.dom');
goog.require('bot.locators');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
/**
* @return {!Window} The top window.
*/
bot.frame.defaultContent = function () {
return bot.getWindow().top;
};
/**
* @return {!Element} The currently active element.
*/
bot.frame.activeElement = function () {
return document.activeElement || document.body;
};
/**
* Gets the parent frame of the specified frame.
*
* @param {!Window=} opt_root The window get the parent of.
* Defaults to `bot.getWindow()`.
* @return {!Window} The frame if found, self otherwise.
*/
bot.frame.parentFrame = function (opt_root) {
var domWindow = opt_root || bot.getWindow();
return domWindow.parent;
};
/**
* Returns a reference to the window object corresponding to the given element.
* Note that the element must be a frame or an iframe.
*
* @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame
* element.
* @return {Window} The window reference for the given iframe or frame element.
*/
bot.frame.getFrameWindow = function (element) {
if (bot.frame.isFrame_(element)) {
var frame = /** @type {HTMLFrameElement|HTMLIFrameElement} */ (element);
return goog.dom.getFrameContentWindow(frame);
}
throw new bot.Error(bot.ErrorCode.NO_SUCH_FRAME,
"The given element isn't a frame or an iframe.");
};
/**
* Returns whether an element is a frame (or iframe).
*
* @param {!Element} element The element to check.
* @return {boolean} Whether the element is a frame (or iframe).
* @private
*/
bot.frame.isFrame_ = function (element) {
return bot.dom.isElement(element, goog.dom.TagName.FRAME) ||
bot.dom.isElement(element, goog.dom.TagName.IFRAME);
};
/**
* Looks for a frame by its name or id (preferring name over id)
* under the given root. If no frame was found, we look for an
* iframe by name or id.
*
* @param {(string|number)} nameOrId The frame's name, the frame's id, or the
* index of the frame in the containing window.
* @param {!Window=} opt_root The window to perform the search under.
* Defaults to `bot.getWindow()`.
* @return {Window} The window if found, null otherwise.
*/
bot.frame.findFrameByNameOrId = function (nameOrId, opt_root) {
var domWindow = opt_root || bot.getWindow();
// Lookup frame by name
var numFrames = domWindow.frames.length;
for (var i = 0; i < numFrames; i++) {
var frame = domWindow.frames[i];
var frameElement = frame.frameElement || frame;
if (frameElement.name == nameOrId) {
// This is needed because Safari 4 returns
// an HTMLFrameElement instead of a Window object.
if (frame.document) {
return frame;
} else {
return goog.dom.getFrameContentWindow(frame);
}
}
}
// Lookup frame by id
var elements = bot.locators.findElements({ id: nameOrId }, domWindow.document);
for (var i = 0; i < elements.length; i++) {
var frameElement = elements[i];
if (frameElement && bot.frame.isFrame_(frameElement)) {
return goog.dom.getFrameContentWindow(frameElement);
}
}
return null;
};
/**
* Looks for a frame by its index under the given root.
*
* @param {number} index The frame's index.
* @param {!Window=} opt_root The window to perform
* the search under. Defaults to `bot.getWindow()`.
* @return {Window} The frame if found, null otherwise.
*/
bot.frame.findFrameByIndex = function (index, opt_root) {
var domWindow = opt_root || bot.getWindow();
return domWindow.frames[index] || null;
};
/**
* Gets the index of a frame in the given window. Note that the element must
* be a frame or an iframe.
*
* @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame
* element.
* @param {!Window=} opt_root The window to perform the search under. Defaults
* to `bot.getWindow()`.
* @return {?number} The index of the frame if found, null otherwise.
*/
bot.frame.getFrameIndex = function (element, opt_root) {
try {
var elementWindow = element.contentWindow;
} catch (e) {
// Happens in IE{7,8} if a frame doesn't have an enclosing frameset.
return null;
}
if (!bot.frame.isFrame_(element)) {
return null;
}
var domWindow = opt_root || bot.getWindow();
for (var i = 0; i < domWindow.frames.length; i++) {
if (elementWindow == domWindow.frames[i]) {
return i;
}
}
return null;
};