Best Python code snippet using sure_python
useFocusWithin-test.internal.js
Source:useFocusWithin-test.internal.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @emails react-core8 */9'use strict';10import {createEventTarget, setPointerEvent} from 'dom-event-testing-library';11let React;12let ReactFeatureFlags;13let ReactDOM;14let useFocusWithin;15let ReactTestRenderer;16let act;17let Scheduler;18function initializeModules(hasPointerEvents) {19  setPointerEvent(hasPointerEvents);20  jest.resetModules();21  ReactFeatureFlags = require('shared/ReactFeatureFlags');22  ReactFeatureFlags.enableScopeAPI = true;23  ReactFeatureFlags.enableCreateEventHandleAPI = true;24  React = require('react');25  ReactDOM = require('react-dom');26  ReactTestRenderer = require('react-test-renderer');27  Scheduler = require('scheduler');28  act = ReactTestRenderer.unstable_concurrentAct;29  // TODO: This import throws outside of experimental mode. Figure out better30  // strategy for gated imports.31  if (__EXPERIMENTAL__) {32    useFocusWithin = require('react-interactions/events/focus').useFocusWithin;33  }34}35const forcePointerEvents = true;36const table = [[forcePointerEvents], [!forcePointerEvents]];37describe.each(table)(`useFocus`, hasPointerEvents => {38  let container;39  let container2;40  beforeEach(() => {41    initializeModules(hasPointerEvents);42    container = document.createElement('div');43    document.body.appendChild(container);44    container2 = document.createElement('div');45    document.body.appendChild(container2);46  });47  afterEach(() => {48    ReactDOM.render(null, container);49    document.body.removeChild(container);50    document.body.removeChild(container2);51    container = null;52    container2 = null;53  });54  describe('disabled', () => {55    let onFocusWithinChange, onFocusWithinVisibleChange, ref;56    const componentInit = () => {57      onFocusWithinChange = jest.fn();58      onFocusWithinVisibleChange = jest.fn();59      ref = React.createRef();60      const Component = () => {61        const focusWithinRef = useFocusWithin(ref, {62          disabled: true,63          onFocusWithinChange,64          onFocusWithinVisibleChange,65        });66        return <div ref={focusWithinRef} />;67      };68      ReactDOM.render(<Component />, container);69      Scheduler.unstable_flushAll();70    };71    // @gate experimental72    it('prevents custom events being dispatched', () => {73      componentInit();74      const target = createEventTarget(ref.current);75      target.focus();76      target.blur();77      expect(onFocusWithinChange).not.toBeCalled();78      expect(onFocusWithinVisibleChange).not.toBeCalled();79    });80  });81  describe('onFocusWithinChange', () => {82    let onFocusWithinChange, ref, innerRef, innerRef2;83    const Component = ({show}) => {84      const focusWithinRef = useFocusWithin(ref, {85        onFocusWithinChange,86      });87      return (88        <div ref={focusWithinRef}>89          {show && <input ref={innerRef} />}90          <div ref={innerRef2} />91        </div>92      );93    };94    const componentInit = () => {95      onFocusWithinChange = jest.fn();96      ref = React.createRef();97      innerRef = React.createRef();98      innerRef2 = React.createRef();99      ReactDOM.render(<Component show={true} />, container);100      Scheduler.unstable_flushAll();101    };102    // @gate experimental103    it('is called after "blur" and "focus" events on focus target', () => {104      componentInit();105      const target = createEventTarget(ref.current);106      target.focus();107      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);108      expect(onFocusWithinChange).toHaveBeenCalledWith(true);109      target.blur({relatedTarget: container});110      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);111      expect(onFocusWithinChange).toHaveBeenCalledWith(false);112    });113    // @gate experimental114    it('is called after "blur" and "focus" events on descendants', () => {115      componentInit();116      const target = createEventTarget(innerRef.current);117      target.focus();118      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);119      expect(onFocusWithinChange).toHaveBeenCalledWith(true);120      target.blur({relatedTarget: container});121      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);122      expect(onFocusWithinChange).toHaveBeenCalledWith(false);123    });124    // @gate experimental125    it('is only called once when focus moves within and outside the subtree', () => {126      componentInit();127      const node = ref.current;128      const innerNode1 = innerRef.current;129      const innerNode2 = innerRef.current;130      const target = createEventTarget(node);131      const innerTarget1 = createEventTarget(innerNode1);132      const innerTarget2 = createEventTarget(innerNode2);133      // focus shifts into subtree134      innerTarget1.focus();135      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);136      expect(onFocusWithinChange).toHaveBeenCalledWith(true);137      // focus moves around subtree138      innerTarget1.blur({relatedTarget: innerNode2});139      innerTarget2.focus();140      innerTarget2.blur({relatedTarget: node});141      target.focus();142      target.blur({relatedTarget: innerNode1});143      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);144      // focus shifts outside subtree145      innerTarget1.blur({relatedTarget: container});146      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);147      expect(onFocusWithinChange).toHaveBeenCalledWith(false);148    });149  });150  describe('onFocusWithinVisibleChange', () => {151    let onFocusWithinVisibleChange, ref, innerRef, innerRef2;152    const Component = ({show}) => {153      const focusWithinRef = useFocusWithin(ref, {154        onFocusWithinVisibleChange,155      });156      return (157        <div ref={focusWithinRef}>158          {show && <input ref={innerRef} />}159          <div ref={innerRef2} />160        </div>161      );162    };163    const componentInit = () => {164      onFocusWithinVisibleChange = jest.fn();165      ref = React.createRef();166      innerRef = React.createRef();167      innerRef2 = React.createRef();168      ReactDOM.render(<Component show={true} />, container);169      Scheduler.unstable_flushAll();170    };171    // @gate experimental172    it('is called after "focus" and "blur" on focus target if keyboard was used', () => {173      componentInit();174      const target = createEventTarget(ref.current);175      const containerTarget = createEventTarget(container);176      // use keyboard first177      containerTarget.keydown({key: 'Tab'});178      target.focus();179      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);180      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);181      target.blur({relatedTarget: container});182      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);183      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);184    });185    // @gate experimental186    it('is called after "focus" and "blur" on descendants if keyboard was used', () => {187      componentInit();188      const innerTarget = createEventTarget(innerRef.current);189      const containerTarget = createEventTarget(container);190      // use keyboard first191      containerTarget.keydown({key: 'Tab'});192      innerTarget.focus();193      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);194      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);195      innerTarget.blur({relatedTarget: container});196      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);197      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);198    });199    // @gate experimental200    it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => {201      componentInit();202      const node = ref.current;203      const innerNode1 = innerRef.current;204      const innerNode2 = innerRef2.current;205      const target = createEventTarget(node);206      const innerTarget1 = createEventTarget(innerNode1);207      const innerTarget2 = createEventTarget(innerNode2);208      // use keyboard first209      target.focus();210      target.keydown({key: 'Tab'});211      target.blur({relatedTarget: innerNode1});212      innerTarget1.focus();213      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);214      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);215      // then use pointer on the next target, focus should no longer be visible216      innerTarget2.pointerdown();217      innerTarget1.blur({relatedTarget: innerNode2});218      innerTarget2.focus();219      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);220      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);221      // then use keyboard again222      innerTarget2.keydown({key: 'Tab', shiftKey: true});223      innerTarget2.blur({relatedTarget: innerNode1});224      innerTarget1.focus();225      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(3);226      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);227      // then use pointer on the target, focus should no longer be visible228      innerTarget1.pointerdown();229      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4);230      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);231      // onFocusVisibleChange should not be called again232      innerTarget1.blur({relatedTarget: container});233      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4);234    });235    // @gate experimental236    it('is not called after "focus" and "blur" events without keyboard', () => {237      componentInit();238      const innerTarget = createEventTarget(innerRef.current);239      innerTarget.pointerdown();240      innerTarget.pointerup();241      innerTarget.blur({relatedTarget: container});242      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(0);243    });244    // @gate experimental245    it('is only called once when focus moves within and outside the subtree', () => {246      componentInit();247      const node = ref.current;248      const innerNode1 = innerRef.current;249      const innerNode2 = innerRef2.current;250      const target = createEventTarget(node);251      const innerTarget1 = createEventTarget(innerNode1);252      const innerTarget2 = createEventTarget(innerNode2);253      // focus shifts into subtree254      innerTarget1.focus();255      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);256      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);257      // focus moves around subtree258      innerTarget1.blur({relatedTarget: innerNode2});259      innerTarget2.focus();260      innerTarget2.blur({relatedTarget: node});261      target.focus();262      target.blur({relatedTarget: innerNode1});263      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);264      // focus shifts outside subtree265      innerTarget1.blur({relatedTarget: container});266      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);267      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);268    });269  });270  // @gate experimental271  it('should correctly handle focus visibility when typing into an input', () => {272    const onFocusWithinVisibleChange = jest.fn();273    const ref = React.createRef();274    const inputRef = React.createRef();275    const Component = () => {276      const focusWithinRef = useFocusWithin(ref, {277        onFocusWithinVisibleChange,278      });279      return (280        <div ref={focusWithinRef}>281          <input ref={inputRef} type="text" />282        </div>283      );284    };285    act(() => {286      ReactDOM.render(<Component />, container);287    });288    const target = createEventTarget(inputRef.current);289    // focus the target290    target.pointerdown();291    target.focus();292    target.keydown({key: 'a'});293    expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(0);294  });295  describe('onBeforeBlurWithin', () => {296    let onBeforeBlurWithin, onAfterBlurWithin, ref, innerRef, innerRef2;297    beforeEach(() => {298      onBeforeBlurWithin = jest.fn();299      onAfterBlurWithin = jest.fn(e => {300        e.persist();301      });302      ref = React.createRef();303      innerRef = React.createRef();304      innerRef2 = React.createRef();305    });306    // @gate experimental307    it('is called after a focused element is unmounted', () => {308      const Component = ({show}) => {309        const focusWithinRef = useFocusWithin(ref, {310          onBeforeBlurWithin,311          onAfterBlurWithin,312        });313        return (314          <div ref={focusWithinRef}>315            {show && <input ref={innerRef} />}316            <div ref={innerRef2} />317          </div>318        );319      };320      ReactDOM.render(<Component show={true} />, container);321      Scheduler.unstable_flushAll();322      const inner = innerRef.current;323      const target = createEventTarget(inner);324      target.keydown({key: 'Tab'});325      target.focus();326      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);327      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);328      ReactDOM.render(<Component show={false} />, container);329      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);330      expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);331      expect(onAfterBlurWithin).toHaveBeenCalledWith(332        expect.objectContaining({relatedTarget: inner}),333      );334    });335    // @gate experimental336    it('is called after a nested focused element is unmounted', () => {337      const Component = ({show}) => {338        const focusWithinRef = useFocusWithin(ref, {339          onBeforeBlurWithin,340          onAfterBlurWithin,341        });342        return (343          <div ref={focusWithinRef}>344            {show && (345              <div>346                <input ref={innerRef} />347              </div>348            )}349            <div ref={innerRef2} />350          </div>351        );352      };353      ReactDOM.render(<Component show={true} />, container);354      Scheduler.unstable_flushAll();355      const inner = innerRef.current;356      const target = createEventTarget(inner);357      target.keydown({key: 'Tab'});358      target.focus();359      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);360      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);361      ReactDOM.render(<Component show={false} />, container);362      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);363      expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);364      expect(onAfterBlurWithin).toHaveBeenCalledWith(365        expect.objectContaining({relatedTarget: inner}),366      );367    });368    // @gate experimental369    it('is called after many elements are unmounted', () => {370      const buttonRef = React.createRef();371      const inputRef = React.createRef();372      const Component = ({show}) => {373        const focusWithinRef = useFocusWithin(ref, {374          onBeforeBlurWithin,375          onAfterBlurWithin,376        });377        return (378          <div ref={focusWithinRef}>379            {show && <button>Press me!</button>}380            {show && <button>Press me!</button>}381            {show && <input ref={inputRef} />}382            {show && <button>Press me!</button>}383            {!show && <button ref={buttonRef}>Press me!</button>}384            {show && <button>Press me!</button>}385            <button>Press me!</button>386            <button>Press me!</button>387          </div>388        );389      };390      ReactDOM.render(<Component show={true} />, container);391      Scheduler.unstable_flushAll();392      inputRef.current.focus();393      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);394      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);395      ReactDOM.render(<Component show={false} />, container);396      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);397      expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);398    });399    // @gate experimental400    it('is called after a nested focused element is unmounted (with scope query)', () => {401      const TestScope = React.unstable_Scope;402      const testScopeQuery = (type, props) => true;403      let targetNodes;404      let targetNode;405      const Component = ({show}) => {406        const scopeRef = React.useRef(null);407        const focusWithinRef = useFocusWithin(scopeRef, {408          onBeforeBlurWithin(event) {409            const scope = scopeRef.current;410            targetNode = innerRef.current;411            targetNodes = scope.DO_NOT_USE_queryAllNodes(testScopeQuery);412          },413        });414        return (415          <TestScope ref={focusWithinRef}>416            {show && <input ref={innerRef} />}417          </TestScope>418        );419      };420      ReactDOM.render(<Component show={true} />, container);421      Scheduler.unstable_flushAll();422      const inner = innerRef.current;423      const target = createEventTarget(inner);424      target.keydown({key: 'Tab'});425      target.focus();426      ReactDOM.render(<Component show={false} />, container);427      Scheduler.unstable_flushAll();428      expect(targetNodes).toEqual([targetNode]);429    });430    // @gate experimental431    it('is called after a focused suspended element is hidden', () => {432      const Suspense = React.Suspense;433      let suspend = false;434      let resolve;435      const promise = new Promise(resolvePromise => (resolve = resolvePromise));436      function Child() {437        if (suspend) {438          throw promise;439        } else {440          return <input ref={innerRef} />;441        }442      }443      const Component = ({show}) => {444        const focusWithinRef = useFocusWithin(ref, {445          onBeforeBlurWithin,446          onAfterBlurWithin,447        });448        return (449          <div ref={focusWithinRef}>450            <Suspense fallback="Loading...">451              <Child />452            </Suspense>453          </div>454        );455      };456      const root = ReactDOM.createRoot(container2);457      act(() => {458        root.render(<Component />);459      });460      jest.runAllTimers();461      expect(container2.innerHTML).toBe('<div><input></div>');462      const inner = innerRef.current;463      const target = createEventTarget(inner);464      target.keydown({key: 'Tab'});465      target.focus();466      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);467      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);468      suspend = true;469      act(() => {470        root.render(<Component />);471      });472      jest.runAllTimers();473      expect(container2.innerHTML).toBe(474        '<div><input style="display: none;">Loading...</div>',475      );476      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);477      expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);478      resolve();479    });480    // @gate experimental481    it('is called after a focused suspended element is hidden then shown', () => {482      const Suspense = React.Suspense;483      let suspend = false;484      let resolve;485      const promise = new Promise(resolvePromise => (resolve = resolvePromise));486      const buttonRef = React.createRef();487      function Child() {488        if (suspend) {489          throw promise;490        } else {491          return <input ref={innerRef} />;492        }493      }494      const Component = ({show}) => {495        const focusWithinRef = useFocusWithin(ref, {496          onBeforeBlurWithin,497          onAfterBlurWithin,498        });499        return (500          <div ref={focusWithinRef}>501            <Suspense fallback={<button ref={buttonRef}>Loading...</button>}>502              <Child />503            </Suspense>504          </div>505        );506      };507      const root = ReactDOM.createRoot(container2);508      act(() => {509        root.render(<Component />);510      });511      jest.runAllTimers();512      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);513      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);514      suspend = true;515      act(() => {516        root.render(<Component />);517      });518      jest.runAllTimers();519      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);520      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);521      act(() => {522        root.render(<Component />);523      });524      jest.runAllTimers();525      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);526      expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);527      buttonRef.current.focus();528      suspend = false;529      act(() => {530        root.render(<Component />);531      });532      jest.runAllTimers();533      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);534      expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);535      resolve();536    });537  });...jquery.ui.position.js
Source:jquery.ui.position.js  
1/*!2 * jQuery UI Position 1.10.43 * http://jqueryui.com4 *5 * Copyright 2014 jQuery Foundation and other contributors6 * Released under the MIT license.7 * http://jquery.org/license8 *9 * http://api.jqueryui.com/position/10 */11(function( $, undefined ) {12$.ui = $.ui || {};13var cachedScrollbarWidth,14	max = Math.max,15	abs = Math.abs,16	round = Math.round,17	rhorizontal = /left|center|right/,18	rvertical = /top|center|bottom/,19	roffset = /[\+\-]\d+(\.[\d]+)?%?/,20	rposition = /^\w+/,21	rpercent = /%$/,22	_position = $.fn.position;23function getOffsets( offsets, width, height ) {24	return [25		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),26		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )27	];28}29function parseCss( element, property ) {30	return parseInt( $.css( element, property ), 10 ) || 0;31}32function getDimensions( elem ) {33	var raw = elem[0];34	if ( raw.nodeType === 9 ) {35		return {36			width: elem.width(),37			height: elem.height(),38			offset: { top: 0, left: 0 }39		};40	}41	if ( $.isWindow( raw ) ) {42		return {43			width: elem.width(),44			height: elem.height(),45			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }46		};47	}48	if ( raw.preventDefault ) {49		return {50			width: 0,51			height: 0,52			offset: { top: raw.pageY, left: raw.pageX }53		};54	}55	return {56		width: elem.outerWidth(),57		height: elem.outerHeight(),58		offset: elem.offset()59	};60}61$.position = {62	scrollbarWidth: function() {63		if ( cachedScrollbarWidth !== undefined ) {64			return cachedScrollbarWidth;65		}66		var w1, w2,67			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),68			innerDiv = div.children()[0];69		$( "body" ).append( div );70		w1 = innerDiv.offsetWidth;71		div.css( "overflow", "scroll" );72		w2 = innerDiv.offsetWidth;73		if ( w1 === w2 ) {74			w2 = div[0].clientWidth;75		}76		div.remove();77		return (cachedScrollbarWidth = w1 - w2);78	},79	getScrollInfo: function( within ) {80		var overflowX = within.isWindow || within.isDocument ? "" :81				within.element.css( "overflow-x" ),82			overflowY = within.isWindow || within.isDocument ? "" :83				within.element.css( "overflow-y" ),84			hasOverflowX = overflowX === "scroll" ||85				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),86			hasOverflowY = overflowY === "scroll" ||87				( overflowY === "auto" && within.height < within.element[0].scrollHeight );88		return {89			width: hasOverflowY ? $.position.scrollbarWidth() : 0,90			height: hasOverflowX ? $.position.scrollbarWidth() : 091		};92	},93	getWithinInfo: function( element ) {94		var withinElement = $( element || window ),95			isWindow = $.isWindow( withinElement[0] ),96			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;97		return {98			element: withinElement,99			isWindow: isWindow,100			isDocument: isDocument,101			offset: withinElement.offset() || { left: 0, top: 0 },102			scrollLeft: withinElement.scrollLeft(),103			scrollTop: withinElement.scrollTop(),104			width: isWindow ? withinElement.width() : withinElement.outerWidth(),105			height: isWindow ? withinElement.height() : withinElement.outerHeight()106		};107	}108};109$.fn.position = function( options ) {110	if ( !options || !options.of ) {111		return _position.apply( this, arguments );112	}113	// make a copy, we don't want to modify arguments114	options = $.extend( {}, options );115	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,116		target = $( options.of ),117		within = $.position.getWithinInfo( options.within ),118		scrollInfo = $.position.getScrollInfo( within ),119		collision = ( options.collision || "flip" ).split( " " ),120		offsets = {};121	dimensions = getDimensions( target );122	if ( target[0].preventDefault ) {123		// force left top to allow flipping124		options.at = "left top";125	}126	targetWidth = dimensions.width;127	targetHeight = dimensions.height;128	targetOffset = dimensions.offset;129	// clone to reuse original targetOffset later130	basePosition = $.extend( {}, targetOffset );131	// force my and at to have valid horizontal and vertical positions132	// if a value is missing or invalid, it will be converted to center133	$.each( [ "my", "at" ], function() {134		var pos = ( options[ this ] || "" ).split( " " ),135			horizontalOffset,136			verticalOffset;137		if ( pos.length === 1) {138			pos = rhorizontal.test( pos[ 0 ] ) ?139				pos.concat( [ "center" ] ) :140				rvertical.test( pos[ 0 ] ) ?141					[ "center" ].concat( pos ) :142					[ "center", "center" ];143		}144		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";145		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";146		// calculate offsets147		horizontalOffset = roffset.exec( pos[ 0 ] );148		verticalOffset = roffset.exec( pos[ 1 ] );149		offsets[ this ] = [150			horizontalOffset ? horizontalOffset[ 0 ] : 0,151			verticalOffset ? verticalOffset[ 0 ] : 0152		];153		// reduce to just the positions without the offsets154		options[ this ] = [155			rposition.exec( pos[ 0 ] )[ 0 ],156			rposition.exec( pos[ 1 ] )[ 0 ]157		];158	});159	// normalize collision option160	if ( collision.length === 1 ) {161		collision[ 1 ] = collision[ 0 ];162	}163	if ( options.at[ 0 ] === "right" ) {164		basePosition.left += targetWidth;165	} else if ( options.at[ 0 ] === "center" ) {166		basePosition.left += targetWidth / 2;167	}168	if ( options.at[ 1 ] === "bottom" ) {169		basePosition.top += targetHeight;170	} else if ( options.at[ 1 ] === "center" ) {171		basePosition.top += targetHeight / 2;172	}173	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );174	basePosition.left += atOffset[ 0 ];175	basePosition.top += atOffset[ 1 ];176	return this.each(function() {177		var collisionPosition, using,178			elem = $( this ),179			elemWidth = elem.outerWidth(),180			elemHeight = elem.outerHeight(),181			marginLeft = parseCss( this, "marginLeft" ),182			marginTop = parseCss( this, "marginTop" ),183			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,184			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,185			position = $.extend( {}, basePosition ),186			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );187		if ( options.my[ 0 ] === "right" ) {188			position.left -= elemWidth;189		} else if ( options.my[ 0 ] === "center" ) {190			position.left -= elemWidth / 2;191		}192		if ( options.my[ 1 ] === "bottom" ) {193			position.top -= elemHeight;194		} else if ( options.my[ 1 ] === "center" ) {195			position.top -= elemHeight / 2;196		}197		position.left += myOffset[ 0 ];198		position.top += myOffset[ 1 ];199		// if the browser doesn't support fractions, then round for consistent results200		if ( !$.support.offsetFractions ) {201			position.left = round( position.left );202			position.top = round( position.top );203		}204		collisionPosition = {205			marginLeft: marginLeft,206			marginTop: marginTop207		};208		$.each( [ "left", "top" ], function( i, dir ) {209			if ( $.ui.position[ collision[ i ] ] ) {210				$.ui.position[ collision[ i ] ][ dir ]( position, {211					targetWidth: targetWidth,212					targetHeight: targetHeight,213					elemWidth: elemWidth,214					elemHeight: elemHeight,215					collisionPosition: collisionPosition,216					collisionWidth: collisionWidth,217					collisionHeight: collisionHeight,218					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],219					my: options.my,220					at: options.at,221					within: within,222					elem : elem223				});224			}225		});226		if ( options.using ) {227			// adds feedback as second argument to using callback, if present228			using = function( props ) {229				var left = targetOffset.left - position.left,230					right = left + targetWidth - elemWidth,231					top = targetOffset.top - position.top,232					bottom = top + targetHeight - elemHeight,233					feedback = {234						target: {235							element: target,236							left: targetOffset.left,237							top: targetOffset.top,238							width: targetWidth,239							height: targetHeight240						},241						element: {242							element: elem,243							left: position.left,244							top: position.top,245							width: elemWidth,246							height: elemHeight247						},248						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",249						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"250					};251				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {252					feedback.horizontal = "center";253				}254				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {255					feedback.vertical = "middle";256				}257				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {258					feedback.important = "horizontal";259				} else {260					feedback.important = "vertical";261				}262				options.using.call( this, props, feedback );263			};264		}265		elem.offset( $.extend( position, { using: using } ) );266	});267};268$.ui.position = {269	fit: {270		left: function( position, data ) {271			var within = data.within,272				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,273				outerWidth = within.width,274				collisionPosLeft = position.left - data.collisionPosition.marginLeft,275				overLeft = withinOffset - collisionPosLeft,276				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,277				newOverRight;278			// element is wider than within279			if ( data.collisionWidth > outerWidth ) {280				// element is initially over the left side of within281				if ( overLeft > 0 && overRight <= 0 ) {282					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;283					position.left += overLeft - newOverRight;284				// element is initially over right side of within285				} else if ( overRight > 0 && overLeft <= 0 ) {286					position.left = withinOffset;287				// element is initially over both left and right sides of within288				} else {289					if ( overLeft > overRight ) {290						position.left = withinOffset + outerWidth - data.collisionWidth;291					} else {292						position.left = withinOffset;293					}294				}295			// too far left -> align with left edge296			} else if ( overLeft > 0 ) {297				position.left += overLeft;298			// too far right -> align with right edge299			} else if ( overRight > 0 ) {300				position.left -= overRight;301			// adjust based on position and margin302			} else {303				position.left = max( position.left - collisionPosLeft, position.left );304			}305		},306		top: function( position, data ) {307			var within = data.within,308				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,309				outerHeight = data.within.height,310				collisionPosTop = position.top - data.collisionPosition.marginTop,311				overTop = withinOffset - collisionPosTop,312				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,313				newOverBottom;314			// element is taller than within315			if ( data.collisionHeight > outerHeight ) {316				// element is initially over the top of within317				if ( overTop > 0 && overBottom <= 0 ) {318					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;319					position.top += overTop - newOverBottom;320				// element is initially over bottom of within321				} else if ( overBottom > 0 && overTop <= 0 ) {322					position.top = withinOffset;323				// element is initially over both top and bottom of within324				} else {325					if ( overTop > overBottom ) {326						position.top = withinOffset + outerHeight - data.collisionHeight;327					} else {328						position.top = withinOffset;329					}330				}331			// too far up -> align with top332			} else if ( overTop > 0 ) {333				position.top += overTop;334			// too far down -> align with bottom edge335			} else if ( overBottom > 0 ) {336				position.top -= overBottom;337			// adjust based on position and margin338			} else {339				position.top = max( position.top - collisionPosTop, position.top );340			}341		}342	},343	flip: {344		left: function( position, data ) {345			var within = data.within,346				withinOffset = within.offset.left + within.scrollLeft,347				outerWidth = within.width,348				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,349				collisionPosLeft = position.left - data.collisionPosition.marginLeft,350				overLeft = collisionPosLeft - offsetLeft,351				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,352				myOffset = data.my[ 0 ] === "left" ?353					-data.elemWidth :354					data.my[ 0 ] === "right" ?355						data.elemWidth :356						0,357				atOffset = data.at[ 0 ] === "left" ?358					data.targetWidth :359					data.at[ 0 ] === "right" ?360						-data.targetWidth :361						0,362				offset = -2 * data.offset[ 0 ],363				newOverRight,364				newOverLeft;365			if ( overLeft < 0 ) {366				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;367				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {368					position.left += myOffset + atOffset + offset;369				}370			}371			else if ( overRight > 0 ) {372				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;373				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {374					position.left += myOffset + atOffset + offset;375				}376			}377		},378		top: function( position, data ) {379			var within = data.within,380				withinOffset = within.offset.top + within.scrollTop,381				outerHeight = within.height,382				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,383				collisionPosTop = position.top - data.collisionPosition.marginTop,384				overTop = collisionPosTop - offsetTop,385				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,386				top = data.my[ 1 ] === "top",387				myOffset = top ?388					-data.elemHeight :389					data.my[ 1 ] === "bottom" ?390						data.elemHeight :391						0,392				atOffset = data.at[ 1 ] === "top" ?393					data.targetHeight :394					data.at[ 1 ] === "bottom" ?395						-data.targetHeight :396						0,397				offset = -2 * data.offset[ 1 ],398				newOverTop,399				newOverBottom;400			if ( overTop < 0 ) {401				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;402				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {403					position.top += myOffset + atOffset + offset;404				}405			}406			else if ( overBottom > 0 ) {407				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;408				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {409					position.top += myOffset + atOffset + offset;410				}411			}412		}413	},414	flipfit: {415		left: function() {416			$.ui.position.flip.left.apply( this, arguments );417			$.ui.position.fit.left.apply( this, arguments );418		},419		top: function() {420			$.ui.position.flip.top.apply( this, arguments );421			$.ui.position.fit.top.apply( this, arguments );422		}423	}424};425// fraction support test426(function () {427	var testElement, testElementParent, testElementStyle, offsetLeft, i,428		body = document.getElementsByTagName( "body" )[ 0 ],429		div = document.createElement( "div" );430	//Create a "fake body" for testing based on method used in jQuery.support431	testElement = document.createElement( body ? "div" : "body" );432	testElementStyle = {433		visibility: "hidden",434		width: 0,435		height: 0,436		border: 0,437		margin: 0,438		background: "none"439	};440	if ( body ) {441		$.extend( testElementStyle, {442			position: "absolute",443			left: "-1000px",444			top: "-1000px"445		});446	}447	for ( i in testElementStyle ) {448		testElement.style[ i ] = testElementStyle[ i ];449	}450	testElement.appendChild( div );451	testElementParent = body || document.documentElement;452	testElementParent.insertBefore( testElement, testElementParent.firstChild );453	div.style.cssText = "position: absolute; left: 10.7432222px;";454	offsetLeft = $( div ).offset().left;455	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;456	testElement.innerHTML = "";457	testElementParent.removeChild( testElement );458})();...position.js
Source:position.js  
1/*!2 * jQuery UI Position 1.12.13 * http://jqueryui.com4 *5 * Copyright jQuery Foundation and other contributors6 * Released under the MIT license.7 * http://jquery.org/license8 *9 * http://api.jqueryui.com/position/10 */11//>>label: Position12//>>group: Core13//>>description: Positions elements relative to other elements.14//>>docs: http://api.jqueryui.com/position/15//>>demos: http://jqueryui.com/position/16( function( factory ) {17	if ( typeof define === "function" && define.amd ) {18		// AMD. Register as an anonymous module.19		define( [ "jquery", "./version" ], factory );20	} else {21		// Browser globals22		factory( jQuery );23	}24}( function( $ ) {25( function() {26var cachedScrollbarWidth,27	max = Math.max,28	abs = Math.abs,29	rhorizontal = /left|center|right/,30	rvertical = /top|center|bottom/,31	roffset = /[\+\-]\d+(\.[\d]+)?%?/,32	rposition = /^\w+/,33	rpercent = /%$/,34	_position = $.fn.position;35function getOffsets( offsets, width, height ) {36	return [37		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),38		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )39	];40}41function parseCss( element, property ) {42	return parseInt( $.css( element, property ), 10 ) || 0;43}44function getDimensions( elem ) {45	var raw = elem[ 0 ];46	if ( raw.nodeType === 9 ) {47		return {48			width: elem.width(),49			height: elem.height(),50			offset: { top: 0, left: 0 }51		};52	}53	if ( $.isWindow( raw ) ) {54		return {55			width: elem.width(),56			height: elem.height(),57			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }58		};59	}60	if ( raw.preventDefault ) {61		return {62			width: 0,63			height: 0,64			offset: { top: raw.pageY, left: raw.pageX }65		};66	}67	return {68		width: elem.outerWidth(),69		height: elem.outerHeight(),70		offset: elem.offset()71	};72}73$.position = {74	scrollbarWidth: function() {75		if ( cachedScrollbarWidth !== undefined ) {76			return cachedScrollbarWidth;77		}78		var w1, w2,79			div = $( "<div " +80				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +81				"<div style='height:100px;width:auto;'></div></div>" ),82			innerDiv = div.children()[ 0 ];83		$( "body" ).append( div );84		w1 = innerDiv.offsetWidth;85		div.css( "overflow", "scroll" );86		w2 = innerDiv.offsetWidth;87		if ( w1 === w2 ) {88			w2 = div[ 0 ].clientWidth;89		}90		div.remove();91		return ( cachedScrollbarWidth = w1 - w2 );92	},93	getScrollInfo: function( within ) {94		var overflowX = within.isWindow || within.isDocument ? "" :95				within.element.css( "overflow-x" ),96			overflowY = within.isWindow || within.isDocument ? "" :97				within.element.css( "overflow-y" ),98			hasOverflowX = overflowX === "scroll" ||99				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),100			hasOverflowY = overflowY === "scroll" ||101				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );102		return {103			width: hasOverflowY ? $.position.scrollbarWidth() : 0,104			height: hasOverflowX ? $.position.scrollbarWidth() : 0105		};106	},107	getWithinInfo: function( element ) {108		var withinElement = $( element || window ),109			isWindow = $.isWindow( withinElement[ 0 ] ),110			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,111			hasOffset = !isWindow && !isDocument;112		return {113			element: withinElement,114			isWindow: isWindow,115			isDocument: isDocument,116			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },117			scrollLeft: withinElement.scrollLeft(),118			scrollTop: withinElement.scrollTop(),119			width: withinElement.outerWidth(),120			height: withinElement.outerHeight()121		};122	}123};124$.fn.position = function( options ) {125	if ( !options || !options.of ) {126		return _position.apply( this, arguments );127	}128	// Make a copy, we don't want to modify arguments129	options = $.extend( {}, options );130	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,131		target = $( options.of ),132		within = $.position.getWithinInfo( options.within ),133		scrollInfo = $.position.getScrollInfo( within ),134		collision = ( options.collision || "flip" ).split( " " ),135		offsets = {};136	dimensions = getDimensions( target );137	if ( target[ 0 ].preventDefault ) {138		// Force left top to allow flipping139		options.at = "left top";140	}141	targetWidth = dimensions.width;142	targetHeight = dimensions.height;143	targetOffset = dimensions.offset;144	// Clone to reuse original targetOffset later145	basePosition = $.extend( {}, targetOffset );146	// Force my and at to have valid horizontal and vertical positions147	// if a value is missing or invalid, it will be converted to center148	$.each( [ "my", "at" ], function() {149		var pos = ( options[ this ] || "" ).split( " " ),150			horizontalOffset,151			verticalOffset;152		if ( pos.length === 1 ) {153			pos = rhorizontal.test( pos[ 0 ] ) ?154				pos.concat( [ "center" ] ) :155				rvertical.test( pos[ 0 ] ) ?156					[ "center" ].concat( pos ) :157					[ "center", "center" ];158		}159		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";160		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";161		// Calculate offsets162		horizontalOffset = roffset.exec( pos[ 0 ] );163		verticalOffset = roffset.exec( pos[ 1 ] );164		offsets[ this ] = [165			horizontalOffset ? horizontalOffset[ 0 ] : 0,166			verticalOffset ? verticalOffset[ 0 ] : 0167		];168		// Reduce to just the positions without the offsets169		options[ this ] = [170			rposition.exec( pos[ 0 ] )[ 0 ],171			rposition.exec( pos[ 1 ] )[ 0 ]172		];173	} );174	// Normalize collision option175	if ( collision.length === 1 ) {176		collision[ 1 ] = collision[ 0 ];177	}178	if ( options.at[ 0 ] === "right" ) {179		basePosition.left += targetWidth;180	} else if ( options.at[ 0 ] === "center" ) {181		basePosition.left += targetWidth / 2;182	}183	if ( options.at[ 1 ] === "bottom" ) {184		basePosition.top += targetHeight;185	} else if ( options.at[ 1 ] === "center" ) {186		basePosition.top += targetHeight / 2;187	}188	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );189	basePosition.left += atOffset[ 0 ];190	basePosition.top += atOffset[ 1 ];191	return this.each( function() {192		var collisionPosition, using,193			elem = $( this ),194			elemWidth = elem.outerWidth(),195			elemHeight = elem.outerHeight(),196			marginLeft = parseCss( this, "marginLeft" ),197			marginTop = parseCss( this, "marginTop" ),198			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +199				scrollInfo.width,200			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +201				scrollInfo.height,202			position = $.extend( {}, basePosition ),203			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );204		if ( options.my[ 0 ] === "right" ) {205			position.left -= elemWidth;206		} else if ( options.my[ 0 ] === "center" ) {207			position.left -= elemWidth / 2;208		}209		if ( options.my[ 1 ] === "bottom" ) {210			position.top -= elemHeight;211		} else if ( options.my[ 1 ] === "center" ) {212			position.top -= elemHeight / 2;213		}214		position.left += myOffset[ 0 ];215		position.top += myOffset[ 1 ];216		collisionPosition = {217			marginLeft: marginLeft,218			marginTop: marginTop219		};220		$.each( [ "left", "top" ], function( i, dir ) {221			if ( $.ui.position[ collision[ i ] ] ) {222				$.ui.position[ collision[ i ] ][ dir ]( position, {223					targetWidth: targetWidth,224					targetHeight: targetHeight,225					elemWidth: elemWidth,226					elemHeight: elemHeight,227					collisionPosition: collisionPosition,228					collisionWidth: collisionWidth,229					collisionHeight: collisionHeight,230					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],231					my: options.my,232					at: options.at,233					within: within,234					elem: elem235				} );236			}237		} );238		if ( options.using ) {239			// Adds feedback as second argument to using callback, if present240			using = function( props ) {241				var left = targetOffset.left - position.left,242					right = left + targetWidth - elemWidth,243					top = targetOffset.top - position.top,244					bottom = top + targetHeight - elemHeight,245					feedback = {246						target: {247							element: target,248							left: targetOffset.left,249							top: targetOffset.top,250							width: targetWidth,251							height: targetHeight252						},253						element: {254							element: elem,255							left: position.left,256							top: position.top,257							width: elemWidth,258							height: elemHeight259						},260						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",261						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"262					};263				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {264					feedback.horizontal = "center";265				}266				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {267					feedback.vertical = "middle";268				}269				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {270					feedback.important = "horizontal";271				} else {272					feedback.important = "vertical";273				}274				options.using.call( this, props, feedback );275			};276		}277		elem.offset( $.extend( position, { using: using } ) );278	} );279};280$.ui.position = {281	fit: {282		left: function( position, data ) {283			var within = data.within,284				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,285				outerWidth = within.width,286				collisionPosLeft = position.left - data.collisionPosition.marginLeft,287				overLeft = withinOffset - collisionPosLeft,288				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,289				newOverRight;290			// Element is wider than within291			if ( data.collisionWidth > outerWidth ) {292				// Element is initially over the left side of within293				if ( overLeft > 0 && overRight <= 0 ) {294					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -295						withinOffset;296					position.left += overLeft - newOverRight;297				// Element is initially over right side of within298				} else if ( overRight > 0 && overLeft <= 0 ) {299					position.left = withinOffset;300				// Element is initially over both left and right sides of within301				} else {302					if ( overLeft > overRight ) {303						position.left = withinOffset + outerWidth - data.collisionWidth;304					} else {305						position.left = withinOffset;306					}307				}308			// Too far left -> align with left edge309			} else if ( overLeft > 0 ) {310				position.left += overLeft;311			// Too far right -> align with right edge312			} else if ( overRight > 0 ) {313				position.left -= overRight;314			// Adjust based on position and margin315			} else {316				position.left = max( position.left - collisionPosLeft, position.left );317			}318		},319		top: function( position, data ) {320			var within = data.within,321				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,322				outerHeight = data.within.height,323				collisionPosTop = position.top - data.collisionPosition.marginTop,324				overTop = withinOffset - collisionPosTop,325				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,326				newOverBottom;327			// Element is taller than within328			if ( data.collisionHeight > outerHeight ) {329				// Element is initially over the top of within330				if ( overTop > 0 && overBottom <= 0 ) {331					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -332						withinOffset;333					position.top += overTop - newOverBottom;334				// Element is initially over bottom of within335				} else if ( overBottom > 0 && overTop <= 0 ) {336					position.top = withinOffset;337				// Element is initially over both top and bottom of within338				} else {339					if ( overTop > overBottom ) {340						position.top = withinOffset + outerHeight - data.collisionHeight;341					} else {342						position.top = withinOffset;343					}344				}345			// Too far up -> align with top346			} else if ( overTop > 0 ) {347				position.top += overTop;348			// Too far down -> align with bottom edge349			} else if ( overBottom > 0 ) {350				position.top -= overBottom;351			// Adjust based on position and margin352			} else {353				position.top = max( position.top - collisionPosTop, position.top );354			}355		}356	},357	flip: {358		left: function( position, data ) {359			var within = data.within,360				withinOffset = within.offset.left + within.scrollLeft,361				outerWidth = within.width,362				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,363				collisionPosLeft = position.left - data.collisionPosition.marginLeft,364				overLeft = collisionPosLeft - offsetLeft,365				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,366				myOffset = data.my[ 0 ] === "left" ?367					-data.elemWidth :368					data.my[ 0 ] === "right" ?369						data.elemWidth :370						0,371				atOffset = data.at[ 0 ] === "left" ?372					data.targetWidth :373					data.at[ 0 ] === "right" ?374						-data.targetWidth :375						0,376				offset = -2 * data.offset[ 0 ],377				newOverRight,378				newOverLeft;379			if ( overLeft < 0 ) {380				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -381					outerWidth - withinOffset;382				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {383					position.left += myOffset + atOffset + offset;384				}385			} else if ( overRight > 0 ) {386				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +387					atOffset + offset - offsetLeft;388				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {389					position.left += myOffset + atOffset + offset;390				}391			}392		},393		top: function( position, data ) {394			var within = data.within,395				withinOffset = within.offset.top + within.scrollTop,396				outerHeight = within.height,397				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,398				collisionPosTop = position.top - data.collisionPosition.marginTop,399				overTop = collisionPosTop - offsetTop,400				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,401				top = data.my[ 1 ] === "top",402				myOffset = top ?403					-data.elemHeight :404					data.my[ 1 ] === "bottom" ?405						data.elemHeight :406						0,407				atOffset = data.at[ 1 ] === "top" ?408					data.targetHeight :409					data.at[ 1 ] === "bottom" ?410						-data.targetHeight :411						0,412				offset = -2 * data.offset[ 1 ],413				newOverTop,414				newOverBottom;415			if ( overTop < 0 ) {416				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -417					outerHeight - withinOffset;418				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {419					position.top += myOffset + atOffset + offset;420				}421			} else if ( overBottom > 0 ) {422				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +423					offset - offsetTop;424				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {425					position.top += myOffset + atOffset + offset;426				}427			}428		}429	},430	flipfit: {431		left: function() {432			$.ui.position.flip.left.apply( this, arguments );433			$.ui.position.fit.left.apply( this, arguments );434		},435		top: function() {436			$.ui.position.flip.top.apply( this, arguments );437			$.ui.position.fit.top.apply( this, arguments );438		}439	}440};441} )();442return $.ui.position;...FocusWithin-test.internal.js
Source:FocusWithin-test.internal.js  
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @emails react-core8 */9'use strict';10import {createEventTarget, setPointerEvent} from 'dom-event-testing-library';11let React;12let ReactFeatureFlags;13let ReactDOM;14let FocusWithinResponder;15let useFocusWithin;16let Scheduler;17const initializeModules = hasPointerEvents => {18  setPointerEvent(hasPointerEvents);19  jest.resetModules();20  ReactFeatureFlags = require('shared/ReactFeatureFlags');21  ReactFeatureFlags.enableDeprecatedFlareAPI = true;22  React = require('react');23  ReactDOM = require('react-dom');24  FocusWithinResponder = require('react-interactions/events/focus')25    .FocusWithinResponder;26  useFocusWithin = require('react-interactions/events/focus').useFocusWithin;27  Scheduler = require('scheduler');28};29const forcePointerEvents = true;30const table = [[forcePointerEvents], [!forcePointerEvents]];31describe.each(table)('FocusWithin responder', hasPointerEvents => {32  let container;33  if (!__EXPERIMENTAL__) {34    it("empty test so Jest doesn't complain", () => {});35    return;36  }37  beforeEach(() => {38    initializeModules();39    container = document.createElement('div');40    document.body.appendChild(container);41  });42  afterEach(() => {43    ReactDOM.render(null, container);44    document.body.removeChild(container);45    container = null;46  });47  describe('disabled', () => {48    let onFocusWithinChange, onFocusWithinVisibleChange, ref;49    beforeEach(() => {50      onFocusWithinChange = jest.fn();51      onFocusWithinVisibleChange = jest.fn();52      ref = React.createRef();53      const Component = () => {54        const listener = useFocusWithin({55          disabled: true,56          onFocusWithinChange,57          onFocusWithinVisibleChange,58        });59        return <div ref={ref} DEPRECATED_flareListeners={listener} />;60      };61      ReactDOM.render(<Component />, container);62    });63    it('prevents custom events being dispatched', () => {64      const target = createEventTarget(ref.current);65      target.focus();66      target.blur();67      expect(onFocusWithinChange).not.toBeCalled();68      expect(onFocusWithinVisibleChange).not.toBeCalled();69    });70  });71  describe('onFocusWithinChange', () => {72    let onFocusWithinChange, ref, innerRef, innerRef2;73    const Component = ({show}) => {74      const listener = useFocusWithin({75        onFocusWithinChange,76      });77      return (78        <div ref={ref} DEPRECATED_flareListeners={listener}>79          {show && <input ref={innerRef} />}80          <div ref={innerRef2} />81        </div>82      );83    };84    beforeEach(() => {85      onFocusWithinChange = jest.fn();86      ref = React.createRef();87      innerRef = React.createRef();88      innerRef2 = React.createRef();89      ReactDOM.render(<Component show={true} />, container);90    });91    it('is called after "blur" and "focus" events on focus target', () => {92      const target = createEventTarget(ref.current);93      target.focus();94      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);95      expect(onFocusWithinChange).toHaveBeenCalledWith(true);96      target.blur({relatedTarget: container});97      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);98      expect(onFocusWithinChange).toHaveBeenCalledWith(false);99    });100    it('is called after "blur" and "focus" events on descendants', () => {101      const target = createEventTarget(innerRef.current);102      target.focus();103      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);104      expect(onFocusWithinChange).toHaveBeenCalledWith(true);105      target.blur({relatedTarget: container});106      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);107      expect(onFocusWithinChange).toHaveBeenCalledWith(false);108    });109    it('is only called once when focus moves within and outside the subtree', () => {110      const node = ref.current;111      const innerNode1 = innerRef.current;112      const innerNode2 = innerRef.current;113      const target = createEventTarget(node);114      const innerTarget1 = createEventTarget(innerNode1);115      const innerTarget2 = createEventTarget(innerNode2);116      // focus shifts into subtree117      innerTarget1.focus();118      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);119      expect(onFocusWithinChange).toHaveBeenCalledWith(true);120      // focus moves around subtree121      innerTarget1.blur({relatedTarget: innerNode2});122      innerTarget2.focus();123      innerTarget2.blur({relatedTarget: node});124      target.focus();125      target.blur({relatedTarget: innerNode1});126      expect(onFocusWithinChange).toHaveBeenCalledTimes(1);127      // focus shifts outside subtree128      innerTarget1.blur({relatedTarget: container});129      expect(onFocusWithinChange).toHaveBeenCalledTimes(2);130      expect(onFocusWithinChange).toHaveBeenCalledWith(false);131    });132  });133  describe('onFocusWithinVisibleChange', () => {134    let onFocusWithinVisibleChange, ref, innerRef, innerRef2;135    const Component = ({show}) => {136      const listener = useFocusWithin({137        onFocusWithinVisibleChange,138      });139      return (140        <div ref={ref} DEPRECATED_flareListeners={listener}>141          {show && <input ref={innerRef} />}142          <div ref={innerRef2} />143        </div>144      );145    };146    beforeEach(() => {147      onFocusWithinVisibleChange = jest.fn();148      ref = React.createRef();149      innerRef = React.createRef();150      innerRef2 = React.createRef();151      ReactDOM.render(<Component show={true} />, container);152    });153    it('is called after "focus" and "blur" on focus target if keyboard was used', () => {154      const target = createEventTarget(ref.current);155      const containerTarget = createEventTarget(container);156      // use keyboard first157      containerTarget.keydown({key: 'Tab'});158      target.focus();159      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);160      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);161      target.blur({relatedTarget: container});162      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);163      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);164    });165    it('is called after "focus" and "blur" on descendants if keyboard was used', () => {166      const innerTarget = createEventTarget(innerRef.current);167      const containerTarget = createEventTarget(container);168      // use keyboard first169      containerTarget.keydown({key: 'Tab'});170      innerTarget.focus();171      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);172      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);173      innerTarget.blur({relatedTarget: container});174      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);175      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);176    });177    it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => {178      const node = ref.current;179      const innerNode1 = innerRef.current;180      const innerNode2 = innerRef2.current;181      const target = createEventTarget(node);182      const innerTarget1 = createEventTarget(innerNode1);183      const innerTarget2 = createEventTarget(innerNode2);184      // use keyboard first185      target.focus();186      target.keydown({key: 'Tab'});187      target.blur({relatedTarget: innerNode1});188      innerTarget1.focus();189      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);190      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);191      // then use pointer on the next target, focus should no longer be visible192      innerTarget2.pointerdown();193      innerTarget1.blur({relatedTarget: innerNode2});194      innerTarget2.focus();195      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);196      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);197      // then use keyboard again198      innerTarget2.keydown({key: 'Tab', shiftKey: true});199      innerTarget2.blur({relatedTarget: innerNode1});200      innerTarget1.focus();201      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(3);202      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);203      // then use pointer on the target, focus should no longer be visible204      innerTarget1.pointerdown();205      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4);206      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);207      // onFocusVisibleChange should not be called again208      innerTarget1.blur({relatedTarget: container});209      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(4);210    });211    it('is not called after "focus" and "blur" events without keyboard', () => {212      const innerTarget = createEventTarget(innerRef.current);213      innerTarget.pointerdown();214      innerTarget.pointerup();215      innerTarget.blur({relatedTarget: container});216      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(0);217    });218    it('is only called once when focus moves within and outside the subtree', () => {219      const node = ref.current;220      const innerNode1 = innerRef.current;221      const innerNode2 = innerRef2.current;222      const target = createEventTarget(node);223      const innerTarget1 = createEventTarget(innerNode1);224      const innerTarget2 = createEventTarget(innerNode2);225      // focus shifts into subtree226      innerTarget1.focus();227      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);228      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(true);229      // focus moves around subtree230      innerTarget1.blur({relatedTarget: innerNode2});231      innerTarget2.focus();232      innerTarget2.blur({relatedTarget: node});233      target.focus();234      target.blur({relatedTarget: innerNode1});235      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(1);236      // focus shifts outside subtree237      innerTarget1.blur({relatedTarget: container});238      expect(onFocusWithinVisibleChange).toHaveBeenCalledTimes(2);239      expect(onFocusWithinVisibleChange).toHaveBeenCalledWith(false);240    });241  });242  describe('onBeforeBlurWithin', () => {243    let onBeforeBlurWithin, onBlurWithin, ref, innerRef, innerRef2;244    beforeEach(() => {245      onBeforeBlurWithin = jest.fn();246      onBlurWithin = jest.fn();247      ref = React.createRef();248      innerRef = React.createRef();249      innerRef2 = React.createRef();250    });251    it('is called after a focused element is unmounted', () => {252      const Component = ({show}) => {253        const listener = useFocusWithin({254          onBeforeBlurWithin,255          onBlurWithin,256        });257        return (258          <div ref={ref} DEPRECATED_flareListeners={listener}>259            {show && <input ref={innerRef} />}260            <div ref={innerRef2} />261          </div>262        );263      };264      ReactDOM.render(<Component show={true} />, container);265      const inner = innerRef.current;266      const target = createEventTarget(inner);267      target.keydown({key: 'Tab'});268      target.focus();269      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);270      expect(onBlurWithin).toHaveBeenCalledTimes(0);271      ReactDOM.render(<Component show={false} />, container);272      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);273      expect(onBlurWithin).toHaveBeenCalledTimes(1);274      expect(onBlurWithin).toHaveBeenCalledWith(275        expect.objectContaining({isTargetAttached: false}),276      );277    });278    it('is called after a nested focused element is unmounted', () => {279      const Component = ({show}) => {280        const listener = useFocusWithin({281          onBeforeBlurWithin,282          onBlurWithin,283        });284        return (285          <div ref={ref} DEPRECATED_flareListeners={listener}>286            {show && (287              <div>288                <input ref={innerRef} />289              </div>290            )}291            <div ref={innerRef2} />292          </div>293        );294      };295      ReactDOM.render(<Component show={true} />, container);296      const inner = innerRef.current;297      const target = createEventTarget(inner);298      target.keydown({key: 'Tab'});299      target.focus();300      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);301      expect(onBlurWithin).toHaveBeenCalledTimes(0);302      ReactDOM.render(<Component show={false} />, container);303      expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);304      expect(onBlurWithin).toHaveBeenCalledTimes(1);305      expect(onBlurWithin).toHaveBeenCalledWith(306        expect.objectContaining({isTargetAttached: false}),307      );308    });309    it.experimental(310      'is called after a focused suspended element is hidden',311      () => {312        const Suspense = React.Suspense;313        let suspend = false;314        let resolve;315        let promise = new Promise(resolvePromise => (resolve = resolvePromise));316        function Child() {317          if (suspend) {318            throw promise;319          } else {320            return <input ref={innerRef} />;321          }322        }323        const Component = ({show}) => {324          const listener = useFocusWithin({325            onBeforeBlurWithin,326            onBlurWithin,327          });328          return (329            <div DEPRECATED_flareListeners={listener}>330              <Suspense fallback="Loading...">331                <Child />332              </Suspense>333            </div>334          );335        };336        const container2 = document.createElement('div');337        document.body.appendChild(container2);338        let root = ReactDOM.createRoot(container2);339        root.render(<Component />);340        Scheduler.unstable_flushAll();341        jest.runAllTimers();342        expect(container2.innerHTML).toBe('<div><input></div>');343        const inner = innerRef.current;344        const target = createEventTarget(inner);345        target.keydown({key: 'Tab'});346        target.focus();347        expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);348        expect(onBlurWithin).toHaveBeenCalledTimes(0);349        suspend = true;350        root.render(<Component />);351        Scheduler.unstable_flushAll();352        jest.runAllTimers();353        expect(container2.innerHTML).toBe(354          '<div><input style="display: none;">Loading...</div>',355        );356        expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);357        expect(onBlurWithin).toHaveBeenCalledTimes(1);358        resolve();359        document.body.removeChild(container2);360      },361    );362  });363  it('expect displayName to show up for event component', () => {364    expect(FocusWithinResponder.displayName).toBe('FocusWithin');365  });...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
