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