// 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; };