// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617/**18* @fileoverview Atoms for frame handling.19*20*/212223goog.provide('bot.frame');2425goog.require('bot');26goog.require('bot.Error');27goog.require('bot.ErrorCode');28goog.require('bot.dom');29goog.require('bot.locators');30goog.require('goog.dom');31goog.require('goog.dom.TagName');323334/**35* @return {!Window} The top window.36*/37bot.frame.defaultContent = function () {38return bot.getWindow().top;39};404142/**43* @return {!Element} The currently active element.44*/45bot.frame.activeElement = function () {46return document.activeElement || document.body;47};484950/**51* Gets the parent frame of the specified frame.52*53* @param {!Window=} opt_root The window get the parent of.54* Defaults to `bot.getWindow()`.55* @return {!Window} The frame if found, self otherwise.56*/57bot.frame.parentFrame = function (opt_root) {58var domWindow = opt_root || bot.getWindow();59return domWindow.parent;60};616263/**64* Returns a reference to the window object corresponding to the given element.65* Note that the element must be a frame or an iframe.66*67* @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame68* element.69* @return {Window} The window reference for the given iframe or frame element.70*/71bot.frame.getFrameWindow = function (element) {72if (bot.frame.isFrame_(element)) {73var frame = /** @type {HTMLFrameElement|HTMLIFrameElement} */ (element);74return goog.dom.getFrameContentWindow(frame);75}76throw new bot.Error(bot.ErrorCode.NO_SUCH_FRAME,77"The given element isn't a frame or an iframe.");78};798081/**82* Returns whether an element is a frame (or iframe).83*84* @param {!Element} element The element to check.85* @return {boolean} Whether the element is a frame (or iframe).86* @private87*/88bot.frame.isFrame_ = function (element) {89return bot.dom.isElement(element, goog.dom.TagName.FRAME) ||90bot.dom.isElement(element, goog.dom.TagName.IFRAME);91};929394/**95* Looks for a frame by its name or id (preferring name over id)96* under the given root. If no frame was found, we look for an97* iframe by name or id.98*99* @param {(string|number)} nameOrId The frame's name, the frame's id, or the100* index of the frame in the containing window.101* @param {!Window=} opt_root The window to perform the search under.102* Defaults to `bot.getWindow()`.103* @return {Window} The window if found, null otherwise.104*/105bot.frame.findFrameByNameOrId = function (nameOrId, opt_root) {106var domWindow = opt_root || bot.getWindow();107108// Lookup frame by name109var numFrames = domWindow.frames.length;110for (var i = 0; i < numFrames; i++) {111var frame = domWindow.frames[i];112var frameElement = frame.frameElement || frame;113if (frameElement.name == nameOrId) {114// This is needed because Safari 4 returns115// an HTMLFrameElement instead of a Window object.116if (frame.document) {117return frame;118} else {119return goog.dom.getFrameContentWindow(frame);120}121}122}123124// Lookup frame by id125var elements = bot.locators.findElements({ id: nameOrId }, domWindow.document);126for (var i = 0; i < elements.length; i++) {127var frameElement = elements[i];128if (frameElement && bot.frame.isFrame_(frameElement)) {129return goog.dom.getFrameContentWindow(frameElement);130}131}132return null;133};134135136/**137* Looks for a frame by its index under the given root.138*139* @param {number} index The frame's index.140* @param {!Window=} opt_root The window to perform141* the search under. Defaults to `bot.getWindow()`.142* @return {Window} The frame if found, null otherwise.143*/144bot.frame.findFrameByIndex = function (index, opt_root) {145var domWindow = opt_root || bot.getWindow();146return domWindow.frames[index] || null;147};148149150/**151* Gets the index of a frame in the given window. Note that the element must152* be a frame or an iframe.153*154* @param {!(HTMLIFrameElement|HTMLFrameElement)} element The iframe or frame155* element.156* @param {!Window=} opt_root The window to perform the search under. Defaults157* to `bot.getWindow()`.158* @return {?number} The index of the frame if found, null otherwise.159*/160bot.frame.getFrameIndex = function (element, opt_root) {161try {162var elementWindow = element.contentWindow;163} catch (e) {164// Happens in IE{7,8} if a frame doesn't have an enclosing frameset.165return null;166}167168if (!bot.frame.isFrame_(element)) {169return null;170}171172var domWindow = opt_root || bot.getWindow();173for (var i = 0; i < domWindow.frames.length; i++) {174if (elementWindow == domWindow.frames[i]) {175return i;176}177}178return null;179};180181182