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!!