Best Python code snippet using pom_python
swipe-back.js
Source:swipe-back.js  
...290      // Update Route291      router.currentRoute = previousPage[0].f7Page.route;292      router.currentPage = previousPage[0];293      // Page before animation callback294      router.pageCallback('beforeOut', currentPage, currentNavbar, 'current', 'next', { route: currentPage[0].f7Page.route, swipeBack: true });295      router.pageCallback('beforeIn', previousPage, previousNavbar, 'previous', 'current', { route: previousPage[0].f7Page.route, swipeBack: true });296      $el.trigger('swipeback:beforechange', callbackData);297      router.emit('swipebackBeforeChange', callbackData);298    } else {299      $el.trigger('swipeback:beforereset', callbackData);300      router.emit('swipebackBeforeReset', callbackData);301    }302    currentPage.transitionEnd(() => {303      $([currentPage[0], previousPage[0]]).removeClass('page-transitioning page-transitioning-swipeback');304      if (dynamicNavbar) {305        currentNavElements.removeClass('navbar-transitioning').css({ opacity: '' }).transform('');306        previousNavElements.removeClass('navbar-transitioning').css({ opacity: '' }).transform('');307        if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.removeClass('navbar-transitioning');308        if (previousNavBackIcon && previousNavBackIcon.length > 0) previousNavBackIcon.removeClass('navbar-transitioning');309      }310      allowViewTouchMove = true;311      router.allowPageChange = true;312      if (pageChanged) {313        // Update History314        if (router.history.length === 1) {315          router.history.unshift(router.url);316        }317        router.history.pop();318        router.saveHistory();319        // Update push state320        if (params.pushState) {321          History.back();322        }323        // Page after animation callback324        router.pageCallback('afterOut', currentPage, currentNavbar, 'current', 'next', { route: currentPage[0].f7Page.route, swipeBack: true });325        router.pageCallback('afterIn', previousPage, previousNavbar, 'previous', 'current', { route: previousPage[0].f7Page.route, swipeBack: true });326        // Remove Old Page327        if (params.stackPages && router.initialPages.indexOf(currentPage[0]) >= 0) {328          currentPage.addClass('stacked');329          if (separateNavbar) {330            currentNavbar.addClass('stacked');331          }332        } else {333          router.pageCallback('beforeRemove', currentPage, currentNavbar, 'next', { swipeBack: true });334          router.removePage(currentPage);335          if (separateNavbar) {336            router.removeNavbar(currentNavbar);337          }338        }339        $el.trigger('swipeback:afterchange', callbackData);340        router.emit('swipebackAfterChange', callbackData);341        router.emit('routeChanged', router.currentRoute, router.previousRoute, router);342        if (params.preloadPreviousPage) {343          router.back(router.history[router.history.length - 2], { preload: true });344        }345      } else {346        $el.trigger('swipeback:afterreset', callbackData);347        router.emit('swipebackAfterReset', callbackData);348      }349      if (pageShadow && pageShadow.length > 0) pageShadow.remove();350      if (pageOpacity && pageOpacity.length > 0) pageOpacity.remove();351    });352  }353  function attachEvents() {354    const passiveListener = (app.touchEvents.start === 'touchstart' && Support.passiveListener) ? { passive: true, capture: false } : false;355    $el.on(app.touchEvents.start, handleTouchStart, passiveListener);356    app.on('touchmove:active', handleTouchMove);357    app.on('touchend:passive', handleTouchEnd);...Bar.js
Source:Bar.js  
1/**2 * This component is used in {@link Ext.navigation.View} to control animations in the toolbar. You should never need to3 * interact with the component directly, unless you are subclassing it.4 * @private5 * @author Robert Dougan <rob@sencha.com>6 */7Ext.define('Ext.navigation.Bar', {8    extend: 'Ext.TitleBar',9    requires: [10        'Ext.Button',11        'Ext.Spacer'12    ],13    // private14    isToolbar: true,15    config: {16        /**17         * @cfg18         * @inheritdoc19         */20        baseCls: Ext.baseCSSPrefix + 'toolbar',21        /**22         * @cfg23         * @inheritdoc24         */25        cls: Ext.baseCSSPrefix + 'navigation-bar',26        /**27         * @cfg {String} ui28         * Style options for Toolbar. Either 'light' or 'dark'.29         * @accessor30         */31        ui: 'dark',32        /**33         * @cfg {String} title34         * The title of the toolbar. You should NEVER set this, it is used internally. You set the title of the35         * navigation bar by giving a navigation views children a title configuration.36         * @private37         * @accessor38         */39        title: null,40        /**41         * @cfg42         * @hide43         * @accessor44         */45        defaultType: 'button',46        /**47         * @cfg48         * @ignore49         * @accessor50         */51        layout: {52            type: 'hbox'53        },54        /**55         * @cfg {Array/Object} items The child items to add to this NavigationBar. The {@link #cfg-defaultType} of56         * a NavigationBar is {@link Ext.Button}, so you do not need to specify an `xtype` if you are adding57         * buttons.58         *59         * You can also give items a `align` configuration which will align the item to the `left` or `right` of60         * the NavigationBar.61         * @hide62         * @accessor63         */64        /**65         * @cfg {String} defaultBackButtonText66         * The text to be displayed on the back button if:67         * a) The previous view does not have a title68         * b) The {@link #useTitleForBackButtonText} configuration is true.69         * @private70         * @accessor71         */72        defaultBackButtonText: 'Back',73        /**74         * @cfg {Object} animation75         * @private76         * @accessor77         */78        animation: {79            duration: 30080        },81        /**82         * @cfg {Boolean} useTitleForBackButtonText83         * Set to false if you always want to display the {@link #defaultBackButtonText} as the text84         * on the back button. True if you want to use the previous views title.85         * @private86         * @accessor87         */88        useTitleForBackButtonText: null,89        /**90         * @cfg {Ext.navigation.View} view A reference to the navigation view this bar is linked to.91         * @private92         * @accessor93         */94        view: null,95        /**96         * @cfg {Boolean} androidAnimation Optionally enable CSS transforms on Android 297         * for NavigationBar animations.  Note that this may cause flickering if the98         * NavigationBar is hidden.99         * @accessor100         */101        android2Transforms: false,102        /**103         * @cfg {Ext.Button/Object} backButton The configuration for the back button104         * @private105         * @accessor106         */107        backButton: {108            align: 'left',109            ui: 'back',110            hidden: true111        }112    },113    /**114     * @event back115     * Fires when the back button was tapped.116     * @param {Ext.navigation.Bar} this This bar117     */118    /**119     * The minmum back button width allowed.120     * @private121     */122    minBackButtonWidth: 80,123    constructor: function(config) {124        config = config || {};125        if (!config.items) {126            config.items = [];127        }128        this.backButtonStack = [];129        this.activeAnimations = [];130        this.callParent([config]);131    },132    /**133     * @private134     */135    applyBackButton: function(config) {136        return Ext.factory(config, Ext.Button, this.getBackButton());137    },138    /**139     * @private140     */141    updateBackButton: function(newBackButton, oldBackButton) {142        if (oldBackButton) {143            this.remove(oldBackButton);144        }145        if (newBackButton) {146            this.add(newBackButton);147            newBackButton.on({148                scope: this,149                tap: this.onBackButtonTap150            });151        }152    },153    onBackButtonTap: function() {154        this.fireEvent('back', this);155    },156    /**157     * @private158     */159    updateView: function(newView) {160        var me = this,161            backButton = me.getBackButton(),162            innerItems, i, backButtonText, item, title;163        me.getItems();164        if (newView) {165            //update the back button stack with the current inner items of the view166            innerItems = newView.getInnerItems();167            for (i = 0; i < innerItems.length; i++) {168                item = innerItems[i];169                title = (item.getTitle) ? item.getTitle() : item.config.title;170                me.backButtonStack.push(title || ' ');171            }172            me.setTitle(me.getTitleText());173            backButtonText = me.getBackButtonText();174            if (backButtonText) {175                backButton.setText(backButtonText);176                backButton.show();177            }178        }179    },180    /**181     * @private182     */183    onViewAdd: function(view, item) {184        var me = this,185            backButtonStack = me.backButtonStack,186            hasPrevious, title;187        me.endAnimation();188        title = (item.getTitle) ? item.getTitle() : item.config.title;189        backButtonStack.push(title || ' ');190        hasPrevious = backButtonStack.length > 1;191        me.doChangeView(view, hasPrevious, false);192    },193    /**194     * @private195     */196    onViewRemove: function(view) {197        var me = this,198            backButtonStack = me.backButtonStack,199            hasPrevious;200        me.endAnimation();201        backButtonStack.pop();202        hasPrevious = backButtonStack.length > 1;203        me.doChangeView(view, hasPrevious, true);204    },205    /**206     * @private207     */208    doChangeView: function(view, hasPrevious, reverse) {209        var me = this,210            leftBox = me.leftBox,211            leftBoxElement = leftBox.element,212            titleComponent = me.titleComponent,213            titleElement = titleComponent.element,214            backButton = me.getBackButton(),215            titleText = me.getTitleText(),216            backButtonText = me.getBackButtonText(),217            animation = me.getAnimation() && view.getLayout().getAnimation(),218            animated = animation && animation.isAnimation && view.isPainted(),219            properties, leftGhost, titleGhost, leftProps, titleProps;220        if (animated) {221            leftGhost = me.createProxy(leftBox.element);222            leftBoxElement.setStyle('opacity', '0');223            backButton.setText(backButtonText);224            backButton[hasPrevious ? 'show' : 'hide']();225            titleGhost = me.createProxy(titleComponent.element.getParent());226            titleElement.setStyle('opacity', '0');227            me.setTitle(titleText);228            me.refreshTitlePosition();229            properties = me.measureView(leftGhost, titleGhost, reverse);230            leftProps = properties.left;231            titleProps = properties.title;232            me.isAnimating = true;233            me.animate(leftBoxElement, leftProps.element);234            me.animate(titleElement, titleProps.element, function() {235                titleElement.setLeft(properties.titleLeft);236                me.isAnimating = false;237            });238            if (Ext.os.is.Android2 && !this.getAndroid2Transforms()) {239                leftGhost.ghost.destroy();240                titleGhost.ghost.destroy();241            }242            else {243                me.animate(leftGhost.ghost, leftProps.ghost);244                me.animate(titleGhost.ghost, titleProps.ghost, function() {245                    leftGhost.ghost.destroy();246                    titleGhost.ghost.destroy();247                });248            }249        }250        else {251            if (hasPrevious) {252                backButton.setText(backButtonText);253                backButton.show();254            }255            else {256                backButton.hide();257            }258            me.setTitle(titleText);259        }260    },261    /**262     * Calculates and returns the position values needed for the back button when you are pushing a title.263     * @private264     */265    measureView: function(oldLeft, oldTitle, reverse) {266        var me = this,267            barElement = me.element,268            newLeftElement = me.leftBox.element,269            titleElement = me.titleComponent.element,270            minOffset = Math.min(barElement.getWidth() / 3, 200),271            newLeftWidth = newLeftElement.getWidth(),272            barX = barElement.getX(),273            barWidth = barElement.getWidth(),274            titleX = titleElement.getX(),275            titleLeft = titleElement.getLeft(),276            titleWidth = titleElement.getWidth(),277            oldLeftX = oldLeft.x,278            oldLeftWidth = oldLeft.width,279            oldLeftLeft = oldLeft.left,280            useLeft = Ext.os.is.Android2 && !this.getAndroid2Transforms(),281            newOffset, oldOffset, leftAnims, titleAnims, omega, theta;282        theta = barX - oldLeftX - oldLeftWidth;283        if (reverse) {284            newOffset = theta;285            oldOffset = Math.min(titleX - oldLeftWidth, minOffset);286        }287        else {288            oldOffset = theta;289            newOffset = Math.min(titleX - barX, minOffset);290        }291        if (useLeft) {292            leftAnims = {293                element: {294                    from: {295                        left: newOffset,296                        opacity: 1297                    },298                    to: {299                        left: 0,300                        opacity: 1301                    }302                }303            };304        }305        else {306            leftAnims = {307                element: {308                    from: {309                        transform: {310                            translateX: newOffset311                        },312                        opacity: 0313                    },314                    to: {315                        transform: {316                            translateX: 0317                        },318                        opacity: 1319                    }320                },321                ghost: {322                    to: {323                        transform: {324                            translateX: oldOffset325                        },326                        opacity: 0327                    }328                }329            };330        }331        theta = barX - titleX + newLeftWidth;332        if ((oldLeftLeft + titleWidth) > titleX) {333            omega = barX - titleX - titleWidth;334        }335        if (reverse) {336            titleElement.setLeft(0);337            oldOffset = barX + barWidth;338            if (omega !== undefined) {339                newOffset = omega;340            }341            else {342                newOffset = theta;343            }344        }345        else {346            newOffset = barWidth - titleX;347            if (omega !== undefined) {348                oldOffset = omega;349            }350            else {351                oldOffset = theta;352            }353        }354        if (useLeft) {355            titleAnims = {356                element: {357                    from: {358                        left: newOffset,359                        opacity: 1360                    },361                    to: {362                        left: titleLeft,363                        opacity: 1364                    }365                }366            };367        }368        else {369            titleAnims = {370                element: {371                    from: {372                        transform: {373                            translateX: newOffset374                        },375                        opacity: 0376                    },377                    to: {378                        transform: {379                            translateX: titleLeft380                        },381                        opacity: 1382                    }383                },384                ghost: {385                    to: {386                        transform: {387                            translateX: oldOffset388                        },389                        opacity: 0390                    }391                }392            };393        }394        return {395            left: leftAnims,396            title: titleAnims,397            titleLeft: titleLeft398        };399    },400    /**401     * Helper method used to animate elements.402     * You pass it an element, objects for the from and to positions an option onEnd callback called when the animation is over.403     * Normally this method is passed configurations returned from the methods such as #measureTitle(true) etc.404     * It is called from the #pushLeftBoxAnimated, #pushTitleAnimated, #popBackButtonAnimated and #popTitleAnimated405     * methods.406     *407     * If the current device is Android, it will use top/left to animate.408     * If it is anything else, it will use transform.409     * @private410     */411    animate: function(element, config, callback) {412        var me = this,413            animation;414        //reset the left of the element415        element.setLeft(0);416        config = Ext.apply(config, {417            element: element,418            easing: 'ease-in-out',419            duration: me.getAnimation().duration420        });421        animation = new Ext.fx.Animation(config);422        animation.on('animationend', function() {423            if (callback) {424                callback.call(me);425            }426        }, me);427        Ext.Animator.run(animation);428        me.activeAnimations.push(animation);429    },430    endAnimation: function() {431        var activeAnimations = this.activeAnimations,432            animation, i, ln;433        if (activeAnimations) {434            ln = activeAnimations.length;435            for (i = 0; i < ln; i++) {436                animation = activeAnimations[i];437                if (animation.isAnimating) {438                    animation.stopAnimation();439                }440                else {441                    animation.destroy();442                }443            }444            this.activeAnimations = [];445        }446    },447    refreshTitlePosition: function() {448        if (!this.isAnimating) {449            this.callParent();450        }451    },452    /**453     * Returns the text needed for the current back button at anytime.454     * @private455     */456    getBackButtonText: function() {457        var text = this.backButtonStack[this.backButtonStack.length - 2],458            useTitleForBackButtonText = this.getUseTitleForBackButtonText();459        if (!useTitleForBackButtonText) {460            if (text) {461                text = this.getDefaultBackButtonText();462            }463        }464        return text;465    },466    /**467     * Returns the text needed for the current title at anytime.468     * @private469     */470    getTitleText: function() {471        return this.backButtonStack[this.backButtonStack.length - 1];472    },473    /**474     * Handles removing back button stacks from this bar475     * @private476     */477    beforePop: function(count) {478        count--;479        for (var i = 0; i < count; i++) {480            this.backButtonStack.pop();481        }482    },483    /**484     * We override the hidden method because we don't want to remove it from the view using display:none. Instead we just position it off485     * the screen, much like the navigation bar proxy. This means that all animations, pushing, popping etc. all still work when if you hide/show486     * this bar at any time.487     * @private488     */489    doSetHidden: function(hidden) {490        if (!hidden) {491            this.element.setStyle({492                position: 'relative',493                top: 'auto',494                left: 'auto',495                width: 'auto'496            });497        } else {498            this.element.setStyle({499                position: 'absolute',500                top: '-1000px',501                left: '-1000px',502                width: this.element.getWidth() + 'px'503            });504        }505    },506    /**507     * Creates a proxy element of the passed element, and positions it in the same position, using absolute positioning.508     * The createNavigationBarProxy method uses this to create proxies of the backButton and the title elements.509     * @private510     */511    createProxy: function(element) {512        var ghost, x, y, left, width;513        ghost = element.dom.cloneNode(true);514        ghost.id = element.id + '-proxy';515        //insert it into the toolbar516        element.getParent().dom.appendChild(ghost);517        //set the x/y518        ghost = Ext.get(ghost);519        x = element.getX();520        y = element.getY();521        left = element.getLeft();522        width = element.getWidth();523        ghost.setStyle('position', 'absolute');524        ghost.setX(x);525        ghost.setY(y);526        ghost.setHeight(element.getHeight());527        ghost.setWidth(width);528        return {529            x: x,530            y: y,531            left: left,532            width: width,533            ghost: ghost534        };535    }...back.js
Source:back.js  
1define(["./_base/config", "./_base/lang", "./sniff", "./dom", "./dom-construct", "./_base/window", "require"],2	function(config, lang, has, dom, domConstruct, baseWindow, require){3	// module:4	//		dojo/back5	var back = {6		// summary:7		//		Browser history management resources8	};9	has("extend-dojo") && lang.setObject("dojo.back", back);10	// everyone deals with encoding the hash slightly differently11	var getHash = back.getHash = function(){12		var h = window.location.hash;13		if(h.charAt(0) == "#"){ h = h.substring(1); }14		return has("mozilla") ? h : decodeURIComponent(h);15	},16	setHash = back.setHash = function(h){17		if(!h){ h = ""; }18		window.location.hash = encodeURIComponent(h);19		historyCounter = history.length;20	};21	var initialHref = (typeof(window) !== "undefined") ? window.location.href : "";22	var initialHash = (typeof(window) !== "undefined") ? getHash() : "";23	var initialState = null;24	var locationTimer = null;25	var bookmarkAnchor = null;26	var historyIframe = null;27	var forwardStack = [];28	var historyStack = [];29	var moveForward = false;30	var changingUrl = false;31	var historyCounter;32	function handleBackButton(){33		// summary:34		//		private method. Do not call this directly.35		//The "current" page is always at the top of the history stack.36		var current = historyStack.pop();37		if(!current){ return; }38		var last = historyStack[historyStack.length-1];39		if(!last && historyStack.length == 0){40			last = initialState;41		}42		if(last){43			if(last.kwArgs["back"]){44				last.kwArgs["back"]();45			}else if(last.kwArgs["backButton"]){46				last.kwArgs["backButton"]();47			}else if(last.kwArgs["handle"]){48				last.kwArgs.handle("back");49			}50		}51		forwardStack.push(current);52	}53	back.goBack = handleBackButton;54	function handleForwardButton(){55		// summary:56		//		private method. Do not call this directly.57		var last = forwardStack.pop();58		if(!last){ return; }59		if(last.kwArgs["forward"]){60			last.kwArgs.forward();61		}else if(last.kwArgs["forwardButton"]){62			last.kwArgs.forwardButton();63		}else if(last.kwArgs["handle"]){64			last.kwArgs.handle("forward");65		}66		historyStack.push(last);67	}68	back.goForward = handleForwardButton;69	function createState(url, args, hash){70		// summary:71		//		private method. Do not call this directly.72		return {"url": url, "kwArgs": args, "urlHash": hash};	//Object73	}74	function getUrlQuery(url){75		// summary:76		//		private method. Do not call this directly.77		var segments = url.split("?");78		if(segments.length < 2){79			return null; //null80		}81		else{82			return segments[1]; //String83		}84	}85	function loadIframeHistory(){86		// summary:87		//		private method. Do not call this directly.88		var url = (config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html")) + "?" + (new Date()).getTime();89		moveForward = true;90		if(historyIframe){91			has("webkit") ? historyIframe.location = url : window.frames[historyIframe.name].location = url;92		}else{93			//console.warn("dojo/back: Not initialised. You need to call back.init() from a <script> block that lives inside the <body> tag.");94		}95		return url; //String96	}97	function checkLocation(){98		if(!changingUrl){99			var hsl = historyStack.length;100			var hash = getHash();101			if((hash === initialHash||window.location.href == initialHref)&&(hsl == 1)){102				// FIXME: could this ever be a forward button?103				// we can't clear it because we still need to check for forwards. Ugg.104				// clearInterval(this.locationTimer);105				handleBackButton();106				return;107			}108			// first check to see if we could have gone forward. We always halt on109			// a no-hash item.110			if(forwardStack.length > 0){111				if(forwardStack[forwardStack.length-1].urlHash === hash){112					handleForwardButton();113					return;114				}115			}116			// ok, that didn't work, try someplace back in the history stack117			if((hsl >= 2)&&(historyStack[hsl-2])){118				if(historyStack[hsl-2].urlHash === hash){119					handleBackButton();120				}121			}122		}123	}124	back.init = function(){125		// summary:126		//		Initializes the undo stack. This must be called from a <script>127		//		block that lives inside the `<body>` tag to prevent bugs on IE.128		//129		//		Only call this method before the page's DOM is finished loading. Otherwise130		//		it will not work. Be careful with xdomain loading or djConfig.debugAtAllCosts scenarios,131		//		in order for this method to work, dojo/back will need to be part of a build layer.132		// prevent reinit133		if(dom.byId("dj_history")){ return; } 134		var src = config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html");135		if (config.afterOnLoad){136			console.error("dojo/back::init() must be called before the DOM has loaded. "137						+ "Include dojo/back in a build layer.");138		}else{139			document.write('<iframe style="border:0;width:1px;height:1px;position:absolute;visibility:hidden;bottom:0;right:0;" name="dj_history" id="dj_history" src="' + src + '"></iframe>');140		}141	};142	back.setInitialState = function(/*Object*/args){143		// summary:144		//		Sets the state object and back callback for the very first page145		//		that is loaded.146		//147		//		It is recommended that you call this method as part of an event148		//		listener that is registered via dojo/ready.149		// args: Object150		//		See the addToHistory() function for the list of valid args properties.151		initialState = createState(initialHref, args, initialHash);152	};153	//FIXME: Make these doc comments not be awful. At least they're not wrong.154	//FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things.155	//FIXME: is there a slight race condition in moz using change URL with the timer check and when156	//		 the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent.157	/*=====158	var __backArgs = {159		// back: Function?160		//		A function to be called when this state is reached via the user161		//		clicking the back button.162		// forward: Function?163		//		Upon return to this state from the "back, forward" combination164		//		of navigation steps, this function will be called. Somewhat165		//		analogous to the semantic of an "onRedo" event handler.166		// changeUrl: Boolean|String?167		//		Boolean indicating whether or not to create a unique hash for168		//		this state. If a string is passed instead, it is used as the169		//		hash.170	};171	=====*/172	back.addToHistory = function(args){173		// summary:174		//		adds a state object (args) to the history list.175		// args: __backArgs176		//		The state object that will be added to the history list.177		// description:178		//		To support getting back button notifications, the object179		//		argument should implement a function called either "back",180		//		"backButton", or "handle". The string "back" will be passed as181		//		the first and only argument to this callback.182		//183		//		To support getting forward button notifications, the object184		//		argument should implement a function called either "forward",185		//		"forwardButton", or "handle". The string "forward" will be186		//		passed as the first and only argument to this callback.187		//188		//		If you want the browser location string to change, define "changeUrl" on the object. If the189		//		value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment190		//		identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does191		//		not evaluate to false, that value will be used as the fragment identifier. For example,192		//		if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1193		//194		//		There are problems with using dojo/back with semantically-named fragment identifiers195		//		("hash values" on an URL). In most browsers it will be hard for dojo/back to know196		//		distinguish a back from a forward event in those cases. For back/forward support to197		//		work best, the fragment ID should always be a unique value (something using new Date().getTime()198		//		for example). If you want to detect hash changes using semantic fragment IDs, then199		//		consider using dojo/hash instead (in Dojo 1.4+).200		//201		// example:202		//		|	back.addToHistory({203		//		|		back: function(){ console.log('back pressed'); },204		//		|		forward: function(){ console.log('forward pressed'); },205		//		|		changeUrl: true206		//		|	});207		//	BROWSER NOTES:208		//	Safari 1.2:209		//	back button "works" fine, however it's not possible to actually210		//	DETECT that you've moved backwards by inspecting window.location.211		//	Unless there is some other means of locating.212		//	FIXME: perhaps we can poll on history.length?213		//	Safari 2.0.3+ (and probably 1.3.2+):214		//	works fine, except when changeUrl is used. When changeUrl is used,215		//	Safari jumps all the way back to whatever page was shown before216		//	the page that uses dojo.undo.browser support.217		//	IE 5.5 SP2:218		//	back button behavior is macro. It does not move back to the219		//	previous hash value, but to the last full page load. This suggests220		//	that the iframe is the correct way to capture the back button in221		//	these cases.222		//	Don't test this page using local disk for MSIE. MSIE will not create223		//	a history list for iframe_history.html if served from a file: URL.224		//	The XML served back from the XHR tests will also not be properly225		//	created if served from local disk. Serve the test pages from a web226		//	server to test in that browser.227		//	IE 6.0:228		//	same behavior as IE 5.5 SP2229		//	Firefox 1.0+:230		//	the back button will return us to the previous hash on the same231		//	page, thereby not requiring an iframe hack, although we do then232		//	need to run a timer to detect inter-page movement.233		//If addToHistory is called, then that means we prune the234		//forward stack -- the user went back, then wanted to235		//start a new forward path.236		forwardStack = [];237		var hash = null;238		var url = null;239		if(!historyIframe){240			if(config["useXDomain"] && !config["dojoIframeHistoryUrl"]){241				console.warn("dojo/back: When using cross-domain Dojo builds,"242					+ " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"243					+ " to the path on your domain to iframe_history.html");244			}245			historyIframe = window.frames["dj_history"];246		}247		if(!bookmarkAnchor){248			bookmarkAnchor = domConstruct.create("a", {style: {display: "none"}}, baseWindow.body());249		}250		if(args["changeUrl"]){251			hash = ""+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());252			//If the current hash matches the new one, just replace the history object with253			//this new one. It doesn't make sense to track different state objects for the same254			//logical URL. This matches the browser behavior of only putting in one history255			//item no matter how many times you click on the same #hash link, at least in Firefox256			//and Safari, and there is no reliable way in those browsers to know if a #hash link257			//has been clicked on multiple times. So making this the standard behavior in all browsers258			//so that dojo/back's behavior is the same in all browsers.259			if(historyStack.length == 0 && initialState.urlHash == hash){260				initialState = createState(url, args, hash);261				return;262			}else if(historyStack.length > 0 && historyStack[historyStack.length - 1].urlHash == hash){263				historyStack[historyStack.length - 1] = createState(url, args, hash);264				return;265			}266			changingUrl = true;267			setTimeout(function(){268					setHash(hash);269					changingUrl = false;270				}, 1);271			bookmarkAnchor.href = hash;272			if(has("ie")){273				url = loadIframeHistory();274				var oldCB = args["back"]||args["backButton"]||args["handle"];275				//The function takes handleName as a parameter, in case the276				//callback we are overriding was "handle". In that case,277				//we will need to pass the handle name to handle.278				var tcb = function(handleName){279					if(getHash() != ""){280						setTimeout(function(){ setHash(hash); }, 1);281					}282					//Use apply to set "this" to args, and to try to avoid memory leaks.283					oldCB.apply(this, [handleName]);284				};285				//Set interceptor function in the right place.286				if(args["back"]){287					args.back = tcb;288				}else if(args["backButton"]){289					args.backButton = tcb;290				}else if(args["handle"]){291					args.handle = tcb;292				}293				var oldFW = args["forward"]||args["forwardButton"]||args["handle"];294				//The function takes handleName as a parameter, in case the295				//callback we are overriding was "handle". In that case,296				//we will need to pass the handle name to handle.297				var tfw = function(handleName){298					if(getHash() != ""){299						setHash(hash);300					}301					if(oldFW){ // we might not actually have one302						//Use apply to set "this" to args, and to try to avoid memory leaks.303						oldFW.apply(this, [handleName]);304					}305				};306				//Set interceptor function in the right place.307				if(args["forward"]){308					args.forward = tfw;309				}else if(args["forwardButton"]){310					args.forwardButton = tfw;311				}else if(args["handle"]){312					args.handle = tfw;313				}314			}else if(!has("ie")){315				// start the timer316				if(!locationTimer){317					locationTimer = setInterval(checkLocation, 200);318				}319			}320		}else{321			url = loadIframeHistory();322		}323		historyStack.push(createState(url, args, hash));324	};325	back._iframeLoaded = function(evt, ifrLoc){326		// summary:327		//		private method. Do not call this directly.328		var query = getUrlQuery(ifrLoc.href);329		if(query == null){330			// alert("iframeLoaded");331			// we hit the end of the history, so we should go back332			if(historyStack.length == 1){333				handleBackButton();334			}335			return;336		}337		if(moveForward){338			// we were expecting it, so it's not either a forward or backward movement339			moveForward = false;340			return;341		}342		//Check the back stack first, since it is more likely.343		//Note that only one step back or forward is supported.344		if(historyStack.length >= 2 && query == getUrlQuery(historyStack[historyStack.length-2].url)){345			handleBackButton();346		}else if(forwardStack.length > 0 && query == getUrlQuery(forwardStack[forwardStack.length-1].url)){347			handleForwardButton();348		}349	};350	return back;351	...back.js.uncompressed.js
Source:back.js.uncompressed.js  
1define("dojo/back", ["./_base/config", "./_base/lang", "./sniff", "./dom", "./dom-construct", "./_base/window", "require"],2	function(config, lang, has, dom, domConstruct, baseWindow, require){3	// module:4	//		dojo/back5	var back = {6		// summary:7		//		Browser history management resources8	};9	 1  && lang.setObject("dojo.back", back);10	// everyone deals with encoding the hash slightly differently11	var getHash = back.getHash = function(){12		var h = window.location.hash;13		if(h.charAt(0) == "#"){ h = h.substring(1); }14		return has("mozilla") ? h : decodeURIComponent(h);15	},16	setHash = back.setHash = function(h){17		if(!h){ h = ""; }18		window.location.hash = encodeURIComponent(h);19		historyCounter = history.length;20	};21	var initialHref = (typeof(window) !== "undefined") ? window.location.href : "";22	var initialHash = (typeof(window) !== "undefined") ? getHash() : "";23	var initialState = null;24	var locationTimer = null;25	var bookmarkAnchor = null;26	var historyIframe = null;27	var forwardStack = [];28	var historyStack = [];29	var moveForward = false;30	var changingUrl = false;31	var historyCounter;32	function handleBackButton(){33		// summary:34		//		private method. Do not call this directly.35		//The "current" page is always at the top of the history stack.36		var current = historyStack.pop();37		if(!current){ return; }38		var last = historyStack[historyStack.length-1];39		if(!last && historyStack.length == 0){40			last = initialState;41		}42		if(last){43			if(last.kwArgs["back"]){44				last.kwArgs["back"]();45			}else if(last.kwArgs["backButton"]){46				last.kwArgs["backButton"]();47			}else if(last.kwArgs["handle"]){48				last.kwArgs.handle("back");49			}50		}51		forwardStack.push(current);52	}53	back.goBack = handleBackButton;54	function handleForwardButton(){55		// summary:56		//		private method. Do not call this directly.57		var last = forwardStack.pop();58		if(!last){ return; }59		if(last.kwArgs["forward"]){60			last.kwArgs.forward();61		}else if(last.kwArgs["forwardButton"]){62			last.kwArgs.forwardButton();63		}else if(last.kwArgs["handle"]){64			last.kwArgs.handle("forward");65		}66		historyStack.push(last);67	}68	back.goForward = handleForwardButton;69	function createState(url, args, hash){70		// summary:71		//		private method. Do not call this directly.72		return {"url": url, "kwArgs": args, "urlHash": hash};	//Object73	}74	function getUrlQuery(url){75		// summary:76		//		private method. Do not call this directly.77		var segments = url.split("?");78		if(segments.length < 2){79			return null; //null80		}81		else{82			return segments[1]; //String83		}84	}85	function loadIframeHistory(){86		// summary:87		//		private method. Do not call this directly.88		var url = (config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html")) + "?" + (new Date()).getTime();89		moveForward = true;90		if(historyIframe){91			has("webkit") ? historyIframe.location = url : window.frames[historyIframe.name].location = url;92		}else{93			//console.warn("dojo/back: Not initialised. You need to call back.init() from a <script> block that lives inside the <body> tag.");94		}95		return url; //String96	}97	function checkLocation(){98		if(!changingUrl){99			var hsl = historyStack.length;100			var hash = getHash();101			if((hash === initialHash||window.location.href == initialHref)&&(hsl == 1)){102				// FIXME: could this ever be a forward button?103				// we can't clear it because we still need to check for forwards. Ugg.104				// clearInterval(this.locationTimer);105				handleBackButton();106				return;107			}108			// first check to see if we could have gone forward. We always halt on109			// a no-hash item.110			if(forwardStack.length > 0){111				if(forwardStack[forwardStack.length-1].urlHash === hash){112					handleForwardButton();113					return;114				}115			}116			// ok, that didn't work, try someplace back in the history stack117			if((hsl >= 2)&&(historyStack[hsl-2])){118				if(historyStack[hsl-2].urlHash === hash){119					handleBackButton();120				}121			}122		}123	}124	back.init = function(){125		// summary:126		//		Initializes the undo stack. This must be called from a <script>127		//		block that lives inside the `<body>` tag to prevent bugs on IE.128		//129		//		Only call this method before the page's DOM is finished loading. Otherwise130		//		it will not work. Be careful with xdomain loading or djConfig.debugAtAllCosts scenarios,131		//		in order for this method to work, dojo/back will need to be part of a build layer.132		// prevent reinit133		if(dom.byId("dj_history")){ return; } 134		var src = config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html");135		if (config.afterOnLoad){136			console.error("dojo/back::init() must be called before the DOM has loaded. "137						+ "Include dojo/back in a build layer.");138		}else{139			document.write('<iframe style="border:0;width:1px;height:1px;position:absolute;visibility:hidden;bottom:0;right:0;" name="dj_history" id="dj_history" src="' + src + '"></iframe>');140		}141	};142	back.setInitialState = function(/*Object*/args){143		// summary:144		//		Sets the state object and back callback for the very first page145		//		that is loaded.146		//147		//		It is recommended that you call this method as part of an event148		//		listener that is registered via dojo/ready.149		// args: Object150		//		See the addToHistory() function for the list of valid args properties.151		initialState = createState(initialHref, args, initialHash);152	};153	//FIXME: Make these doc comments not be awful. At least they're not wrong.154	//FIXME: Would like to support arbitrary back/forward jumps. Have to rework iframeLoaded among other things.155	//FIXME: is there a slight race condition in moz using change URL with the timer check and when156	//		 the hash gets set? I think I have seen a back/forward call in quick succession, but not consistent.157	/*=====158	var __backArgs = {159		// back: Function?160		//		A function to be called when this state is reached via the user161		//		clicking the back button.162		// forward: Function?163		//		Upon return to this state from the "back, forward" combination164		//		of navigation steps, this function will be called. Somewhat165		//		analogous to the semantic of an "onRedo" event handler.166		// changeUrl: Boolean|String?167		//		Boolean indicating whether or not to create a unique hash for168		//		this state. If a string is passed instead, it is used as the169		//		hash.170	};171	=====*/172	back.addToHistory = function(args){173		// summary:174		//		adds a state object (args) to the history list.175		// args: __backArgs176		//		The state object that will be added to the history list.177		// description:178		//		To support getting back button notifications, the object179		//		argument should implement a function called either "back",180		//		"backButton", or "handle". The string "back" will be passed as181		//		the first and only argument to this callback.182		//183		//		To support getting forward button notifications, the object184		//		argument should implement a function called either "forward",185		//		"forwardButton", or "handle". The string "forward" will be186		//		passed as the first and only argument to this callback.187		//188		//		If you want the browser location string to change, define "changeUrl" on the object. If the189		//		value of "changeUrl" is true, then a unique number will be appended to the URL as a fragment190		//		identifier (http://some.domain.com/path#uniquenumber). If it is any other value that does191		//		not evaluate to false, that value will be used as the fragment identifier. For example,192		//		if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1193		//194		//		There are problems with using dojo/back with semantically-named fragment identifiers195		//		("hash values" on an URL). In most browsers it will be hard for dojo/back to know196		//		distinguish a back from a forward event in those cases. For back/forward support to197		//		work best, the fragment ID should always be a unique value (something using new Date().getTime()198		//		for example). If you want to detect hash changes using semantic fragment IDs, then199		//		consider using dojo/hash instead (in Dojo 1.4+).200		//201		// example:202		//		|	back.addToHistory({203		//		|		back: function(){ console.log('back pressed'); },204		//		|		forward: function(){ console.log('forward pressed'); },205		//		|		changeUrl: true206		//		|	});207		//	BROWSER NOTES:208		//	Safari 1.2:209		//	back button "works" fine, however it's not possible to actually210		//	DETECT that you've moved backwards by inspecting window.location.211		//	Unless there is some other means of locating.212		//	FIXME: perhaps we can poll on history.length?213		//	Safari 2.0.3+ (and probably 1.3.2+):214		//	works fine, except when changeUrl is used. When changeUrl is used,215		//	Safari jumps all the way back to whatever page was shown before216		//	the page that uses dojo.undo.browser support.217		//	IE 5.5 SP2:218		//	back button behavior is macro. It does not move back to the219		//	previous hash value, but to the last full page load. This suggests220		//	that the iframe is the correct way to capture the back button in221		//	these cases.222		//	Don't test this page using local disk for MSIE. MSIE will not create223		//	a history list for iframe_history.html if served from a file: URL.224		//	The XML served back from the XHR tests will also not be properly225		//	created if served from local disk. Serve the test pages from a web226		//	server to test in that browser.227		//	IE 6.0:228		//	same behavior as IE 5.5 SP2229		//	Firefox 1.0+:230		//	the back button will return us to the previous hash on the same231		//	page, thereby not requiring an iframe hack, although we do then232		//	need to run a timer to detect inter-page movement.233		//If addToHistory is called, then that means we prune the234		//forward stack -- the user went back, then wanted to235		//start a new forward path.236		forwardStack = [];237		var hash = null;238		var url = null;239		if(!historyIframe){240			if(config["useXDomain"] && !config["dojoIframeHistoryUrl"]){241				console.warn("dojo/back: When using cross-domain Dojo builds,"242					+ " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"243					+ " to the path on your domain to iframe_history.html");244			}245			historyIframe = window.frames["dj_history"];246		}247		if(!bookmarkAnchor){248			bookmarkAnchor = domConstruct.create("a", {style: {display: "none"}}, baseWindow.body());249		}250		if(args["changeUrl"]){251			hash = ""+ ((args["changeUrl"]!==true) ? args["changeUrl"] : (new Date()).getTime());252			//If the current hash matches the new one, just replace the history object with253			//this new one. It doesn't make sense to track different state objects for the same254			//logical URL. This matches the browser behavior of only putting in one history255			//item no matter how many times you click on the same #hash link, at least in Firefox256			//and Safari, and there is no reliable way in those browsers to know if a #hash link257			//has been clicked on multiple times. So making this the standard behavior in all browsers258			//so that dojo/back's behavior is the same in all browsers.259			if(historyStack.length == 0 && initialState.urlHash == hash){260				initialState = createState(url, args, hash);261				return;262			}else if(historyStack.length > 0 && historyStack[historyStack.length - 1].urlHash == hash){263				historyStack[historyStack.length - 1] = createState(url, args, hash);264				return;265			}266			changingUrl = true;267			setTimeout(function(){268					setHash(hash);269					changingUrl = false;270				}, 1);271			bookmarkAnchor.href = hash;272			if(has("ie")){273				url = loadIframeHistory();274				var oldCB = args["back"]||args["backButton"]||args["handle"];275				//The function takes handleName as a parameter, in case the276				//callback we are overriding was "handle". In that case,277				//we will need to pass the handle name to handle.278				var tcb = function(handleName){279					if(getHash() != ""){280						setTimeout(function(){ setHash(hash); }, 1);281					}282					//Use apply to set "this" to args, and to try to avoid memory leaks.283					oldCB.apply(this, [handleName]);284				};285				//Set interceptor function in the right place.286				if(args["back"]){287					args.back = tcb;288				}else if(args["backButton"]){289					args.backButton = tcb;290				}else if(args["handle"]){291					args.handle = tcb;292				}293				var oldFW = args["forward"]||args["forwardButton"]||args["handle"];294				//The function takes handleName as a parameter, in case the295				//callback we are overriding was "handle". In that case,296				//we will need to pass the handle name to handle.297				var tfw = function(handleName){298					if(getHash() != ""){299						setHash(hash);300					}301					if(oldFW){ // we might not actually have one302						//Use apply to set "this" to args, and to try to avoid memory leaks.303						oldFW.apply(this, [handleName]);304					}305				};306				//Set interceptor function in the right place.307				if(args["forward"]){308					args.forward = tfw;309				}else if(args["forwardButton"]){310					args.forwardButton = tfw;311				}else if(args["handle"]){312					args.handle = tfw;313				}314			}else if(!has("ie")){315				// start the timer316				if(!locationTimer){317					locationTimer = setInterval(checkLocation, 200);318				}319			}320		}else{321			url = loadIframeHistory();322		}323		historyStack.push(createState(url, args, hash));324	};325	back._iframeLoaded = function(evt, ifrLoc){326		// summary:327		//		private method. Do not call this directly.328		var query = getUrlQuery(ifrLoc.href);329		if(query == null){330			// alert("iframeLoaded");331			// we hit the end of the history, so we should go back332			if(historyStack.length == 1){333				handleBackButton();334			}335			return;336		}337		if(moveForward){338			// we were expecting it, so it's not either a forward or backward movement339			moveForward = false;340			return;341		}342		//Check the back stack first, since it is more likely.343		//Note that only one step back or forward is supported.344		if(historyStack.length >= 2 && query == getUrlQuery(historyStack[historyStack.length-2].url)){345			handleBackButton();346		}else if(forwardStack.length > 0 && query == getUrlQuery(forwardStack[forwardStack.length-1].url)){347			handleForwardButton();348		}349	};350	return back;351	...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!!
