From fc9f2bb01c537cb1afc5f781c34af9aeaf9f6207 Mon Sep 17 00:00:00 2001 From: decaffeinate Date: Sat, 15 Dec 2018 23:04:46 -0500 Subject: [PATCH] decaffeinate: Run post-processing cleanups on coordinates.coffee and 7 other files --- packages/driver/src/dom/coordinates.js | 278 ++++++----- packages/driver/src/dom/document.js | 41 +- packages/driver/src/dom/elements.js | 637 ++++++++++++++----------- packages/driver/src/dom/index.js | 38 +- packages/driver/src/dom/jquery.js | 43 +- packages/driver/src/dom/selection.js | 557 +++++++++++---------- packages/driver/src/dom/visibility.js | 287 ++++++----- packages/driver/src/dom/window.js | 43 +- 8 files changed, 1081 insertions(+), 843 deletions(-) diff --git a/packages/driver/src/dom/coordinates.js b/packages/driver/src/dom/coordinates.js index 45a3df7b83d3..90eb73d9a401 100644 --- a/packages/driver/src/dom/coordinates.js +++ b/packages/driver/src/dom/coordinates.js @@ -1,28 +1,35 @@ +/* eslint-disable + default-case, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS205: Consider reworking code to avoid use of IIFEs * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $window = require("./window"); +const $window = require('./window') -const getElementAtPointFromViewport = (doc, x, y) => doc.elementFromPoint(x, y); +const getElementAtPointFromViewport = (doc, x, y) => { + return doc.elementFromPoint(x, y) +} -const getElementPositioning = function($el) { - const el = $el[0]; +const getElementPositioning = function ($el) { + const el = $el[0] - const win = $window.getWindowByElement(el); + const win = $window.getWindowByElement(el) //# properties except for width / height //# are relative to the top left of the viewport - const rect = el.getBoundingClientRect(); + const rect = el.getBoundingClientRect() - const center = getCenterCoordinates(rect); + const center = getCenterCoordinates(rect) //# add the center coordinates //# because its useful to any caller - const topCenter = center.y; - const leftCenter = center.x; + const topCenter = center.y + const leftCenter = center.x return { scrollTop: el.scrollTop, @@ -35,29 +42,33 @@ const getElementPositioning = function($el) { right: rect.right, bottom: rect.bottom, topCenter, - leftCenter + leftCenter, }, fromWindow: { top: rect.top + win.pageYOffset, left: rect.left + win.pageXOffset, topCenter: topCenter + win.pageYOffset, - leftCenter: leftCenter + win.pageXOffset + leftCenter: leftCenter + win.pageXOffset, + }, + } +} + +const getCoordsByPosition = function (left, top, xPosition = 'center', yPosition = 'center') { + left = (() => { + switch (xPosition) { + case 'left': return Math.ceil(left) + case 'center': return Math.floor(left) + case 'right': return Math.floor(left) - 1 + } + })() + + top = (() => { + switch (yPosition) { + case 'top': return Math.ceil(top) + case 'center': return Math.floor(top) + case 'bottom': return Math.floor(top) - 1 } - }; -}; - -const getCoordsByPosition = function(left, top, xPosition = "center", yPosition = "center") { - left = (() => { switch (xPosition) { - case "left": return Math.ceil(left); - case "center": return Math.floor(left); - case "right": return Math.floor(left) - 1; - } })(); - - top = (() => { switch (yPosition) { - case "top": return Math.ceil(top); - case "center": return Math.floor(top); - case "bottom": return Math.floor(top) - 1; - } })(); + })() //# returning x/y here because this is //# about the target position we want @@ -65,104 +76,113 @@ const getCoordsByPosition = function(left, top, xPosition = "center", yPosition //# the desired xPosition and yPosition is return { x: left, - y: top - }; -}; - -const getTopLeftCoordinates = function(rect) { - const x = rect.left; - const y = rect.top; - return getCoordsByPosition(x, y, "left", "top"); -}; - -const getTopCoordinates = function(rect) { - const x = rect.left + (rect.width / 2); - const y = rect.top; - return getCoordsByPosition(x, y, "center", "top"); -}; - -const getTopRightCoordinates = function(rect) { - const x = rect.left + rect.width; - const y = rect.top; - return getCoordsByPosition(x, y, "right", "top"); -}; - -const getLeftCoordinates = function(rect) { - const x = rect.left; - const y = rect.top + (rect.height / 2); - return getCoordsByPosition(x, y, "left", "center"); -}; - -var getCenterCoordinates = function(rect) { - const x = rect.left + (rect.width / 2); - const y = rect.top + (rect.height / 2); - return getCoordsByPosition(x, y, "center", "center"); -}; - -const getRightCoordinates = function(rect) { - const x = rect.left + rect.width; - const y = rect.top + (rect.height / 2); - return getCoordsByPosition(x, y, "right", "center"); -}; - -const getBottomLeftCoordinates = function(rect) { - const x = rect.left; - const y = rect.top + rect.height; - return getCoordsByPosition(x, y, "left", "bottom"); -}; - -const getBottomCoordinates = function(rect) { - const x = rect.left + (rect.width / 2); - const y = rect.top + rect.height; - return getCoordsByPosition(x, y, "center", "bottom"); -}; - -const getBottomRightCoordinates = function(rect) { - const x = rect.left + rect.width; - const y = rect.top + rect.height; - return getCoordsByPosition(x, y, "right", "bottom"); -}; - -const getElementCoordinatesByPositionRelativeToXY = function($el, x, y) { - const positionProps = getElementPositioning($el); - - const { fromViewport, fromWindow } = positionProps; - - fromViewport.left += x; - fromViewport.top += y; - - fromWindow.left += x; - fromWindow.top += y; - - const viewportTargetCoords = getTopLeftCoordinates(fromViewport); - const windowTargetCoords = getTopLeftCoordinates(fromWindow); - - fromViewport.x = viewportTargetCoords.x; - fromViewport.y = viewportTargetCoords.y; - - fromWindow.x = windowTargetCoords.x; - fromWindow.y = windowTargetCoords.y; - - return positionProps; -}; - -const getElementCoordinatesByPosition = function($el, position = "center") { - const positionProps = getElementPositioning($el); + y: top, + } +} + +const getTopLeftCoordinates = function (rect) { + const x = rect.left + const y = rect.top + + return getCoordsByPosition(x, y, 'left', 'top') +} + +const getTopCoordinates = function (rect) { + const x = rect.left + (rect.width / 2) + const y = rect.top + + return getCoordsByPosition(x, y, 'center', 'top') +} + +const getTopRightCoordinates = function (rect) { + const x = rect.left + rect.width + const y = rect.top + + return getCoordsByPosition(x, y, 'right', 'top') +} + +const getLeftCoordinates = function (rect) { + const x = rect.left + const y = rect.top + (rect.height / 2) + + return getCoordsByPosition(x, y, 'left', 'center') +} + +const getCenterCoordinates = function (rect) { + const x = rect.left + (rect.width / 2) + const y = rect.top + (rect.height / 2) + + return getCoordsByPosition(x, y, 'center', 'center') +} + +const getRightCoordinates = function (rect) { + const x = rect.left + rect.width + const y = rect.top + (rect.height / 2) + + return getCoordsByPosition(x, y, 'right', 'center') +} + +const getBottomLeftCoordinates = function (rect) { + const x = rect.left + const y = rect.top + rect.height + + return getCoordsByPosition(x, y, 'left', 'bottom') +} + +const getBottomCoordinates = function (rect) { + const x = rect.left + (rect.width / 2) + const y = rect.top + rect.height + + return getCoordsByPosition(x, y, 'center', 'bottom') +} + +const getBottomRightCoordinates = function (rect) { + const x = rect.left + rect.width + const y = rect.top + rect.height + + return getCoordsByPosition(x, y, 'right', 'bottom') +} + +const getElementCoordinatesByPositionRelativeToXY = function ($el, x, y) { + const positionProps = getElementPositioning($el) + + const { fromViewport, fromWindow } = positionProps + + fromViewport.left += x + fromViewport.top += y + + fromWindow.left += x + fromWindow.top += y + + const viewportTargetCoords = getTopLeftCoordinates(fromViewport) + const windowTargetCoords = getTopLeftCoordinates(fromWindow) + + fromViewport.x = viewportTargetCoords.x + fromViewport.y = viewportTargetCoords.y + + fromWindow.x = windowTargetCoords.x + fromWindow.y = windowTargetCoords.y + + return positionProps +} + +const getElementCoordinatesByPosition = function ($el, position = 'center') { + const positionProps = getElementPositioning($el) //# get the coordinates from the window //# but also from the viewport so //# whoever is calling us can use it //# however they'd like - const { width, height, fromViewport, fromWindow } = positionProps; + const { width, height, fromViewport, fromWindow } = positionProps //# dynamically call the function by transforming the name //# bottom -> getBottomCoordinates //# topLeft -> getTopLeftCoordinates - const capitalizedPosition = position.charAt(0).toUpperCase() + position.slice(1); + const capitalizedPosition = position.charAt(0).toUpperCase() + position.slice(1) - const fnName = `get${capitalizedPosition}Coordinates`; + const fnName = `get${capitalizedPosition}Coordinates` - const fn = calculations[fnName]; + const fn = calculations[fnName] //# get the desired x/y coords based on //# what position we're trying to target @@ -170,8 +190,8 @@ const getElementCoordinatesByPosition = function($el, position = "center") { width, height, top: fromViewport.top, - left: fromViewport.left - }); + left: fromViewport.left, + }) //# get the desired x/y coords based on //# what position we're trying to target @@ -179,14 +199,14 @@ const getElementCoordinatesByPosition = function($el, position = "center") { width, height, top: fromWindow.top, - left: fromWindow.left - }); + left: fromWindow.left, + }) - fromViewport.x = viewportTargetCoords.x; - fromViewport.y = viewportTargetCoords.y; + fromViewport.x = viewportTargetCoords.x + fromViewport.y = viewportTargetCoords.y - fromWindow.x = windowTargetCoords.x; - fromWindow.y = windowTargetCoords.y; + fromWindow.x = windowTargetCoords.x + fromWindow.y = windowTargetCoords.y //# return an object with both sets //# of normalized coordinates for both @@ -195,11 +215,11 @@ const getElementCoordinatesByPosition = function($el, position = "center") { width, height, fromViewport, - fromWindow - }; -}; + fromWindow, + } +} -var calculations = { +const calculations = { getTopCoordinates, getTopLeftCoordinates, getTopRightCoordinates, @@ -208,8 +228,8 @@ var calculations = { getRightCoordinates, getBottomLeftCoordinates, getBottomCoordinates, - getBottomRightCoordinates -}; + getBottomRightCoordinates, +} module.exports = { getCoordsByPosition, @@ -220,5 +240,5 @@ module.exports = { getElementCoordinatesByPosition, - getElementCoordinatesByPositionRelativeToXY -}; + getElementCoordinatesByPositionRelativeToXY, +} diff --git a/packages/driver/src/dom/document.js b/packages/driver/src/dom/document.js index 3b789d6da2f4..3aaf2ae9c125 100644 --- a/packages/driver/src/dom/document.js +++ b/packages/driver/src/dom/document.js @@ -1,41 +1,48 @@ +/* eslint-disable + brace-style, + no-undef, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $jquery = require("./jquery"); +const $jquery = require('./jquery') -const docNode = Node.DOCUMENT_NODE; +const docNode = Node.DOCUMENT_NODE -const isDocument = function(obj) { +const isDocument = function (obj) { try { if ($jquery.isJquery(obj)) { - obj = obj[0]; + obj = obj[0] } - return Boolean(obj && (obj.nodeType === docNode)); + return Boolean(obj && (obj.nodeType === docNode)) } catch (error) { - return false; + return false } -}; +} -const hasActiveWindow = doc => - //# does this document have a currently active window (defaultView) - !!doc.defaultView -; +const hasActiveWindow = (doc) => +//# does this document have a currently active window (defaultView) +{ + return !!doc.defaultView +} -const getDocumentFromElement = function(el) { +const getDocumentFromElement = function (el) { if (isDocument(el)) { - return el; + return el } - return el.ownerDocument; -}; + return el.ownerDocument +} module.exports = { isDocument, hasActiveWindow, - getDocumentFromElement -}; + getDocumentFromElement, +} diff --git a/packages/driver/src/dom/elements.js b/packages/driver/src/dom/elements.js index 7a565f069dce..9723c9b12c82 100644 --- a/packages/driver/src/dom/elements.js +++ b/packages/driver/src/dom/elements.js @@ -1,163 +1,178 @@ +/* eslint-disable + brace-style, + default-case, + no-case-declarations, + no-cond-assign, + no-const-assign, + no-dupe-keys, + no-undef, + no-unused-vars, + one-var, + prefer-rest-params, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const _ = require("lodash"); -const $ = require("jquery"); -const $jquery = require("./jquery"); -const $window = require("./window"); -const $document = require("./document"); -const $utils = require("../cypress/utils"); +const _ = require('lodash') +const $ = require('jquery') +const $jquery = require('./jquery') +const $window = require('./window') +const $document = require('./document') +const $utils = require('../cypress/utils') -const fixedOrStickyRe = /(fixed|sticky)/; +const fixedOrStickyRe = /(fixed|sticky)/ -const focusable = "body,a[href],link[href],button,select,[tabindex],input,textarea,[contenteditable]"; +const focusable = 'body,a[href],link[href],button,select,[tabindex],input,textarea,[contenteditable]' -const inputTypeNeedSingleValueChangeRe = /^(date|time|month|week)$/; -const canSetSelectionRangeElementRe = /^(text|search|URL|tel|password)$/; +const inputTypeNeedSingleValueChangeRe = /^(date|time|month|week)$/ +const canSetSelectionRangeElementRe = /^(text|search|URL|tel|password)$/ //# rules for native methods and props //# if a setter or getter or function then add a native method //# if a traversal, don't -const descriptor = (klass, prop) => Object.getOwnPropertyDescriptor(window[klass].prototype, prop); +const descriptor = (klass, prop) => { + return Object.getOwnPropertyDescriptor(window[klass].prototype, prop) +} -const _getValue = function() { +const _getValue = function () { switch (false) { case !isInput(this): - return descriptor("HTMLInputElement", "value").get; + return descriptor('HTMLInputElement', 'value').get case !isTextarea(this): - return descriptor("HTMLTextAreaElement", "value").get; + return descriptor('HTMLTextAreaElement', 'value').get case !isSelect(this): - return descriptor("HTMLSelectElement", "value").get; + return descriptor('HTMLSelectElement', 'value').get case !isButton(this): - return descriptor("HTMLButtonElement", "value").get; + return descriptor('HTMLButtonElement', 'value').get default: //# is an option element - return descriptor("HTMLOptionElement", "value").get; + return descriptor('HTMLOptionElement', 'value').get } -}; +} -const _setValue = function() { +const _setValue = function () { switch (false) { case !isInput(this): - return descriptor("HTMLInputElement", "value").set; + return descriptor('HTMLInputElement', 'value').set case !isTextarea(this): - return descriptor("HTMLTextAreaElement", "value").set; + return descriptor('HTMLTextAreaElement', 'value').set case !isSelect(this): - return descriptor("HTMLSelectElement", "value").set; + return descriptor('HTMLSelectElement', 'value').set case !isButton(this): - return descriptor("HTMLButtonElement", "value").set; + return descriptor('HTMLButtonElement', 'value').set default: //# is an options element - return descriptor("HTMLOptionElement", "value").set; + return descriptor('HTMLOptionElement', 'value').set } -}; +} -const _getSelectionStart = function() { +const _getSelectionStart = function () { switch (false) { case !isInput(this): - return descriptor('HTMLInputElement', 'selectionStart').get; + return descriptor('HTMLInputElement', 'selectionStart').get case !isTextarea(this): - return descriptor('HTMLTextAreaElement', 'selectionStart').get; + return descriptor('HTMLTextAreaElement', 'selectionStart').get } -}; +} -const _getSelectionEnd = function() { +const _getSelectionEnd = function () { switch (false) { case !isInput(this): - return descriptor('HTMLInputElement', 'selectionEnd').get; + return descriptor('HTMLInputElement', 'selectionEnd').get case !isTextarea(this): - return descriptor('HTMLTextAreaElement', 'selectionEnd').get; + return descriptor('HTMLTextAreaElement', 'selectionEnd').get } -}; +} -const _nativeFocus = function() { +const _nativeFocus = function () { switch (false) { case !$window.isWindow(this): - return window.focus; + return window.focus case !isSvg(this): - return window.SVGElement.prototype.focus; + return window.SVGElement.prototype.focus default: - return window.HTMLElement.prototype.focus; + return window.HTMLElement.prototype.focus } -}; +} -const _nativeBlur = function() { +const _nativeBlur = function () { switch (false) { case !$window.isWindow(this): - return window.blur; + return window.blur case !isSvg(this): - return window.SVGElement.prototype.blur; + return window.SVGElement.prototype.blur default: - return window.HTMLElement.prototype.blur; + return window.HTMLElement.prototype.blur } -}; +} -const _nativeSetSelectionRange = function() { +const _nativeSetSelectionRange = function () { switch (false) { case !isInput(this): - return window.HTMLInputElement.prototype.setSelectionRange; + return window.HTMLInputElement.prototype.setSelectionRange default: //# is textarea - return window.HTMLTextAreaElement.prototype.setSelectionRange; + return window.HTMLTextAreaElement.prototype.setSelectionRange } -}; +} -const _nativeSelect = function() { +const _nativeSelect = function () { switch (false) { case !isInput(this): - return window.HTMLInputElement.prototype.select; + return window.HTMLInputElement.prototype.select default: //# is textarea - return window.HTMLTextAreaElement.prototype.select; + return window.HTMLTextAreaElement.prototype.select } -}; +} -const _isContentEditable = function() { +const _isContentEditable = function () { switch (false) { case !isSvg(this): - return false; + return false default: - return descriptor("HTMLElement", "isContentEditable").get; + return descriptor('HTMLElement', 'isContentEditable').get } -}; +} -const _setType = function() { +const _setType = function () { switch (false) { case !isInput(this): - return descriptor("HTMLInputElement", "type").set; + return descriptor('HTMLInputElement', 'type').set case !isButton(this): - return descriptor("HTMLButtonElement", "type").set; + return descriptor('HTMLButtonElement', 'type').set } -}; +} - -const _getType = function() { +const _getType = function () { switch (false) { case !isInput(this): - return descriptor("HTMLInputElement", "type").get; + return descriptor('HTMLInputElement', 'type').get case !isButton(this): - return descriptor("HTMLButtonElement", "type").get; + return descriptor('HTMLButtonElement', 'type').get } -}; +} const nativeGetters = { value: _getValue, - selectionStart: descriptor("HTMLInputElement", "selectionStart").get, + selectionStart: descriptor('HTMLInputElement', 'selectionStart').get, isContentEditable: _isContentEditable, - isCollapsed: descriptor("Selection", 'isCollapsed').get, + isCollapsed: descriptor('Selection', 'isCollapsed').get, selectionStart: _getSelectionStart, selectionEnd: _getSelectionEnd, - type: _getType -}; + type: _getType, +} const nativeSetters = { value: _setValue, - type: _setType -}; + type: _setType, +} const nativeMethods = { addEventListener: window.EventTarget.prototype.addEventListener, @@ -172,152 +187,184 @@ const nativeMethods = { modify: window.Selection.prototype.modify, focus: _nativeFocus, blur: _nativeBlur, - select: _nativeSelect -}; + select: _nativeSelect, +} -const tryCallNativeMethod = function() { +const tryCallNativeMethod = function () { try { - return callNativeMethod.apply(null, arguments); + return callNativeMethod(...arguments) } catch (err) { - return; + return } -}; +} + +const callNativeMethod = function (obj, fn, ...args) { + let nativeFn -var callNativeMethod = function(obj, fn, ...args) { - let nativeFn; if (!(nativeFn = nativeMethods[fn])) { - const fns = _.keys(nativeMethods).join(", "); - throw new Error(`attempted to use a native fn called: ${fn}. Available fns are: ${fns}`); + const fns = _.keys(nativeMethods).join(', ') + + throw new Error(`attempted to use a native fn called: ${fn}. Available fns are: ${fns}`) } - let retFn = nativeFn.apply(obj, args); + let retFn = nativeFn.apply(obj, args) if (_.isFunction(retFn)) { - retFn = retFn.apply(obj, args); + retFn = retFn.apply(obj, args) } - return retFn; -}; + return retFn +} + +const getNativeProp = function (obj, prop) { + let nativeProp -const getNativeProp = function(obj, prop) { - let nativeProp; if (!(nativeProp = nativeGetters[prop])) { - const props = _.keys(nativeGetters).join(", "); - throw new Error(`attempted to use a native getter prop called: ${prop}. Available props are: ${props}`); + const props = _.keys(nativeGetters).join(', ') + + throw new Error(`attempted to use a native getter prop called: ${prop}. Available props are: ${props}`) } - let retProp = nativeProp.call(obj, prop); + let retProp = nativeProp.call(obj, prop) if (_.isFunction(retProp)) { //# if we got back another function //# then invoke it again - retProp = retProp.call(obj, prop); + retProp = retProp.call(obj, prop) } - return retProp; -}; + return retProp +} + +const setNativeProp = function (obj, prop, val) { + let nativeProp -const setNativeProp = function(obj, prop, val) { - let nativeProp; if (!(nativeProp = nativeSetters[prop])) { - const fns = _.keys(nativeSetters).join(", "); - throw new Error(`attempted to use a native setter prop called: ${fn}. Available props are: ${fns}`); + const fns = _.keys(nativeSetters).join(', ') + + throw new Error(`attempted to use a native setter prop called: ${fn}. Available props are: ${fns}`) } - let retProp = nativeProp.call(obj, val); + let retProp = nativeProp.call(obj, val) if (_.isFunction(retProp)) { - retProp = retProp.call(obj, val); + retProp = retProp.call(obj, val) } - return retProp; -}; + return retProp +} -const isNeedSingleValueChangeInputElement = function(el) { +const isNeedSingleValueChangeInputElement = function (el) { if (!isInput(el)) { - return false; + return false } - return inputTypeNeedSingleValueChangeRe.test(el.type); -}; + return inputTypeNeedSingleValueChangeRe.test(el.type) +} -const canSetSelectionRangeElement = el => isTextarea(el) || (isInput(el) && canSetSelectionRangeElementRe.test(getNativeProp(el, 'type'))); +const canSetSelectionRangeElement = (el) => { + return isTextarea(el) || (isInput(el) && canSetSelectionRangeElementRe.test(getNativeProp(el, 'type'))) +} -const getTagName = function(el) { - const tagName = el.tagName || ""; - return tagName.toLowerCase(); -}; +const getTagName = function (el) { + const tagName = el.tagName || '' -const isContentEditable = el => - //# this property is the tell-all for contenteditable - //# should be true for elements: - //# - with [contenteditable] - //# - with document.designMode = 'on' - getNativeProp(el, "isContentEditable") -; + return tagName.toLowerCase() +} -var isTextarea = el => getTagName(el) === 'textarea'; +const isContentEditable = (el) => +//# this property is the tell-all for contenteditable +//# should be true for elements: +//# - with [contenteditable] +//# - with document.designMode = 'on' +{ + return getNativeProp(el, 'isContentEditable') +} -var isInput = el => getTagName(el) === 'input'; +const isTextarea = (el) => { + return getTagName(el) === 'textarea' +} -var isButton = el => getTagName(el) === 'button'; +const isInput = (el) => { + return getTagName(el) === 'input' +} -var isSelect = el => getTagName(el) === 'select'; +const isButton = (el) => { + return getTagName(el) === 'button' +} -const isOption = el => getTagName(el) === 'option'; +const isSelect = (el) => { + return getTagName(el) === 'select' +} -const isBody = el => getTagName(el) === 'body'; +const isOption = (el) => { + return getTagName(el) === 'option' +} -var isSvg = function(el) { +const isBody = (el) => { + return getTagName(el) === 'body' +} + +const isSvg = function (el) { try { - return "ownerSVGElement" in el; + return 'ownerSVGElement' in el } catch (error) { - return false; + return false } -}; +} -const isElement = function(obj) { +const isElement = function (obj) { try { if ($jquery.isJquery(obj)) { - obj = obj[0]; + obj = obj[0] } - return Boolean(obj && _.isElement(obj)); + return Boolean(obj && _.isElement(obj)) } catch (error) { - return false; + return false } -}; +} -const isFocusable = $el => $el.is(focusable); +const isFocusable = ($el) => { + return $el.is(focusable) +} -const isType = function($el, type) { - const el = [].concat($jquery.unwrap($el))[0]; +const isType = function ($el, type) { + const el = [].concat($jquery.unwrap($el))[0] //# NOTE: use DOMElement.type instead of getAttribute('type') since //# will have type="text", and behaves like text type - const elType = (getNativeProp(el, 'type') || "").toLowerCase(); + const elType = (getNativeProp(el, 'type') || '').toLowerCase() if (_.isArray(type)) { - return _.includes(type, elType); + return _.includes(type, elType) } - return elType === type; -}; + return elType === type +} -const isScrollOrAuto = prop => (prop === "scroll") || (prop === "auto"); +const isScrollOrAuto = (prop) => { + return (prop === 'scroll') || (prop === 'auto') +} -const isAncestor = ($el, $maybeAncestor) => $el.parents().index($maybeAncestor) >= 0; +const isAncestor = ($el, $maybeAncestor) => { + return $el.parents().index($maybeAncestor) >= 0 +} -const isSelector = ($el, selector) => $el.is(selector); +const isSelector = ($el, selector) => { + return $el.is(selector) +} -const isDetached = $el => !isAttached($el); +const isDetached = ($el) => { + return !isAttached($el) +} -var isAttached = function($el) { +const isAttached = function ($el) { //# if we're being given window //# then these are automaticallyed attached if ($window.isWindow($el)) { //# there is a code path when forcing focus and //# blur on the window where this check is necessary. - return true; + return true } //# if this is a document we can simply check @@ -325,165 +372,187 @@ var isAttached = function($el) { //# documents which are part of stale pages //# will have this property null'd out if ($document.isDocument($el)) { - return $document.hasActiveWindow($el); + return $document.hasActiveWindow($el) } //# normalize into an array - const els = [].concat($jquery.unwrap($el)); + const els = [].concat($jquery.unwrap($el)) //# we could be passed an empty array here //# which in that case it is not attached if (els.length === 0) { - return false; + return false } //# get the document from the first element - const doc = $document.getDocumentFromElement(els[0]); + const doc = $document.getDocumentFromElement(els[0]) //# TODO: i guess its possible each element //# is technically bound to a differnet document //# but c'mon - const isIn = el => $.contains(doc, el); + const isIn = (el) => { + return $.contains(doc, el) + } //# make sure the document is currently //# active (it has a window) and //# make sure every single element //# is attached to this document - return $document.hasActiveWindow(doc) && _.every(els, isIn); -}; + return $document.hasActiveWindow(doc) && _.every(els, isIn) +} -const isSame = function($el1, $el2) { - const el1 = $jquery.unwrap($el1); - const el2 = $jquery.unwrap($el2); +const isSame = function ($el1, $el2) { + const el1 = $jquery.unwrap($el1) + const el2 = $jquery.unwrap($el2) - return el1 && el2 && _.isEqual(el1, el2); -}; + return el1 && el2 && _.isEqual(el1, el2) +} -const isTextLike = function($el) { - const sel = selector => isSelector($el, selector); - const type = type => isType($el, type); +const isTextLike = function ($el) { + const sel = (selector) => { + return isSelector($el, selector) + } + const type = (type) => { + return isType($el, type) + } - const isContentEditableElement = isContentEditable($el.get(0)); + const isContentEditableElement = isContentEditable($el.get(0)) return _.some([ isContentEditableElement, - sel("textarea"), - sel(":text"), - type("text"), - type("password"), - type("email"), - type("number"), - type("date"), - type("week"), - type("month"), - type("time"), - type("datetime"), - type("datetime-local"), - type("search"), - type("url"), - type("tel") - ]); -}; - -const isScrollable = function($el) { - const checkDocumentElement = function(win, documentElement) { + sel('textarea'), + sel(':text'), + type('text'), + type('password'), + type('email'), + type('number'), + type('date'), + type('week'), + type('month'), + type('time'), + type('datetime'), + type('datetime-local'), + type('search'), + type('url'), + type('tel'), + ]) +} + +const isScrollable = function ($el) { + const checkDocumentElement = function (win, documentElement) { //# Check if body height is higher than window height - if (win.innerHeight < documentElement.scrollHeight) { return true; } + if (win.innerHeight < documentElement.scrollHeight) { + return true + } //# Check if body width is higher than window width - if (win.innerWidth < documentElement.scrollWidth) { return true; } + if (win.innerWidth < documentElement.scrollWidth) { + return true + } //# else return false since the window is not scrollable - return false; - }; + return false + } //# if we're the window, we want to get the document's //# element and check its size against the actual window switch (false) { case !$window.isWindow($el): - var win = $el; + const win = $el - return checkDocumentElement(win, win.document.documentElement); + return checkDocumentElement(win, win.document.documentElement) default: //# if we're any other element, we do some css calculations //# to see that the overflow is correct and the scroll //# area is larger than the actual height or width - var el = $el[0]; + const el = $el[0] - var {overflow, overflowY, overflowX} = window.getComputedStyle(el); + const { overflow, overflowY, overflowX } = window.getComputedStyle(el) //# y axis //# if our content height is less than the total scroll height if (el.clientHeight < el.scrollHeight) { //# and our element has scroll or auto overflow or overflowX - if (isScrollOrAuto(overflow) || isScrollOrAuto(overflowY)) { return true; } + if (isScrollOrAuto(overflow) || isScrollOrAuto(overflowY)) { + return true + } } //# x axis if (el.clientWidth < el.scrollWidth) { - if (isScrollOrAuto(overflow) || isScrollOrAuto(overflowX)) { return true; } + if (isScrollOrAuto(overflow) || isScrollOrAuto(overflowX)) { + return true + } } - return false; + return false } -}; +} -const isDescendent = function($el1, $el2) { - if (!$el2) { return false; } +const isDescendent = function ($el1, $el2) { + if (!$el2) { + return false + } - return !!(($el1.get(0) === $el2.get(0)) || $el1.has($el2).length); -}; + return !!(($el1.get(0) === $el2.get(0)) || $el1.has($el2).length) +} //# in order to simulate actual user behavior we need to do the following: //# 1. take our element and figure out its center coordinate //# 2. check to figure out the element listed at those coordinates //# 3. if this element is ourself or our descendants, click whatever was returned //# 4. else throw an error because something is covering us up -var getFirstFocusableEl = function($el) { - if (isFocusable($el)) { return $el; } +const getFirstFocusableEl = function ($el) { + if (isFocusable($el)) { + return $el + } - const parent = $el.parent(); + const parent = $el.parent() //# if we have no parent then just return //# the window since that can receive focus if (!parent.length) { - const win = $window.getWindowByElement($el.get(0)); + const win = $window.getWindowByElement($el.get(0)) - return $(win); + return $(win) } - return getFirstFocusableEl($el.parent()); -}; + return getFirstFocusableEl($el.parent()) +} -var getFirstFixedOrStickyPositionParent = function($el) { +const getFirstFixedOrStickyPositionParent = function ($el) { //# return null if we're at body/html //# cuz that means nothing has fixed position - if (!$el || $el.is("body,html")) { return null; } + if (!$el || $el.is('body,html')) { + return null + } //# if we have fixed position return ourselves - if (fixedOrStickyRe.test($el.css("position"))) { - return $el; + if (fixedOrStickyRe.test($el.css('position'))) { + return $el } //# else recursively continue to walk up the parent node chain - return getFirstFixedOrStickyPositionParent($el.parent()); -}; + return getFirstFixedOrStickyPositionParent($el.parent()) +} -var getFirstStickyPositionParent = function($el) { +const getFirstStickyPositionParent = function ($el) { //# return null if we're at body/html //# cuz that means nothing has sticky position - if (!$el || $el.is("body,html")) { return null; } + if (!$el || $el.is('body,html')) { + return null + } //# if we have sticky position return ourselves - if ($el.css("position") === "sticky") { - return $el; + if ($el.css('position') === 'sticky') { + return $el } //# else recursively continue to walk up the parent node chain - return getFirstStickyPositionParent($el.parent()); -}; + return getFirstStickyPositionParent($el.parent()) +} -const getFirstScrollableParent = function($el) { +const getFirstScrollableParent = function ($el) { // doc = $el.prop("ownerDocument") // win = getWindowFromDoc(doc) @@ -491,12 +560,12 @@ const getFirstScrollableParent = function($el) { //# this may be null or not even defined in IE // scrollingElement = doc.scrollingElement - var search = function($el) { - const $parent = $el.parent(); + const search = function ($el) { + const $parent = $el.parent() //# we have no more parents if (!($parent || $parent.length)) { - return null; + return null } //# we match the scrollingElement @@ -507,117 +576,133 @@ const getFirstScrollableParent = function($el) { //# we'll simply return null here and let our //# caller deal with situations where they're //# needing to scroll the window or scrollableElement - if ($parent.is("html,body") || $document.isDocument($parent)) { - return null; + if ($parent.is('html,body') || $document.isDocument($parent)) { + return null } if (isScrollable($parent)) { - return $parent; + return $parent } - return search($parent); - }; + return search($parent) + } - return search($el); -}; + return search($el) +} -const getElements = function($el) { - if (!($el != null ? $el.length : undefined)) { return; } +const getElements = function ($el) { + if (!($el != null ? $el.length : undefined)) { + return + } //# unroll the jquery object - const els = $jquery.unwrap($el); + const els = $jquery.unwrap($el) if (els.length === 1) { - return els[0]; - } else { - return els; + return els[0] } -}; -const getContainsSelector = function(text, filter = "") { - const escapedText = $utils.escapeQuotes(text); - return `${filter}:not(script):contains('${escapedText}'), ${filter}[type='submit'][value~='${escapedText}']`; -}; + return els + +} + +const getContainsSelector = function (text, filter = '') { + const escapedText = $utils.escapeQuotes(text) + + return `${filter}:not(script):contains('${escapedText}'), ${filter}[type='submit'][value~='${escapedText}']` +} -const priorityElement = "input[type='submit'], button, a, label"; +const priorityElement = 'input[type=\'submit\'], button, a, label' -var getFirstDeepestElement = function(elements, index = 0) { +const getFirstDeepestElement = function (elements, index = 0) { //# iterate through all of the elements in pairs //# and check if the next item in the array is a //# descedent of the current. if it is continue //# to recurse. if not, or there is no next item //# then return the current - const $current = elements.slice(index, index + 1); - const $next = elements.slice(index + 1, index + 2); + const $current = elements.slice(index, index + 1) + const $next = elements.slice(index + 1, index + 2) - if (!$next) { return $current; } + if (!$next) { + return $current + } //# does current contain next? if ($.contains($current.get(0), $next.get(0))) { - return getFirstDeepestElement(elements, index + 1); - } else { - //# return the current if it already is a priority element - if ($current.is(priorityElement)) { return $current; } + return getFirstDeepestElement(elements, index + 1) + } - //# else once we find the first deepest element then return its priority - //# parent if it has one and it exists in the elements chain - const $priorities = elements.filter($current.parents(priorityElement)); - if ($priorities.length) { return $priorities.last(); } else { return $current; } + //# return the current if it already is a priority element + if ($current.is(priorityElement)) { + return $current } -}; + + //# else once we find the first deepest element then return its priority + //# parent if it has one and it exists in the elements chain + const $priorities = elements.filter($current.parents(priorityElement)) + + if ($priorities.length) { + return $priorities.last() + } + + return $current + +} //# short form css-inlines the element //# long form returns the outerHTML -const stringify = function(el, form = "long") { +const stringify = function (el, form = 'long') { //# if we are formatting the window object - let id, klass; + let id, klass + if ($window.isWindow(el)) { - return ""; + return '' } //# if we are formatting the document object if ($document.isDocument(el)) { - return ""; + return '' } //# convert this to jquery if its not already one - const $el = $jquery.wrap(el); + const $el = $jquery.wrap(el) switch (form) { - case "long": - var text = _.chain($el.text()).clean().truncate({length: 10 }).value(); - var children = $el.children().length; - var str = $el.clone().empty().prop("outerHTML"); + case 'long': + const text = _.chain($el.text()).clean().truncate({ length: 10 }).value() + const children = $el.children().length + const str = $el.clone().empty().prop('outerHTML') + switch (false) { - case !children: return str.replace(">...${text}...${text} 1) { - return `[ <${str}>, ${$el.length - 1} more... ]`; - } else { - return `<${str}>`; + return `[ <${str}>, ${$el.length - 1} more... ]` } - } -}; + return `<${str}>` + + } +} module.exports = { isElement, @@ -678,5 +763,5 @@ module.exports = { getFirstStickyPositionParent, - getFirstScrollableParent -}; + getFirstScrollableParent, +} diff --git a/packages/driver/src/dom/index.js b/packages/driver/src/dom/index.js index 8fc8ef69bf3e..b5da69c76730 100644 --- a/packages/driver/src/dom/index.js +++ b/packages/driver/src/dom/index.js @@ -1,23 +1,27 @@ +// TODO: This file was created by bulk-decaffeinate. +// Sanity-check the conversion and remove this comment. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $jquery = require("./jquery"); -const $window = require("./window"); -const $document = require("./document"); -const $elements = require("./elements"); -const $visibility = require("./visibility"); -const $coordinates = require("./coordinates"); - -const { isWindow, getWindowByElement } = $window; -const { isDocument } = $document; -const { wrap, unwrap, isJquery, query } = $jquery; -const { isVisible, isHidden, getReasonIsHidden } = $visibility; -const { isType, isFocusable, isElement, isScrollable, stringify, getElements, getContainsSelector, getFirstDeepestElement, isDetached, isAttached, isTextLike, isSelector, isDescendent, getFirstFixedOrStickyPositionParent, getFirstStickyPositionParent, getFirstScrollableParent } = $elements; -const { getCoordsByPosition, getElementPositioning, getElementCoordinatesByPosition, getElementAtPointFromViewport, getElementCoordinatesByPositionRelativeToXY } = $coordinates; - -const isDom = obj => isElement(obj) || isWindow(obj) || isDocument(obj); +const $jquery = require('./jquery') +const $window = require('./window') +const $document = require('./document') +const $elements = require('./elements') +const $visibility = require('./visibility') +const $coordinates = require('./coordinates') + +const { isWindow, getWindowByElement } = $window +const { isDocument } = $document +const { wrap, unwrap, isJquery, query } = $jquery +const { isVisible, isHidden, getReasonIsHidden } = $visibility +const { isType, isFocusable, isElement, isScrollable, stringify, getElements, getContainsSelector, getFirstDeepestElement, isDetached, isAttached, isTextLike, isSelector, isDescendent, getFirstFixedOrStickyPositionParent, getFirstStickyPositionParent, getFirstScrollableParent } = $elements +const { getCoordsByPosition, getElementPositioning, getElementCoordinatesByPosition, getElementAtPointFromViewport, getElementCoordinatesByPositionRelativeToXY } = $coordinates + +const isDom = (obj) => { + return isElement(obj) || isWindow(obj) || isDocument(obj) +} //# we are exposing these publicly to be used //# by our own internal code, but also for @@ -87,6 +91,6 @@ module.exports = { getElementCoordinatesByPosition, - getElementCoordinatesByPositionRelativeToXY + getElementCoordinatesByPositionRelativeToXY, -}; +} diff --git a/packages/driver/src/dom/jquery.js b/packages/driver/src/dom/jquery.js index 95478b9059bf..bf7e179b87e2 100644 --- a/packages/driver/src/dom/jquery.js +++ b/packages/driver/src/dom/jquery.js @@ -1,31 +1,42 @@ +/* eslint-disable + brace-style, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $ = require("jquery"); -const _ = require("lodash"); +const $ = require('jquery') +const _ = require('lodash') //# wrap the object in jquery -const wrap = obj => $(obj); +const wrap = (obj) => { + return $(obj) +} -const query = (selector, context) => new $.fn.init(selector, context); +const query = (selector, context) => { + return new $.fn.init(selector, context) +} //# pull out the raw elements if this is wrapped -const unwrap = function(obj) { +const unwrap = function (obj) { if (isJquery(obj)) { //# return an array of elements - return obj.toArray(); - } else { - return obj; + return obj.toArray() } -}; -var isJquery = obj => - //# does it have the jquery property and is the - //# constructor a function? - !!(obj && obj.jquery && _.isFunction(obj.constructor)) -; + return obj + +} + +const isJquery = (obj) => +//# does it have the jquery property and is the +//# constructor a function? +{ + return !!(obj && obj.jquery && _.isFunction(obj.constructor)) +} //# doing a little jiggle wiggle here //# to avoid circular dependencies @@ -36,5 +47,5 @@ module.exports = { unwrap, - isJquery -}; + isJquery, +} diff --git a/packages/driver/src/dom/selection.js b/packages/driver/src/dom/selection.js index ac69b87ef45e..c64ed1ef994b 100644 --- a/packages/driver/src/dom/selection.js +++ b/packages/driver/src/dom/selection.js @@ -1,174 +1,194 @@ +/* eslint-disable + no-cond-assign, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $document = require("./document"); -const $elements = require("./elements"); -const $ = require("jquery"); +const $document = require('./document') +const $elements = require('./elements') +const $ = require('jquery') -const INTERNAL_STATE = "__Cypress_state__"; +const INTERNAL_STATE = '__Cypress_state__' -const _getSelectionBoundsFromTextarea = el => - ({ - start: $elements.getNativeProp(el, "selectionStart"), - end: $elements.getNativeProp(el, "selectionEnd") - }) -; +const _getSelectionBoundsFromTextarea = (el) => { + return { + start: $elements.getNativeProp(el, 'selectionStart'), + end: $elements.getNativeProp(el, 'selectionEnd'), + } +} + +const _getSelectionBoundsFromInput = function (el) { + let internalState -const _getSelectionBoundsFromInput = function(el) { - let internalState; if ($elements.canSetSelectionRangeElement(el)) { return { - start: $elements.getNativeProp(el, "selectionStart"), - end: $elements.getNativeProp(el, "selectionEnd") - }; + start: $elements.getNativeProp(el, 'selectionStart'), + end: $elements.getNativeProp(el, 'selectionEnd'), + } } if (internalState = el[INTERNAL_STATE]) { return { start: internalState.start, - end: internalState.end - }; + end: internalState.end, + } } return { start: 0, - end: 0 - }; -}; + end: 0, + } +} -const _getSelectionBoundsFromContentEditable = function(el) { - const doc = $document.getDocumentFromElement(el); +const _getSelectionBoundsFromContentEditable = function (el) { + const doc = $document.getDocumentFromElement(el) if (doc.getSelection) { //# global selection object - const sel = doc.getSelection(); + const sel = doc.getSelection() + //# selection has at least one range (most always 1; only 0 at page load) if (sel.rangeCount) { //# get the first (usually only) range obj - const range = sel.getRangeAt(0); + const range = sel.getRangeAt(0) //# if div[contenteditable] > text - const hostContenteditable = _getHostContenteditable(range.commonAncestorContainer); + const hostContenteditable = _getHostContenteditable(range.commonAncestorContainer) + if (hostContenteditable === el) { return { start: range.startOffset, - end: range.endOffset - }; + end: range.endOffset, + } } } } return { start: null, - end: null - }; -}; + end: null, + } +} + +//# TODO get ACTUAL caret position in contenteditable, not line - //# TODO get ACTUAL caret position in contenteditable, not line +const _replaceSelectionContentsContentEditable = function (el, text) { + const doc = $document.getDocumentFromElement(el) -const _replaceSelectionContentsContentEditable = function(el, text) { - const doc = $document.getDocumentFromElement(el); //# NOTE: insertText will also handle '\n', and render newlines - $elements.callNativeMethod(doc, "execCommand", "insertText", true, text); -}; - - //# Keeping around native implementation - //# for same reasons as listed below - //# - // if text is "\n" - // return _insertNewlineIntoContentEditable(el) - // doc = $document.getDocumentFromElement(el) - // range = _getSelectionRangeByEl(el) - // ## delete anything in the selection - // startNode = range.startContainer - // range.deleteContents() - // newTextNode - // if text is ' ' - // newTextNode = doc.createElement('p') - // else - // newTextNode = doc.createTextNode(text) - // if $elements.isElement(startNode) - // if startNode.firstChild?.tagName is "BR" - // range.selectNode(startNode.firstChild) - // range.deleteContents() - // ## else startNode is el, so just insert the node - // startNode.appendChild(newTextNode) - // if text is ' ' - // newTextNode.outerHTML = ' ' - // range.selectNodeContents(startNode.lastChild) - // range.collapse() - // return - // else - // # nodeOffset = range.startOffset - // # oldValue = startNode.nodeValue || "" - // range.insertNode(newTextNode) - // range.selectNodeContents(newTextNode) - // range.collapse() - // if text is ' ' - // newTextNode.outerHTML = ' ' - // # updatedValue = _insertSubstring(oldValue, text, [nodeOffset, nodeOffset]) - // # newNodeOffset = nodeOffset + text.length - // # startNode.nodeValue = updatedValue - // el.normalize() - -const _insertSubstring = (curText, newText, [start, end]) => curText.substring(0, start) + newText + curText.substring(end); - -var _getHostContenteditable = function(el) { - let curEl = el; - - while (curEl.parentElement && !$elements.tryCallNativeMethod(curEl, "getAttribute", "contenteditable")) { - curEl = curEl.parentElement; + $elements.callNativeMethod(doc, 'execCommand', 'insertText', true, text) +} + +//# Keeping around native implementation +//# for same reasons as listed below +//# +// if text is "\n" +// return _insertNewlineIntoContentEditable(el) +// doc = $document.getDocumentFromElement(el) +// range = _getSelectionRangeByEl(el) +// ## delete anything in the selection +// startNode = range.startContainer +// range.deleteContents() +// newTextNode +// if text is ' ' +// newTextNode = doc.createElement('p') +// else +// newTextNode = doc.createTextNode(text) +// if $elements.isElement(startNode) +// if startNode.firstChild?.tagName is "BR" +// range.selectNode(startNode.firstChild) +// range.deleteContents() +// ## else startNode is el, so just insert the node +// startNode.appendChild(newTextNode) +// if text is ' ' +// newTextNode.outerHTML = ' ' +// range.selectNodeContents(startNode.lastChild) +// range.collapse() +// return +// else +// # nodeOffset = range.startOffset +// # oldValue = startNode.nodeValue || "" +// range.insertNode(newTextNode) +// range.selectNodeContents(newTextNode) +// range.collapse() +// if text is ' ' +// newTextNode.outerHTML = ' ' +// # updatedValue = _insertSubstring(oldValue, text, [nodeOffset, nodeOffset]) +// # newNodeOffset = nodeOffset + text.length +// # startNode.nodeValue = updatedValue +// el.normalize() + +const _insertSubstring = (curText, newText, [start, end]) => { + return curText.substring(0, start) + newText + curText.substring(end) +} + +const _getHostContenteditable = function (el) { + let curEl = el + + while (curEl.parentElement && !$elements.tryCallNativeMethod(curEl, 'getAttribute', 'contenteditable')) { + curEl = curEl.parentElement } + //# if there's no host contenteditable, we must be in designmode //# so act as if the original element is the host contenteditable //# TODO: remove this when we no longer click before type and move //# cursor to the end - if (!$elements.callNativeMethod(curEl, "getAttribute", "contenteditable")) { - return el; + if (!$elements.callNativeMethod(curEl, 'getAttribute', 'contenteditable')) { + return el } - return curEl; -}; + return curEl +} -const _getInnerLastChild = function(el) { +const _getInnerLastChild = function (el) { while (el.lastChild) { - el = el.lastChild; + el = el.lastChild } - return el; -}; + return el +} -const _getSelectionByEl = function(el) { - const doc = $document.getDocumentFromElement(el); - return doc.getSelection(); -}; +const _getSelectionByEl = function (el) { + const doc = $document.getDocumentFromElement(el) + + return doc.getSelection() +} + +const _getSelectionRangeByEl = function (el) { + const sel = _getSelectionByEl(el) -const _getSelectionRangeByEl = function(el) { - const sel = _getSelectionByEl(el); if (sel.rangeCount > 0) { - return sel.getRangeAt(0); - } else { throw new Error("No selection in document"); } -}; + return sel.getRangeAt(0) + } -const deleteSelectionContents = function(el) { + throw new Error('No selection in document') +} + +const deleteSelectionContents = function (el) { if ($elements.isContentEditable(el)) { - const doc = $document.getDocumentFromElement(el); - $elements.callNativeMethod(doc, "execCommand", 'delete', false, null); - return; + const doc = $document.getDocumentFromElement(el) + + $elements.callNativeMethod(doc, 'execCommand', 'delete', false, null) + + return } //# for input and textarea, update selected text with empty string - return replaceSelectionContents(el, ""); -}; + return replaceSelectionContents(el, '') +} -const setSelectionRange = function(el, start, end) { +const setSelectionRange = function (el, start, end) { if ($elements.canSetSelectionRangeElement(el)) { - $elements.callNativeMethod(el, "setSelectionRange", start, end); - return; + $elements.callNativeMethod(el, 'setSelectionRange', start, end) + + return } //# NOTE: Some input elements have mobile implementations @@ -177,274 +197,305 @@ const setSelectionRange = function(el, start, end) { el[INTERNAL_STATE] = { start, - end - }; + end, + } -}; +} -const deleteRightOfCursor = function(el) { +const deleteRightOfCursor = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - const {start, end} = getSelectionBounds(el); + const { start, end } = getSelectionBounds(el) - if (start === $elements.getNativeProp(el, "value").length) { + if (start === $elements.getNativeProp(el, 'value').length) { //# nothing to delete, nothing to right of selection - return false; + return false } - setSelectionRange(el, start, end + 1); - deleteSelectionContents(el); + setSelectionRange(el, start, end + 1) + deleteSelectionContents(el) + //# successful delete - return true; + return true } if ($elements.isContentEditable(el)) { - const selection = _getSelectionByEl(el); - $elements.callNativeMethod(selection, "modify", "extend", "forward", "character"); + const selection = _getSelectionByEl(el) - if ($elements.getNativeProp(selection, "isCollapsed")) { + $elements.callNativeMethod(selection, 'modify', 'extend', 'forward', 'character') + + if ($elements.getNativeProp(selection, 'isCollapsed')) { //# there's nothing to delete - return false; + return false } - deleteSelectionContents(el); + deleteSelectionContents(el) + //# successful delete - return true; + return true } -}; +} -const deleteLeftOfCursor = function(el) { +const deleteLeftOfCursor = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - const {start, end} = getSelectionBounds(el); + const { start, end } = getSelectionBounds(el) if (start === 0) { //# there's nothing to delete, nothing before cursor - return false; + return false } - setSelectionRange(el, start - 1, end); - deleteSelectionContents(el); + setSelectionRange(el, start - 1, end) + deleteSelectionContents(el) + //# successful delete - return true; + return true } if ($elements.isContentEditable(el)) { //# there is no 'backwardDelete' command for execCommand, so use the Selection API - const selection = _getSelectionByEl(el); - $elements.callNativeMethod(selection, "modify", "extend", "backward", "character"); + const selection = _getSelectionByEl(el) + + $elements.callNativeMethod(selection, 'modify', 'extend', 'backward', 'character') if (selection.isCollapsed) { //# there's nothing to delete //# since extending the selection didn't do anything - return false; + return false } - deleteSelectionContents(el); + deleteSelectionContents(el) + //# successful delete - return true; + return true } -}; +} -const _collapseInputOrTextArea = (el, toIndex) => setSelectionRange(el, toIndex, toIndex); +const _collapseInputOrTextArea = (el, toIndex) => { + return setSelectionRange(el, toIndex, toIndex) +} -const moveCursorLeft = function(el) { +const moveCursorLeft = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - const {start, end} = getSelectionBounds(el); + const { start, end } = getSelectionBounds(el) if (start !== end) { - return _collapseInputOrTextArea(el, start); + return _collapseInputOrTextArea(el, start) } if (start === 0) { - return; + return } - return setSelectionRange(el, start - 1, start - 1); + return setSelectionRange(el, start - 1, start - 1) } if ($elements.isContentEditable(el)) { - const selection = _getSelectionByEl(el); - return $elements.callNativeMethod(selection, "modify", "move", "backward", "character"); - } -}; - - //# Keeping around native implementation - //# for same reasons as listed below - //# - // range = _getSelectionRangeByEl(el) - // if !range.collapsed - // return range.collapse(true) - // if range.startOffset is 0 - // return _contenteditableMoveToEndOfPrevLine(el) - // newOffset = range.startOffset - 1 - // range.setStart(range.startContainer, newOffset) - // range.setEnd(range.startContainer, newOffset) - -const moveCursorRight = function(el) { + const selection = _getSelectionByEl(el) + + return $elements.callNativeMethod(selection, 'modify', 'move', 'backward', 'character') + } +} + +//# Keeping around native implementation +//# for same reasons as listed below +//# +// range = _getSelectionRangeByEl(el) +// if !range.collapsed +// return range.collapse(true) +// if range.startOffset is 0 +// return _contenteditableMoveToEndOfPrevLine(el) +// newOffset = range.startOffset - 1 +// range.setStart(range.startContainer, newOffset) +// range.setEnd(range.startContainer, newOffset) + +const moveCursorRight = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - const {start, end} = getSelectionBounds(el); + const { start, end } = getSelectionBounds(el) + if (start !== end) { - return _collapseInputOrTextArea(el, end); + return _collapseInputOrTextArea(el, end) } //# Don't worry about moving past the end of the string //# nothing will happen and there is no error. - return setSelectionRange(el, start + 1, end + 1); + return setSelectionRange(el, start + 1, end + 1) } if ($elements.isContentEditable(el)) { - const selection = _getSelectionByEl(el); - return $elements.callNativeMethod(selection, "modify", "move", "forward", "character"); + const selection = _getSelectionByEl(el) + + return $elements.callNativeMethod(selection, 'modify', 'move', 'forward', 'character') } -}; +} -const moveCursorUp = el => _moveCursorUpOrDown(el, true); +const moveCursorUp = (el) => { + return _moveCursorUpOrDown(el, true) +} -const moveCursorDown = el => _moveCursorUpOrDown(el, false); +const moveCursorDown = (el) => { + return _moveCursorUpOrDown(el, false) +} -var _moveCursorUpOrDown = function(el, up) { +const _moveCursorUpOrDown = function (el, up) { if ($elements.isInput(el)) { //# on an input, instead of moving the cursor //# we want to perform the native browser action //# which is to increment the step/interval - if ($elements.isType(el, "number")) { - if (up) { if (typeof el.stepUp === 'function') { - el.stepUp(); - } } else { if (typeof el.stepDown === 'function') { - el.stepDown(); - } } + if ($elements.isType(el, 'number')) { + if (up) { + if (typeof el.stepUp === 'function') { + el.stepUp() + } + } else { + if (typeof el.stepDown === 'function') { + el.stepDown() + } + } } - return; + + return } if ($elements.isTextarea(el) || $elements.isContentEditable(el)) { - const selection = _getSelectionByEl(el); - return $elements.callNativeMethod(selection, "modify", - "move", - up ? "backward" : "forward", - "line" - ); + const selection = _getSelectionByEl(el) + + return $elements.callNativeMethod(selection, 'modify', + 'move', + up ? 'backward' : 'forward', + 'line' + ) } -}; +} -const isCollapsed = function(el) { +const isCollapsed = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - const {start, end} = getSelectionBounds(el); - return start === end; + const { start, end } = getSelectionBounds(el) + + return start === end } if ($elements.isContentEditable(el)) { - const selection = _getSelectionByEl(el); - return selection.isCollapsed; + const selection = _getSelectionByEl(el) + + return selection.isCollapsed } -}; +} -const selectAll = function(el) { +const selectAll = function (el) { if ($elements.isTextarea(el) || $elements.isInput(el)) { - setSelectionRange(el, 0, $elements.getNativeProp(el, "value").length); - return; + setSelectionRange(el, 0, $elements.getNativeProp(el, 'value').length) + + return } if ($elements.isContentEditable(el)) { - const doc = $document.getDocumentFromElement(el); - return $elements.callNativeMethod(doc, 'execCommand', 'selectAll', false, null); - } -}; - //# Keeping around native implementation - //# for same reasons as listed below - //# - // range = _getSelectionRangeByEl(el) - // range.selectNodeContents(el) - // range.deleteContents() - // return - // startTextNode = _getFirstTextNode(el.firstChild) - // endTextNode = _getInnerLastChild(el.lastChild) - // range.setStart(startTextNode, 0) - // range.setEnd(endTextNode, endTextNode.length) - -var getSelectionBounds = function(el) { + const doc = $document.getDocumentFromElement(el) + + return $elements.callNativeMethod(doc, 'execCommand', 'selectAll', false, null) + } +} +//# Keeping around native implementation +//# for same reasons as listed below +//# +// range = _getSelectionRangeByEl(el) +// range.selectNodeContents(el) +// range.deleteContents() +// return +// startTextNode = _getFirstTextNode(el.firstChild) +// endTextNode = _getInnerLastChild(el.lastChild) +// range.setStart(startTextNode, 0) +// range.setEnd(endTextNode, endTextNode.length) + +const getSelectionBounds = function (el) { //# this function works for input, textareas, and contentEditables switch (false) { case !$elements.isInput(el): - return _getSelectionBoundsFromInput(el); + return _getSelectionBoundsFromInput(el) case !$elements.isTextarea(el): - return _getSelectionBoundsFromTextarea(el); + return _getSelectionBoundsFromTextarea(el) case !$elements.isContentEditable(el): - return _getSelectionBoundsFromContentEditable(el); + return _getSelectionBoundsFromContentEditable(el) default: return { start: null, - end: null - }; + end: null, + } } -}; +} + +const moveSelectionToEnd = function (el) { + let length -const moveSelectionToEnd = function(el) { - let length; if ($elements.isInput(el) || $elements.isTextarea(el)) { - ({ length } = $elements.getNativeProp(el, "value")); - return setSelectionRange(el, length, length); + ({ length } = $elements.getNativeProp(el, 'value')) - } else if ($elements.isContentEditable(el)) { + return setSelectionRange(el, length, length) + + } + + if ($elements.isContentEditable(el)) { //# NOTE: can't use execCommand API here because we would have //# to selectAll and then collapse so we use the Selection API - const doc = $document.getDocumentFromElement(el); - const range = $elements.callNativeMethod(doc, "createRange"); - const hostContenteditable = _getHostContenteditable(el); - let lastTextNode = _getInnerLastChild(hostContenteditable); + const doc = $document.getDocumentFromElement(el) + const range = $elements.callNativeMethod(doc, 'createRange') + const hostContenteditable = _getHostContenteditable(el) + let lastTextNode = _getInnerLastChild(hostContenteditable) - if (lastTextNode.tagName === "BR") { - lastTextNode = lastTextNode.parentNode; + if (lastTextNode.tagName === 'BR') { + lastTextNode = lastTextNode.parentNode } - range.setStart(lastTextNode, lastTextNode.length); - range.setEnd(lastTextNode, lastTextNode.length); + range.setStart(lastTextNode, lastTextNode.length) + range.setEnd(lastTextNode, lastTextNode.length) + + const sel = $elements.callNativeMethod(doc, 'getSelection') + + $elements.callNativeMethod(sel, 'removeAllRanges') - const sel = $elements.callNativeMethod(doc, "getSelection"); - $elements.callNativeMethod(sel, "removeAllRanges"); - return $elements.callNativeMethod(sel, "addRange", range); + return $elements.callNativeMethod(sel, 'addRange', range) } -}; +} //# TODO: think about renaming this -var replaceSelectionContents = function(el, key) { +const replaceSelectionContents = function (el, key) { if ($elements.isContentEditable(el)) { - return _replaceSelectionContentsContentEditable(el, key); + return _replaceSelectionContentsContentEditable(el, key) } if ($elements.isInput(el) || $elements.isTextarea(el)) { - const { start, end } = getSelectionBounds(el); + const { start, end } = getSelectionBounds(el) - const value = $elements.getNativeProp(el, "value") || ""; - const updatedValue = _insertSubstring(value, key, [start, end]); + const value = $elements.getNativeProp(el, 'value') || '' + const updatedValue = _insertSubstring(value, key, [start, end]) - $elements.setNativeProp(el, "value", updatedValue); + $elements.setNativeProp(el, 'value', updatedValue) - return setSelectionRange(el, start + key.length, start + key.length); + return setSelectionRange(el, start + key.length, start + key.length) } -}; +} -const getCaretPosition = function(el) { - const bounds = getSelectionBounds(el); +const getCaretPosition = function (el) { + const bounds = getSelectionBounds(el) if ((bounds.start == null)) { //# no selection - return null; + return null } if (bounds.start === bounds.end) { - return bounds.start; + return bounds.start } - return null; -}; + return null +} -const interceptSelect = function() { +const interceptSelect = function () { if ($elements.isInput(this) && !$elements.canSetSelectionRangeElement(this)) { - setSelectionRange(this, 0, $elements.getNativeProp(this, "value").length); + setSelectionRange(this, 0, $elements.getNativeProp(this, 'value').length) } - return $elements.callNativeMethod(this, "select"); -}; + return $elements.callNativeMethod(this, 'select') +} //# Selection API implementation of insert newline. //# Worth keeping around if we ever have to insert native @@ -535,5 +586,5 @@ module.exports = { moveCursorDown, replaceSelectionContents, isCollapsed, - interceptSelect -}; + interceptSelect, +} diff --git a/packages/driver/src/dom/visibility.js b/packages/driver/src/dom/visibility.js index c84f430ad6ac..93109ab9ce86 100644 --- a/packages/driver/src/dom/visibility.js +++ b/packages/driver/src/dom/visibility.js @@ -1,3 +1,12 @@ +/* eslint-disable + no-case-declarations, + no-cond-assign, + no-const-assign, + no-irregular-whitespace, + one-var, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -6,35 +15,39 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const _ = require("lodash"); +const _ = require('lodash') -const $jquery = require("./jquery"); -const $document = require("./document"); -const $elements = require("./elements"); -const $coordinates = require("./coordinates"); +const $jquery = require('./jquery') +const $document = require('./document') +const $elements = require('./elements') +const $coordinates = require('./coordinates') -const fixedOrAbsoluteRe = /(fixed|absolute)/; +const fixedOrAbsoluteRe = /(fixed|absolute)/ -const OVERFLOW_PROPS = ["hidden", "scroll", "auto"]; +const OVERFLOW_PROPS = ['hidden', 'scroll', 'auto'] //# WARNING: //# developer beware. visibility is a sink hole //# that leads to sheer madness. you should //# avoid this file before its too late. -const isVisible = el => !isHidden(el, "isVisible()"); +const isVisible = (el) => { + return !isHidden(el, 'isVisible()') +} //# TODO: we should prob update dom //# to be passed in $utils as a dependency //# because of circular references -var isHidden = function(el, name) { +const isHidden = function (el, name) { if (!$elements.isElement(el)) { - if (name == null) { name = "isHidden()"; } + if (name == null) { + name = 'isHidden()' + } - throw new Error(`Cypress.dom.${name} must be passed a basic DOM element.`); + throw new Error(`Cypress.dom.${name} must be passed a basic DOM element.`) } - const $el = $jquery.wrap(el); + const $el = $jquery.wrap(el) //# in Cypress-land we consider the element hidden if //# either its offsetHeight or offsetWidth is 0 because @@ -55,113 +68,138 @@ var isHidden = function(el, name) { ( elIsFixed($el) ? elIsNotElementFromPoint($el) - : + : //# else check if el is outside the bounds //# of its ancestors overflow elIsOutOfBoundsOfAncestorsOverflow($el) - ); -}; + ) +} -var elHasNoEffectiveWidthOrHeight = $el => (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0) || ($el[0].getClientRects().length <= 0); +const elHasNoEffectiveWidthOrHeight = ($el) => { + return (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0) || ($el[0].getClientRects().length <= 0) +} -const elHasNoOffsetWidthOrHeight = $el => (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0); +const elHasNoOffsetWidthOrHeight = ($el) => { + return (elOffsetWidth($el) <= 0) || (elOffsetHeight($el) <= 0) +} -var elOffsetWidth = $el => $el[0].offsetWidth; +const elOffsetWidth = ($el) => { + return $el[0].offsetWidth +} -var elOffsetHeight = $el => $el[0].offsetHeight; +const elOffsetHeight = ($el) => { + return $el[0].offsetHeight +} -var elHasVisibilityHidden = $el => $el.css("visibility") === "hidden"; +const elHasVisibilityHidden = ($el) => { + return $el.css('visibility') === 'hidden' +} -const elHasDisplayNone = $el => $el.css("display") === "none"; +const elHasDisplayNone = ($el) => { + return $el.css('display') === 'none' +} -const elHasOverflowHidden = function($el) { - let needle; - return (needle = "hidden", [$el.css("overflow"), $el.css("overflow-y"), $el.css("overflow-x")].includes(needle)); -}; +const elHasOverflowHidden = function ($el) { + let needle -const elHasPositionRelative = $el => $el.css("position") === "relative"; + return (needle = 'hidden', [$el.css('overflow'), $el.css('overflow-y'), $el.css('overflow-x')].includes(needle)) +} -const elHasClippableOverflow = function($el) { - let needle, needle1, needle2; - return (needle = $el.css("overflow"), OVERFLOW_PROPS.includes(needle)) || - (needle1 = $el.css("overflow-y"), OVERFLOW_PROPS.includes(needle1)) || - (needle2 = $el.css("overflow-x"), OVERFLOW_PROPS.includes(needle2)); -}; +const elHasPositionRelative = ($el) => { + return $el.css('position') === 'relative' +} -const canClipContent = function($el, $ancestor) { +const elHasClippableOverflow = function ($el) { + let needle, needle1, needle2 + + return (needle = $el.css('overflow'), OVERFLOW_PROPS.includes(needle)) || + (needle1 = $el.css('overflow-y'), OVERFLOW_PROPS.includes(needle1)) || + (needle2 = $el.css('overflow-x'), OVERFLOW_PROPS.includes(needle2)) +} + +const canClipContent = function ($el, $ancestor) { //# can't clip without clippable overflow if (!elHasClippableOverflow($ancestor)) { - return false; + return false } - const $offsetParent = $jquery.wrap($el[0].offsetParent); + const $offsetParent = $jquery.wrap($el[0].offsetParent) //# even if overflow is clippable, if an ancestor of the ancestor is the //# element's offset parent, the ancestor will not clip the element //# unless the element is position relative if (!elHasPositionRelative($el) && $elements.isAncestor($ancestor, $offsetParent)) { - return false; + return false } - return true; -}; + return true +} + +const elIsFixed = function ($el) { + let $stickyOrFixedEl -var elIsFixed = function($el) { - let $stickyOrFixedEl; if ($stickyOrFixedEl = $elements.getFirstFixedOrStickyPositionParent($el)) { - return $stickyOrFixedEl.css("position") === "fixed"; + return $stickyOrFixedEl.css('position') === 'fixed' } -}; +} -const elAtCenterPoint = function($el) { - let el; - const elProps = $coordinates.getElementPositioning($el); +const elAtCenterPoint = function ($el) { + let el + const elProps = $coordinates.getElementPositioning($el) - const { topCenter, leftCenter } = elProps.fromViewport; + const { topCenter, leftCenter } = elProps.fromViewport - const doc = $document.getDocumentFromElement($el.get(0)); + const doc = $document.getDocumentFromElement($el.get(0)) if (el = $coordinates.getElementAtPointFromViewport(doc, leftCenter, topCenter)) { - return $jquery.wrap(el); + return $jquery.wrap(el) } -}; +} -const elDescendentsHavePositionFixedOrAbsolute = function($parent, $child) { +const elDescendentsHavePositionFixedOrAbsolute = function ($parent, $child) { //# create an array of all elements between $parent and $child //# including child but excluding parent //# and check if these have position fixed|absolute - const $els = $child.parentsUntil($parent).add($child); + const $els = $child.parentsUntil($parent).add($child) - return _.some($els.get(), el => fixedOrAbsoluteRe.test($jquery.wrap(el).css("position"))); -}; + return _.some($els.get(), (el) => { + return fixedOrAbsoluteRe.test($jquery.wrap(el).css('position')) + }) +} -var elIsNotElementFromPoint = function($el) { +const elIsNotElementFromPoint = function ($el) { //# if we have a fixed position element that means //# it is fixed 'relative' to the viewport which means //# it MUST be available with elementFromPoint because //# that is also relative to the viewport - const $elAtPoint = elAtCenterPoint($el); + const $elAtPoint = elAtCenterPoint($el) //# if the element at point is not a descendent //# of our $el then we know it's being covered or its //# not visible - return !$elements.isDescendent($el, $elAtPoint); -}; + return !$elements.isDescendent($el, $elAtPoint) +} -var elIsOutOfBoundsOfAncestorsOverflow = function($el, $ancestor) { - if ($ancestor == null) { $ancestor = $el.parent(); } +const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor) { + if ($ancestor == null) { + $ancestor = $el.parent() + } //# no ancestor, not out of bounds! - if (!$ancestor) { return false; } + if (!$ancestor) { + return false + } //# if we've reached the top parent, which is document //# then we're in bounds all the way up, return false - if ($ancestor.is("body,html") || $document.isDocument($ancestor)) { return false; } + if ($ancestor.is('body,html') || $document.isDocument($ancestor)) { + return false + } - const elProps = $coordinates.getElementPositioning($el); + const elProps = $coordinates.getElementPositioning($el) if (canClipContent($el, $ancestor)) { - const ancestorProps = $coordinates.getElementPositioning($ancestor); + const ancestorProps = $coordinates.getElementPositioning($ancestor) //# target el is out of bounds if ( @@ -176,15 +214,19 @@ var elIsOutOfBoundsOfAncestorsOverflow = function($el, $ancestor) { //# target el is above the ancestor's visible area ((elProps.fromWindow.top + elProps.height) < ancestorProps.fromWindow.top) - ) { return true; } + ) { + return true + } } - return elIsOutOfBoundsOfAncestorsOverflow($el, $ancestor.parent()); -}; + return elIsOutOfBoundsOfAncestorsOverflow($el, $ancestor.parent()) +} -var elIsHiddenByAncestors = function($el, $origEl) { +const elIsHiddenByAncestors = function ($el, $origEl) { //# store the original $el - if ($origEl == null) { $origEl = $el; } + if ($origEl == null) { + $origEl = $el + } //# walk up to each parent until we reach the body //# if any parent has an effective offsetHeight of 0 @@ -192,130 +234,141 @@ var elIsHiddenByAncestors = function($el, $origEl) { //# is effectively hidden //# -----UNLESS------ //# the parent or a descendent has position: absolute|fixed - const $parent = $el.parent(); + const $parent = $el.parent() //# stop if we've reached the body or html //# in case there is no body //# or if parent is the document which can //# happen if we already have an element - if ($parent.is("body,html") || $document.isDocument($parent)) { return false; } + if ($parent.is('body,html') || $document.isDocument($parent)) { + return false + } if (elHasOverflowHidden($parent) && elHasNoEffectiveWidthOrHeight($parent)) { //# if any of the elements between the parent and origEl //# have fixed or position absolute - return !elDescendentsHavePositionFixedOrAbsolute($parent, $origEl); + return !elDescendentsHavePositionFixedOrAbsolute($parent, $origEl) } //# continue to recursively walk up the chain until we reach body or html - return elIsHiddenByAncestors($parent, $origEl); -}; + return elIsHiddenByAncestors($parent, $origEl) +} -var parentHasNoOffsetWidthOrHeightAndOverflowHidden = function($el) { +const parentHasNoOffsetWidthOrHeightAndOverflowHidden = function ($el) { //# if we've walked all the way up to body or html then return false - if (!$el.length || $el.is("body,html")) { return false; } + if (!$el.length || $el.is('body,html')) { + return false + } //# if we have overflow hidden and no effective width or height if (elHasOverflowHidden($el) && elHasNoEffectiveWidthOrHeight($el)) { - return $el; - } else { - //# continue walking - return parentHasNoOffsetWidthOrHeightAndOverflowHidden($el.parent()); + return $el } -}; -var parentHasDisplayNone = function($el) { + //# continue walking + return parentHasNoOffsetWidthOrHeightAndOverflowHidden($el.parent()) + +} + +const parentHasDisplayNone = function ($el) { //# if we have no $el or we've walked all the way up to document //# then return false - if (!$el.length || $document.isDocument($el)) { return false; } + if (!$el.length || $document.isDocument($el)) { + return false + } //# if we have display none then return the $el if (elHasDisplayNone($el)) { - return $el; - } else { - //# continue walking - return parentHasDisplayNone($el.parent()); + return $el } -}; -var parentHasVisibilityNone = function($el) { + //# continue walking + return parentHasDisplayNone($el.parent()) + +} + +const parentHasVisibilityNone = function ($el) { //# if we've walked all the way up to document then return false - if (!$el.length || $document.isDocument($el)) { return false; } + if (!$el.length || $document.isDocument($el)) { + return false + } //# if we have display none then return the $el if (elHasVisibilityHidden($el)) { - return $el; - } else { - //# continue walking - return parentHasVisibilityNone($el.parent()); + return $el } -}; -const getReasonIsHidden = function($el) { + //# continue walking + return parentHasVisibilityNone($el.parent()) + +} + +const getReasonIsHidden = function ($el) { //# TODO: need to add in the reason an element //# is hidden when its fixed position and its //# either being covered or there is no el - let $parent; - const node = $elements.stringify($el, "short"); + let $parent + const node = $elements.stringify($el, 'short') //# returns the reason in human terms why an element is considered not visible switch (false) { case !elHasDisplayNone($el): - return `This element '${node}' is not visible because it has CSS property: 'display: none'`; + return `This element '${node}' is not visible because it has CSS property: 'display: none'` case !($parent = parentHasDisplayNone($el.parent())): - var parentNode = $elements.stringify($parent, "short"); + const parentNode = $elements.stringify($parent, 'short') - return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'display: none'`; + return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'display: none'` case !($parent = parentHasVisibilityNone($el.parent())): - parentNode = $elements.stringify($parent, "short"); + parentNode = $elements.stringify($parent, 'short') - return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'visibility: hidden'`; + return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'visibility: hidden'` case !elHasVisibilityHidden($el): - return `This element '${node}' is not visible because it has CSS property: 'visibility: hidden'`; + return `This element '${node}' is not visible because it has CSS property: 'visibility: hidden'` case !elHasNoOffsetWidthOrHeight($el): - var width = elOffsetWidth($el); - var height = elOffsetHeight($el); + const width = elOffsetWidth($el) + const height = elOffsetHeight($el) - return `This element '${node}' is not visible because it has an effective width and height of: '${width} x ${height}' pixels.`; + return `This element '${node}' is not visible because it has an effective width and height of: '${width} x ${height}' pixels.` case !($parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden($el.parent())): - parentNode = $elements.stringify($parent, "short"); - width = elOffsetWidth($parent); - height = elOffsetHeight($parent); + parentNode = $elements.stringify($parent, 'short') + width = elOffsetWidth($parent) + height = elOffsetHeight($parent) - return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'overflow: hidden' and an effective width and height of: '${width} x ${height}' pixels.`; + return `This element '${node}' is not visible because its parent '${parentNode}' has CSS property: 'overflow: hidden' and an effective width and height of: '${width} x ${height}' pixels.` default: //# nested else --___________-- if (elIsFixed($el)) { if (elIsNotElementFromPoint($el)) { //# show the long element here - const covered = $elements.stringify(elAtCenterPoint($el)); + const covered = $elements.stringify(elAtCenterPoint($el)) return `\ This element '${node}' is not visible because it has CSS property: 'position: fixed' and its being covered by another element: ${covered}\ -`; +` } } else { if (elIsOutOfBoundsOfAncestorsOverflow($el)) { - return `This element '${node}' is not visible because its content is being clipped by one of its parent elements, which has a CSS property of overflow: 'hidden', 'scroll' or 'auto'`; + return `This element '${node}' is not visible because its content is being clipped by one of its parent elements, which has a CSS property of overflow: 'hidden', 'scroll' or 'auto'` } } - return `Cypress could not determine why this element '${node}' is not visible.`; + return `Cypress could not determine why this element '${node}' is not visible.` } -}; +} module.exports = { isVisible, isHidden, - getReasonIsHidden -}; + getReasonIsHidden, +} diff --git a/packages/driver/src/dom/window.js b/packages/driver/src/dom/window.js index a148a3126d09..f4faeba00b45 100644 --- a/packages/driver/src/dom/window.js +++ b/packages/driver/src/dom/window.js @@ -1,41 +1,48 @@ +/* eslint-disable + brace-style, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const $jquery = require("./jquery"); -const $document = require("./document"); +const $jquery = require('./jquery') +const $document = require('./document') -const getWindowByElement = function(el) { +const getWindowByElement = function (el) { if (isWindow(el)) { - return el; + return el } - const doc = $document.getDocumentFromElement(el); - return getWindowByDocument(doc); -}; + const doc = $document.getDocumentFromElement(el) -var getWindowByDocument = doc => - //# parentWindow for IE - doc.defaultView || doc.parentWindow -; + return getWindowByDocument(doc) +} -var isWindow = function(obj) { +const getWindowByDocument = (doc) => +//# parentWindow for IE +{ + return doc.defaultView || doc.parentWindow +} + +const isWindow = function (obj) { try { if ($jquery.isJquery(obj)) { - obj = obj[0]; + obj = obj[0] } - return Boolean(obj && (obj.window === obj)); + return Boolean(obj && (obj.window === obj)) } catch (error) { - return false; + return false } -}; +} module.exports = { getWindowByElement, getWindowByDocument, - isWindow -}; + isWindow, +}