<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Global initialization of the library.
//>>label: Init
//>>group: Core

define([
	"jquery",
	"./jquery.ui.core",
	"./jquery.mobile.defaults",
	"./jquery.mobile.helpers",
	"./jquery.mobile.data",
	"./jquery.mobile.support",
	"./events/navigate",
	"./navigation/path",
	"./navigation/method",
	"./jquery.mobile.navigation",
	"./widgets/loader",
	"./jquery.mobile.vmouse",
	"jquery.hashchange" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {
	var	$html = $( "html" ),
		$window = $.mobile.window;

	//remove initial build class (only present on first pageshow)
	function hideRenderingClass() {
		$html.removeClass( "ui-mobile-rendering" );
	}

	// trigger mobileinit event - useful hook for configuring $.mobile settings before they're used
	$( window.document ).trigger( "mobileinit" );

	// support conditions
	// if device support condition(s) aren't met, leave things as they are -> a basic, usable experience,
	// otherwise, proceed with the enhancements
	if ( !$.mobile.gradeA() ) {
		return;
	}

	// override ajaxEnabled on platforms that have known conflicts with hash history updates
	// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini)
	if ( $.mobile.ajaxBlacklist ) {
		$.mobile.ajaxEnabled = false;
	}

	// Add mobile, initial load "rendering" classes to docEl
	$html.addClass( "ui-mobile ui-mobile-rendering" );

	// This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
	// this ensures the rendering class is removed after 5 seconds, so content is visible and accessible
	setTimeout( hideRenderingClass, 5000 );

	$.extend( $.mobile, {
		// find and enhance the pages in the dom and transition to the first page.
		initializePage: function() {
			// find present pages
			var path = $.mobile.path,
				$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
				hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
				hashPage = document.getElementById( hash );

			// if no pages are found, create one with body's inner html
			if ( !$pages.length ) {
				$pages = $( "body" ).wrapInner( "

" ).children( 0 );
			}

			// add dialogs, set data-url attrs
			$pages.each(function() {
				var $this = $( this );

				// unless the data url is already set set it to the pathname
				if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
					$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search );
				}
			});

			// define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback)
			$.mobile.firstPage = $pages.first();

			// define page container
			$.mobile.pageContainer = $.mobile.firstPage
				.parent()
				.addClass( "ui-mobile-viewport" )
				.pagecontainer();

			// initialize navigation events now, after mobileinit has occurred and the page container
			// has been created but before the rest of the library is alerted to that fact
			$.mobile.navreadyDeferred.resolve();

			// alert listeners that the pagecontainer has been determined for binding
			// to events triggered on it
			$window.trigger( "pagecontainercreate" );

			// cue page loading message
			$.mobile.showPageLoadingMsg();

			//remove initial build class (only present on first pageshow)
			hideRenderingClass();

			// if hashchange listening is disabled, there's no hash deeplink,
			// the hash is not valid (contains more than one # or does not start with #)
			// or there is no page with that hash, change to the first page in the DOM
			// Remember, however, that the hash can also be a path!
			if ( ! ( $.mobile.hashListeningEnabled &&
				$.mobile.path.isHashValid( location.hash ) &&
				( $( hashPage ).is( ":jqmData(role='page')" ) ||
					$.mobile.path.isPath( hash ) ||
					hash === $.mobile.dialogHashKey ) ) ) {

				// Store the initial destination
				if ( $.mobile.path.isHashValid( location.hash ) ) {
					$.mobile.urlHistory.initialDst = hash.replace( "#", "" );
				}

				// make sure to set initial popstate state if it exists
				// so that navigation back to the initial page works properly
				if ( $.event.special.navigate.isPushStateEnabled() ) {
					$.mobile.navigate.navigator.squash( path.parseLocation().href );
				}

				$.mobile.changePage( $.mobile.firstPage, {
					transition: "none",
					reverse: true,
					changeHash: false,
					fromHashChange: true
				});
			} else {
				// trigger hashchange or navigate to squash and record the correct
				// history entry for an initial hash path
				if ( !$.event.special.navigate.isPushStateEnabled() ) {
					$window.trigger( "hashchange", [true] );
				} else {
					// TODO figure out how to simplify this interaction with the initial history entry
					// at the bottom js/navigate/navigate.js
					$.mobile.navigate.history.stack = [];
					$.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
				}
			}
		}
	});

	$(function() {
		//Run inlineSVG support test
		$.support.inlineSVG();

		// check which scrollTop value should be used by scrolling to 1 immediately at domready
		// then check what the scroll top is. Android will report 0... others 1
		// note that this initial scroll won't hide the address bar. It's just for the check.

		// hide iOS browser chrome on load if hideUrlBar is true this is to try and do it as soon as possible
		if ( $.mobile.hideUrlBar ) {
			window.scrollTo( 0, 1 );
		}

		// if defaultHomeScroll hasn't been set yet, see if scrollTop is 1
		// it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar)
		// so if it's 1, use 0 from now on
		$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $.mobile.window.scrollTop() === 1 ) ? 0 : 1;

		//dom-ready inits
		if ( $.mobile.autoInitializePage ) {
			$.mobile.initializePage();
		}

		// window load event
		// hide iOS browser chrome on load if hideUrlBar is true this is as fall back incase we were too early before
		if ( $.mobile.hideUrlBar ) {
			$window.load( $.mobile.silentScroll );
		}

		if ( !$.support.cssPointerEvents ) {
			// IE and Opera don't support CSS pointer-events: none that we use to disable link-based buttons
			// by adding the 'ui-disabled' class to them. Using a JavaScript workaround for those browser.
			// https://github.com/jquery/jquery-mobile/issues/3558

			$.mobile.document.delegate( ".ui-disabled", "vclick",
				function( e ) {
					e.preventDefault();
					e.stopImmediatePropagation();
				}
			);
		}
	});
}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>init: Disable mouse events the hard way based also on the presence of ui-state-disabled.<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Global initialization of the library.
//>>label: Init
//>>group: Core

define([
	"jquery",
	"./jquery.ui.core",
	"./jquery.mobile.defaults",
	"./jquery.mobile.helpers",
	"./jquery.mobile.data",
	"./jquery.mobile.support",
	"./events/navigate",
	"./navigation/path",
	"./navigation/method",
	"./jquery.mobile.navigation",
	"./widgets/loader",
	"./jquery.mobile.vmouse",
	"jquery.hashchange" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {
	var	$html = $( "html" ),
		$window = $.mobile.window;

	//remove initial build class (only present on first pageshow)
	function hideRenderingClass() {
		$html.removeClass( "ui-mobile-rendering" );
	}

	// trigger mobileinit event - useful hook for configuring $.mobile settings before they're used
	$( window.document ).trigger( "mobileinit" );

	// support conditions
	// if device support condition(s) aren't met, leave things as they are -> a basic, usable experience,
	// otherwise, proceed with the enhancements
	if ( !$.mobile.gradeA() ) {
		return;
	}

	// override ajaxEnabled on platforms that have known conflicts with hash history updates
	// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini)
	if ( $.mobile.ajaxBlacklist ) {
		$.mobile.ajaxEnabled = false;
	}

	// Add mobile, initial load "rendering" classes to docEl
	$html.addClass( "ui-mobile ui-mobile-rendering" );

	// This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
	// this ensures the rendering class is removed after 5 seconds, so content is visible and accessible
	setTimeout( hideRenderingClass, 5000 );

	$.extend( $.mobile, {
		// find and enhance the pages in the dom and transition to the first page.
		initializePage: function() {
			// find present pages
			var path = $.mobile.path,
				$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
				hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
				hashPage = document.getElementById( hash );

			// if no pages are found, create one with body's inner html
			if ( !$pages.length ) {
				$pages = $( "body" ).wrapInner( "

" ).children( 0 );
			}

			// add dialogs, set data-url attrs
			$pages.each(function() {
				var $this = $( this );

				// unless the data url is already set set it to the pathname
				if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
					$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search );
				}
			});

			// define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback)
			$.mobile.firstPage = $pages.first();

			// define page container
			$.mobile.pageContainer = $.mobile.firstPage
				.parent()
				.addClass( "ui-mobile-viewport" )
				.pagecontainer();

			// initialize navigation events now, after mobileinit has occurred and the page container
			// has been created but before the rest of the library is alerted to that fact
			$.mobile.navreadyDeferred.resolve();

			// alert listeners that the pagecontainer has been determined for binding
			// to events triggered on it
			$window.trigger( "pagecontainercreate" );

			// cue page loading message
			$.mobile.showPageLoadingMsg();

			//remove initial build class (only present on first pageshow)
			hideRenderingClass();

			// if hashchange listening is disabled, there's no hash deeplink,
			// the hash is not valid (contains more than one # or does not start with #)
			// or there is no page with that hash, change to the first page in the DOM
			// Remember, however, that the hash can also be a path!
			if ( ! ( $.mobile.hashListeningEnabled &&
				$.mobile.path.isHashValid( location.hash ) &&
				( $( hashPage ).is( ":jqmData(role='page')" ) ||
					$.mobile.path.isPath( hash ) ||
					hash === $.mobile.dialogHashKey ) ) ) {

				// Store the initial destination
				if ( $.mobile.path.isHashValid( location.hash ) ) {
					$.mobile.urlHistory.initialDst = hash.replace( "#", "" );
				}

				// make sure to set initial popstate state if it exists
				// so that navigation back to the initial page works properly
				if ( $.event.special.navigate.isPushStateEnabled() ) {
					$.mobile.navigate.navigator.squash( path.parseLocation().href );
				}

				$.mobile.changePage( $.mobile.firstPage, {
					transition: "none",
					reverse: true,
					changeHash: false,
					fromHashChange: true
				});
			} else {
				// trigger hashchange or navigate to squash and record the correct
				// history entry for an initial hash path
				if ( !$.event.special.navigate.isPushStateEnabled() ) {
					$window.trigger( "hashchange", [true] );
				} else {
					// TODO figure out how to simplify this interaction with the initial history entry
					// at the bottom js/navigate/navigate.js
					$.mobile.navigate.history.stack = [];
					$.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
				}
			}
		}
	});

	$(function() {
		//Run inlineSVG support test
		$.support.inlineSVG();

		// check which scrollTop value should be used by scrolling to 1 immediately at domready
		// then check what the scroll top is. Android will report 0... others 1
		// note that this initial scroll won't hide the address bar. It's just for the check.

		// hide iOS browser chrome on load if hideUrlBar is true this is to try and do it as soon as possible
		if ( $.mobile.hideUrlBar ) {
			window.scrollTo( 0, 1 );
		}

		// if defaultHomeScroll hasn't been set yet, see if scrollTop is 1
		// it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar)
		// so if it's 1, use 0 from now on
		$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $.mobile.window.scrollTop() === 1 ) ? 0 : 1;

		//dom-ready inits
		if ( $.mobile.autoInitializePage ) {
			$.mobile.initializePage();
		}

		// window load event
		// hide iOS browser chrome on load if hideUrlBar is true this is as fall back incase we were too early before
		if ( $.mobile.hideUrlBar ) {
			$window.load( $.mobile.silentScroll );
		}

		if ( !$.support.cssPointerEvents ) {
			// IE and Opera don't support CSS pointer-events: none that we use to disable link-based buttons
			// by adding the 'ui-disabled' class to them. Using a JavaScript workaround for those browser.
			// https://github.com/jquery/jquery-mobile/issues/3558

			// DEPRECATED as of 1.4.0 - remove ui-disabled after 1.4.0 release
			// only ui-state-disabled should be present thereafter
			$.mobile.document.delegate( ".ui-state-disabled,.ui-disabled", "vclick",
				function( e ) {
					e.preventDefault();
					e.stopImmediatePropagation();
				}
			);
		}
	});
}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Global initialization of the library.
//>>label: Init
//>>group: Core

define([
	"jquery",
	"./jquery.ui.core",
	"./jquery.mobile.defaults",
	"./jquery.mobile.helpers",
	"./jquery.mobile.data",
	"./jquery.mobile.support",
	"./events/navigate",
	"./navigation/path",
	"./navigation/method",
	"./jquery.mobile.navigation",
	"./widgets/loader",
	"./jquery.mobile.vmouse",
	"jquery.hashchange" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {
	var	$html = $( "html" ),
		$window = $.mobile.window;

	//remove initial build class (only present on first pageshow)
	function hideRenderingClass() {
		$html.removeClass( "ui-mobile-rendering" );
	}

	// trigger mobileinit event - useful hook for configuring $.mobile settings before they're used
	$( window.document ).trigger( "mobileinit" );

	// support conditions
	// if device support condition(s) aren't met, leave things as they are -> a basic, usable experience,
	// otherwise, proceed with the enhancements
	if ( !$.mobile.gradeA() ) {
		return;
	}

	// override ajaxEnabled on platforms that have known conflicts with hash history updates
	// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini)
	if ( $.mobile.ajaxBlacklist ) {
		$.mobile.ajaxEnabled = false;
	}

	// Add mobile, initial load "rendering" classes to docEl
	$html.addClass( "ui-mobile ui-mobile-rendering" );

	// This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
	// this ensures the rendering class is removed after 5 seconds, so content is visible and accessible
	setTimeout( hideRenderingClass, 5000 );

	$.extend( $.mobile, {
		// find and enhance the pages in the dom and transition to the first page.
		initializePage: function() {
			// find present pages
			var path = $.mobile.path,
				$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
				hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
				hashPage = document.getElementById( hash );

			// if no pages are found, create one with body's inner html
			if ( !$pages.length ) {
				$pages = $( "body" ).wrapInner( "

" ).children( 0 );
			}

			// add dialogs, set data-url attrs
			$pages.each(function() {
				var $this = $( this );

				// unless the data url is already set set it to the pathname
				if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
					$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search );
				}
			});

			// define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback)
			$.mobile.firstPage = $pages.first();

			// define page container
			$.mobile.pageContainer = $.mobile.firstPage
        .parent()
        .addClass( "ui-mobile-viewport" )
        .content();

			// initialize navigation events now, after mobileinit has occurred and the page container
			// has been created but before the rest of the library is alerted to that fact
			$.mobile.navreadyDeferred.resolve();

			// alert listeners that the pagecontainer has been determined for binding
			// to events triggered on it
			$window.trigger( "pagecontainercreate" );

			// cue page loading message
			$.mobile.showPageLoadingMsg();

			//remove initial build class (only present on first pageshow)
			hideRenderingClass();

			// if hashchange listening is disabled, there's no hash deeplink,
			// the hash is not valid (contains more than one # or does not start with #)
			// or there is no page with that hash, change to the first page in the DOM
			// Remember, however, that the hash can also be a path!
			if ( ! ( $.mobile.hashListeningEnabled &&
				$.mobile.path.isHashValid( location.hash ) &&
				( $( hashPage ).is( ":jqmData(role='page')" ) ||
					$.mobile.path.isPath( hash ) ||
					hash === $.mobile.dialogHashKey ) ) ) {

				// Store the initial destination
				if ( $.mobile.path.isHashValid( location.hash ) ) {
					$.mobile.urlHistory.initialDst = hash.replace( "#", "" );
				}

				// make sure to set initial popstate state if it exists
				// so that navigation back to the initial page works properly
				if( $.event.special.navigate.isPushStateEnabled() ) {
					$.mobile.navigate.navigator.squash( path.parseLocation().href );
				}

				$.mobile.changePage( $.mobile.firstPage, {
					transition: "none",
					reverse: true,
					changeHash: false,
					fromHashChange: true
				});
			} else {
				// trigger hashchange or navigate to squash and record the correct
				// history entry for an initial hash path
				if( !$.event.special.navigate.isPushStateEnabled() ) {
					$window.trigger( "hashchange", [true] );
				} else {
					// TODO figure out how to simplify this interaction with the initial history entry
					// at the bottom js/navigate/navigate.js
					$.mobile.navigate.history.stack = [];
					$.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
				}
			}
		}
	});

	// check which scrollTop value should be used by scrolling to 1 immediately at domready
	// then check what the scroll top is. Android will report 0... others 1
	// note that this initial scroll won't hide the address bar. It's just for the check.
	$(function() {
		//Run inlineSVG support test
		$.support.inlineSVG();

		window.scrollTo( 0, 1 );

		// if defaultHomeScroll hasn't been set yet, see if scrollTop is 1
		// it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar)
		// so if it's 1, use 0 from now on
		$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $.mobile.window.scrollTop() === 1 ) ? 0 : 1;

		//dom-ready inits
		if ( $.mobile.autoInitializePage ) {
			$.mobile.initializePage();
		}

		// window load event
		// hide iOS browser chrome on load
		if( $.mobile.hideUrlBar ){
			$window.load( $.mobile.silentScroll );
		}

		if ( !$.support.cssPointerEvents ) {
			// IE and Opera don't support CSS pointer-events: none that we use to disable link-based buttons
			// by adding the 'ui-disabled' class to them. Using a JavaScript workaround for those browser.
			// https://github.com/jquery/jquery-mobile/issues/3558

			$.mobile.document.delegate( ".ui-disabled", "vclick",
				function( e ) {
					e.preventDefault();
					e.stopImmediatePropagation();
				}
			);
		}
	});
}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>Init: stop inital scroll when not hiding url<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Global initialization of the library.
//>>label: Init
//>>group: Core

define([
	"jquery",
	"./jquery.ui.core",
	"./jquery.mobile.defaults",
	"./jquery.mobile.helpers",
	"./jquery.mobile.data",
	"./jquery.mobile.support",
	"./events/navigate",
	"./navigation/path",
	"./navigation/method",
	"./jquery.mobile.navigation",
	"./widgets/loader",
	"./jquery.mobile.vmouse",
	"jquery.hashchange" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {
	var	$html = $( "html" ),
		$window = $.mobile.window;

	//remove initial build class (only present on first pageshow)
	function hideRenderingClass() {
		$html.removeClass( "ui-mobile-rendering" );
	}

	// trigger mobileinit event - useful hook for configuring $.mobile settings before they're used
	$( window.document ).trigger( "mobileinit" );

	// support conditions
	// if device support condition(s) aren't met, leave things as they are -> a basic, usable experience,
	// otherwise, proceed with the enhancements
	if ( !$.mobile.gradeA() ) {
		return;
	}

	// override ajaxEnabled on platforms that have known conflicts with hash history updates
	// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini)
	if ( $.mobile.ajaxBlacklist ) {
		$.mobile.ajaxEnabled = false;
	}

	// Add mobile, initial load "rendering" classes to docEl
	$html.addClass( "ui-mobile ui-mobile-rendering" );

	// This is a fallback. If anything goes wrong (JS errors, etc), or events don't fire,
	// this ensures the rendering class is removed after 5 seconds, so content is visible and accessible
	setTimeout( hideRenderingClass, 5000 );

	$.extend( $.mobile, {
		// find and enhance the pages in the dom and transition to the first page.
		initializePage: function() {
			// find present pages
			var path = $.mobile.path,
				$pages = $( ":jqmData(role='page'), :jqmData(role='dialog')" ),
				hash = path.stripHash( path.stripQueryParams(path.parseLocation().hash) ),
				hashPage = document.getElementById( hash );

			// if no pages are found, create one with body's inner html
			if ( !$pages.length ) {
				$pages = $( "body" ).wrapInner( "

" ).children( 0 );
			}

			// add dialogs, set data-url attrs
			$pages.each(function() {
				var $this = $( this );

				// unless the data url is already set set it to the pathname
				if ( !$this[ 0 ].getAttribute( "data-" + $.mobile.ns + "url" ) ) {
					$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search );
				}
			});

			// define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback)
			$.mobile.firstPage = $pages.first();

			// define page container
			$.mobile.pageContainer = $.mobile.firstPage
        .parent()
        .addClass( "ui-mobile-viewport" )
        .content();

			// initialize navigation events now, after mobileinit has occurred and the page container
			// has been created but before the rest of the library is alerted to that fact
			$.mobile.navreadyDeferred.resolve();

			// alert listeners that the pagecontainer has been determined for binding
			// to events triggered on it
			$window.trigger( "pagecontainercreate" );

			// cue page loading message
			$.mobile.showPageLoadingMsg();

			//remove initial build class (only present on first pageshow)
			hideRenderingClass();

			// if hashchange listening is disabled, there's no hash deeplink,
			// the hash is not valid (contains more than one # or does not start with #)
			// or there is no page with that hash, change to the first page in the DOM
			// Remember, however, that the hash can also be a path!
			if ( ! ( $.mobile.hashListeningEnabled &&
				$.mobile.path.isHashValid( location.hash ) &&
				( $( hashPage ).is( ":jqmData(role='page')" ) ||
					$.mobile.path.isPath( hash ) ||
					hash === $.mobile.dialogHashKey ) ) ) {

				// Store the initial destination
				if ( $.mobile.path.isHashValid( location.hash ) ) {
					$.mobile.urlHistory.initialDst = hash.replace( "#", "" );
				}

				// make sure to set initial popstate state if it exists
				// so that navigation back to the initial page works properly
				if( $.event.special.navigate.isPushStateEnabled() ) {
					$.mobile.navigate.navigator.squash( path.parseLocation().href );
				}

				$.mobile.changePage( $.mobile.firstPage, {
					transition: "none",
					reverse: true,
					changeHash: false,
					fromHashChange: true
				});
			} else {
				// trigger hashchange or navigate to squash and record the correct
				// history entry for an initial hash path
				if( !$.event.special.navigate.isPushStateEnabled() ) {
					$window.trigger( "hashchange", [true] );
				} else {
					// TODO figure out how to simplify this interaction with the initial history entry
					// at the bottom js/navigate/navigate.js
					$.mobile.navigate.history.stack = [];
					$.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
				}
			}
		}
	});

	// check which scrollTop value should be used by scrolling to 1 immediately at domready
	// then check what the scroll top is. Android will report 0... others 1
	// note that this initial scroll won't hide the address bar. It's just for the check.
	$(function() {
		//Run inlineSVG support test
		$.support.inlineSVG();
		if( $.mobile.hideUrlBar ){
			window.scrollTo( 0, 1 );
		}

		// if defaultHomeScroll hasn't been set yet, see if scrollTop is 1
		// it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar)
		// so if it's 1, use 0 from now on
		$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $.mobile.window.scrollTop() === 1 ) ? 0 : 1;

		//dom-ready inits
		if ( $.mobile.autoInitializePage ) {
			$.mobile.initializePage();
		}

		// window load event
		// hide iOS browser chrome on load
		if( $.mobile.hideUrlBar ){
			$window.load( $.mobile.silentScroll );
		}

		if ( !$.support.cssPointerEvents ) {
			// IE and Opera don't support CSS pointer-events: none that we use to disable link-based buttons
			// by adding the 'ui-disabled' class to them. Using a JavaScript workaround for those browser.
			// https://github.com/jquery/jquery-mobile/issues/3558

			$.mobile.document.delegate( ".ui-disabled", "vclick",
				function( e ) {
					e.preventDefault();
					e.stopImmediatePropagation();
				}
			);
		}
	});
}( jQuery, this ));
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>/*|
 *| jQuery File Ajaxis Plugin for Materialize
 *| https://github.com/amranidev/ajaxis
 *|
 *| Copyright 2015, Amrani Houssain
 *| amranidev@gmail.com
 *|
 *| Licensed under the MIT license:
 *| http://www.opensource.org/licenses/MIT
 *|
 */

$(document).on('ready', function() {
    $('.modal-trigger').leanModal();
});
$(document).on("click", ".closeModal", function() {
    $(this).parent().parent().parent().parent().closeModal();
});
$(document).on('click', '.show', function() {
    GET($(this).data('link'));
})
$('body').on('click', '.delete', function() {
    GET($(this).data('link'));
});
$("body").on('click', '.edit', function() {
    GET($(this).data('link'));
})
$(document).on("click", ".create", function() {
    GET($(this).data('link'));
})
$(document).on("click", ".update", function(e) {
    e.preventDefault();
    POST($(this).parent().parent().serializeArray(), $(this).data('link'));
});
$(document).on("click", ".save", function() {
    POST($(this).parent().parent().serializeArray(), $(this).data('link'));
})

$('body').on('click', '.remove', function() {
    $.ajax({
        async: true,
        method: 'get',
        url: baseURL + $(this).data('link'),
        success: function(response) {
            window.location.replace(response);
        }
    });
});

function POST(postData, dataLink) {
    $.ajax({
        async: true,
        type: 'post',
        url: baseURL + dataLink,
        data: postData,
        success: function(response) {
            window.location.replace(response);
        }
    })
}

function GET(dataLink) {
    $.ajax({
        async: true,
        type: 'get',
        url: baseURL + dataLink,
        success: function(response) {
            $('.AjaxisModal').html(response);
            $('select').material_select();
            $('.datepicker').pickadate({
                selectMonths: true,
                selectYears: 15
            });
        }
    })
}
<commit_msg>fix rederiction url Mt<commit_after>/*|
 *| jQuery File Ajaxis Plugin for Materialize
 *| https://github.com/amranidev/ajaxis
 *|
 *| Copyright 2015, Amrani Houssain
 *| amranidev@gmail.com
 *|
 *| Licensed under the MIT license:
 *| http://www.opensource.org/licenses/MIT
 *|
 */

$(document).on('ready', function() {
    $('.modal-trigger').leanModal();
});
$(document).on("click", ".closeModal", function() {
    $(this).parent().parent().parent().parent().closeModal();
});
$(document).on('click', '.show', function() {
    GET($(this).data('link'));
})
$('body').on('click', '.delete', function() {
    GET($(this).data('link'));
});
$("body").on('click', '.edit', function() {
    GET($(this).data('link'));
})
$(document).on("click", ".create", function() {
    GET($(this).data('link'));
})
$(document).on("click", ".update", function(e) {
    e.preventDefault();
    POST($(this).parent().parent().serializeArray(), $(this).data('link'));
});
$(document).on("click", ".save", function() {
    POST($(this).parent().parent().serializeArray(), $(this).data('link'));
})

$('body').on('click', '.remove', function() {
    $.ajax({
        async: true,
        method: 'get',
        url: baseURL + $(this).data('link'),
        success: function(response) {
            window.location = response;
        }
    });
});

function POST(postData, dataLink) {
    $.ajax({
        async: true,
        type: 'post',
        url: baseURL + dataLink,
        data: postData,
        success: function(response) {
            window.location = response;
        }
    })
}

function GET(dataLink) {
    $.ajax({
        async: true,
        type: 'get',
        url: baseURL + dataLink,
        success: function(response) {
            $('.AjaxisModal').html(response);
            $('select').material_select();
            $('.datepicker').pickadate({
                selectMonths: true,
                selectYears: 15
            });
        }
    })
}
<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular
    .module('app')
    .controller('SearchController', ['$scope','$rootScope','requestService','$translate','$routeParams','$route','$window','$location',
    function($scope,$rootScope,requestService,$translate,$routeParams, $route, $window, $location) {

        $scope.loading_animation = true;
        $scope.search_page_nr = 1;
        $scope.total_count = 0;

        if($location.search().q){
            console.log('search ', $location.search().q);
            $scope.search_word = $location.search().q;
        }

        if($location.search().page){
            console.log('page ', $location.search().page);
            $scope.search_page_nr = $location.search().page;
        }

        if($location.search().subjects){
            console.log('subjects ', $location.search().subjects);
        }

        if($location.search().languages){
            console.log('languages ', $location.search().languages);
        }

        $translate('PAGE.SEARCH').then(function (t) {
            $rootScope.title = t+' | Leplanner beta';

            /* ANALYTICS */
            $window.ga('send', 'pageview', {
                'page': $location.path(),
                'title': $rootScope.title
            });
        });

        $scope.$on('triggerSearchForm', function(e) {
            angular.element('#search-word-input').trigger('focus');
            $scope.search();
        });

        //replace search word from top search
        if(typeof $rootScope.top_search_word !== 'undefined'){
            $scope.search_word = $rootScope.top_search_word;
            $rootScope.top_search_word = undefined;
            $scope.$parent.top_search_word = undefined;
            //angular.element('#search-word-input').trigger('focus');

            $location.search('q', $scope.search_word);
            return;
        }

        // INIT
        createDropDownMenusAndInitialSearch();

        function createDropDownMenusAndInitialSearch(){
            //  arrays to store selected multiple choices
            $scope.selected_subjects = [];

            $scope.subjectsSettings = {
                scrollableHeight: '400px',
                scrollable: true,
                enableSearch: true,
                smartButtonMaxItems: 3,
                displayProp: 'name',
                idProp: '_id',
                showCheckAll: false,
                //externalIdProp: '_id',
                externalIdProp: '',
                buttonClasses: 'btn btn-default btn-fixed-width',
            };

            //$scope.subjectsText = {buttonDefaultText: 'Filter subjects'};
            $scope.subjectsText = {
                buttonDefaultText: $rootScope.translated.dropdowns.subjects,
                uncheckAll: $rootScope.translated.dropdowns.uncheck_all,
                searchPlaceholder: $rootScope.translated.dropdowns.search
            };

            $scope.selected_languages = [];

            $scope.languagesSettings = {
                scrollableHeight: '400px',
                scrollable: false,
                enableSearch: false,
                smartButtonMaxItems: 3,
                displayProp: 'name',
                idProp: 'value',
                showCheckAll: false,
                showUncheckAll: false,
                //externalIdProp: '_id',
                externalIdProp: '',
                buttonClasses: 'btn btn-default btn-fixed-width',
            };

            //$scope.subjectsText = {buttonDefaultText: 'Filter subjects'};
            $scope.languagesText = {
                buttonDefaultText: $rootScope.translated.dropdowns.language,
                uncheckAll: $rootScope.translated.dropdowns.uncheck_all,
                searchPlaceholder: $rootScope.translated.dropdowns.search
            };

            $scope.language_options = [{name: $rootScope.translated.dropdowns.estonian, value: 'et'},{name: $rootScope.translated.dropdowns.english, value: 'en'}];

            requestService.get('/meta/subjects')
            .then(function(data) {
                if(data.subjects){
                    $scope.subjects = data.subjects;
                    for(var a = 0; a < $scope.subjects.length; a++){
                        $scope.subjects[a].name = $scope.subjects[a]["name_"+$translate.use()];
                    }
                    // INITAL SEARCH
                    getSearchParamsAndSearch();
                }
                if(data.error){
                    console.log(data.error);
                }
            });
        }

        function getSearchParamsAndSearch(){

            $scope.loading_animation = true;

            var subjects = [];
            var selected_subjects_labels = [];
            var selected_languages_labels = [];

            if($scope.selected_subjects.length === 0 && $location.search().subjects){
                var subject_array_from_url = $location.search().subjects.split(',');
                $scope.selected_subjects = [];
                for(var j = 0; j < $scope.subjects.length; j++){
                    for(var k = 0; k < subject_array_from_url.length; k++){
                        if($scope.subjects[j]._id === subject_array_from_url[k]){
                            $scope.selected_subjects.push($scope.subjects[j]);
                        }
                    }
                }
            }

            if($scope.selected_languages.length === 0 && $location.search().languages){
                var lang_array_from_url = $location.search().languages.split(',');
                $scope.selected_languages = [];
                for(var l = 0; l < $scope.language_options.length; l++){
                    for(var m = 0; m < lang_array_from_url.length; m++){
                        if($scope.language_options[l].value === lang_array_from_url[m]){
                            $scope.selected_languages.push($scope.language_options[l]);
                        }
                    }
                }
            }

            searchScenarios();
        }

        function searchScenarios(){

            var q = {
                q: $location.search().q,
                page: $location.search().page - 1,
                sort: $location.search().sort || 'latest',
                subjects: $location.search().subjects,
                languages: $location.search().languages,
            };

            requestService.get('/scenario/search/', q)
            .then(function(data) {

                /* ANALYTICS */
                if(q.q){
                    console.log('logged ANALYTICS');
                    $window.ga('send', 'event', 'Keyword', 'search', q.q);
                }

                if(data.scenarios){

                    $scope.total_count = data.count;

                    $scope.scenarios = data.scenarios;
                    if(typeof q !== 'undefined'){
                        $scope.search_word_end = q.q;
                    }else{
                        $scope.search_word_end = undefined;
                    }

                    for(var j = 0; j < $scope.scenarios.length; j++){
                        //translating subjects
                        for(var a = 0; a < $scope.scenarios[j].subjects.length; a++){
                            $scope.scenarios[j].subjects[a].name = $scope.scenarios[j].subjects[a]["name_"+$translate.use()];
                        }
                    }

                    $scope.loading_animation = false;
                }

                if(data.error){
                    console.log(data.error);
                }
            });

        }

        $scope.search = function() {

            var url_params = {};

            var selected_subjects_labels = [];
            var selected_languages_labels = [];

            // SORT
            if($location.search().sort){
                url_params.sort = $location.search().sort;
            }else{
                url_params.sort = 'latest';
            }

            // PAGE
            if($location.search().page){
                url_params.page = $location.search().page;

                //if new search word - start from 0
                if ($location.search().q !== $scope.search_word) {
                    url_params.page = 1;
                }
            }

            // SUBJECTS
            $scope.selected_subjects.forEach(function(element) {
                selected_subjects_labels.push(element._id);
            });
            if(selected_subjects_labels.length > 0){
                url_params.subjects = selected_subjects_labels.toString();
            }
            // LANGUAGES
            $scope.selected_languages.forEach(function(element) {
                selected_languages_labels.push(element.value);
            });
            if(selected_languages_labels.length  > 0){
                url_params.languages = selected_languages_labels.toString();
            }

            //SEARCH WORD
            url_params.q = $scope.search_word;

            $location.search(url_params);

        };

        $scope.pageChanged = function(new_page_nr) {
            $location.search('page', new_page_nr);
            getSearchParamsAndSearch();
            document.body.scrollTop = 0;
        };

        $scope.isSortActive = function(tab){
            if(!$location.search().sort && tab === 'latest'){ return true; }
            if(tab === $location.search().sort){ return true; }
            return false;
        };

        $scope.updateSortList = function(tab){
            if(tab === 'latest ' || tab === 'popular' || tab === 'favorited' || tab === 'commented'){
                if($location.search().sort !== tab){
                    $location.search('sort', tab);
                }
                getSearchParamsAndSearch();
            }else{
                $location.search('sort', 'latest');
                getSearchParamsAndSearch();
            }
        };

    }]); // SearchController end
}());
<commit_msg>fixed search sort to search order<commit_after>(function() {
    'use strict';

    angular
    .module('app')
    .controller('SearchController', ['$scope','$rootScope','requestService','$translate','$routeParams','$route','$window','$location',
    function($scope,$rootScope,requestService,$translate,$routeParams, $route, $window, $location) {

        $scope.loading_animation = true;
        $scope.search_page_nr = 1;
        $scope.total_count = 0;

        if($location.search().q){
            console.log('search ', $location.search().q);
            $scope.search_word = $location.search().q;
        }

        if($location.search().page){
            console.log('page ', $location.search().page);
            $scope.search_page_nr = $location.search().page;
        }

        if($location.search().subjects){
            console.log('subjects ', $location.search().subjects);
        }

        if($location.search().languages){
            console.log('languages ', $location.search().languages);
        }

        $translate('PAGE.SEARCH').then(function (t) {
            $rootScope.title = t+' | Leplanner beta';

            /* ANALYTICS */
            $window.ga('send', 'pageview', {
                'page': $location.path(),
                'title': $rootScope.title
            });
        });

        // INIT
        createDropDownMenusAndInitialSearch();

        function createDropDownMenusAndInitialSearch(){
            //  arrays to store selected multiple choices
            $scope.selected_subjects = [];

            $scope.subjectsSettings = {
                scrollableHeight: '400px',
                scrollable: true,
                enableSearch: true,
                smartButtonMaxItems: 3,
                displayProp: 'name',
                idProp: '_id',
                showCheckAll: false,
                //externalIdProp: '_id',
                externalIdProp: '',
                buttonClasses: 'btn btn-default btn-fixed-width',
            };

            //$scope.subjectsText = {buttonDefaultText: 'Filter subjects'};
            $scope.subjectsText = {
                buttonDefaultText: $rootScope.translated.dropdowns.subjects,
                uncheckAll: $rootScope.translated.dropdowns.uncheck_all,
                searchPlaceholder: $rootScope.translated.dropdowns.search
            };

            $scope.selected_languages = [];

            $scope.languagesSettings = {
                scrollableHeight: '400px',
                scrollable: false,
                enableSearch: false,
                smartButtonMaxItems: 3,
                displayProp: 'name',
                idProp: 'value',
                showCheckAll: false,
                showUncheckAll: false,
                //externalIdProp: '_id',
                externalIdProp: '',
                buttonClasses: 'btn btn-default btn-fixed-width',
            };

            //$scope.subjectsText = {buttonDefaultText: 'Filter subjects'};
            $scope.languagesText = {
                buttonDefaultText: $rootScope.translated.dropdowns.language,
                uncheckAll: $rootScope.translated.dropdowns.uncheck_all,
                searchPlaceholder: $rootScope.translated.dropdowns.search
            };

            $scope.language_options = [{name: $rootScope.translated.dropdowns.estonian, value: 'et'},{name: $rootScope.translated.dropdowns.english, value: 'en'}];

            requestService.get('/meta/subjects')
            .then(function(data) {
                if(data.subjects){
                    $scope.subjects = data.subjects;
                    for(var a = 0; a < $scope.subjects.length; a++){
                        $scope.subjects[a].name = $scope.subjects[a]["name_"+$translate.use()];
                    }

                    //Focus search
                    //angular.element('#search-word-input').trigger('focus');

                    // INITAL SEARCH
                    getSearchParamsAndSearch();
                }
                if(data.error){
                    console.log(data.error);
                }
            });
        }

        function getSearchParamsAndSearch(){

            $scope.loading_animation = true;

            //replace search word from top search
            if($rootScope.top_search_word){
                $scope.search_word = $rootScope.top_search_word;
                $rootScope.top_search_word = undefined;
                $scope.$parent.top_search_word = undefined;

                $location.search('q', $scope.search_word);
                return;
            }

            var subjects = [];
            var selected_subjects_labels = [];
            var selected_languages_labels = [];

            if($scope.selected_subjects.length === 0 && $location.search().subjects){
                var subject_array_from_url = $location.search().subjects.split(',');
                $scope.selected_subjects = [];
                for(var j = 0; j < $scope.subjects.length; j++){
                    for(var k = 0; k < subject_array_from_url.length; k++){
                        if($scope.subjects[j]._id === subject_array_from_url[k]){
                            $scope.selected_subjects.push($scope.subjects[j]);
                        }
                    }
                }
            }

            if($scope.selected_languages.length === 0 && $location.search().languages){
                var lang_array_from_url = $location.search().languages.split(',');
                $scope.selected_languages = [];
                for(var l = 0; l < $scope.language_options.length; l++){
                    for(var m = 0; m < lang_array_from_url.length; m++){
                        if($scope.language_options[l].value === lang_array_from_url[m]){
                            $scope.selected_languages.push($scope.language_options[l]);
                        }
                    }
                }
            }

            searchScenarios();
        }

        function searchScenarios(){

            var q = {
                q: $location.search().q,
                page: $location.search().page - 1,
                order: $location.search().sort || 'latest',
                subjects: $location.search().subjects,
                languages: $location.search().languages,
            };

            requestService.get('/scenarios/search/', q)
            .then(function(data) {

                /* ANALYTICS */
                if(q.q){
                    console.log('logged ANALYTICS');
                    $window.ga('send', 'event', 'Keyword', 'search', q.q);
                }

                if(data.scenarios){

                    $scope.total_count = data.count;

                    $scope.scenarios = data.scenarios;
                    if(typeof q !== 'undefined'){
                        $scope.search_word_end = q.q;
                    }else{
                        $scope.search_word_end = undefined;
                    }

                    for(var j = 0; j < $scope.scenarios.length; j++){
                        //translating subjects
                        for(var a = 0; a < $scope.scenarios[j].subjects.length; a++){
                            $scope.scenarios[j].subjects[a].name = $scope.scenarios[j].subjects[a]["name_"+$translate.use()];
                        }
                    }

                    $scope.loading_animation = false;
                }

                if(data.error){
                    console.log(data.error);
                }
            });

        }

        $scope.search = function() {

            var url_params = {};

            var selected_subjects_labels = [];
            var selected_languages_labels = [];

            // SORT
            if($location.search().sort){
                url_params.sort = $location.search().sort;
            }else{
                url_params.sort = 'latest';
            }

            // PAGE
            if($location.search().page){
                url_params.page = $location.search().page;

                //if new search word - start from 0
                if ($location.search().q !== $scope.search_word) {
                    url_params.page = 1;
                }
            }

            // SUBJECTS
            $scope.selected_subjects.forEach(function(element) {
                selected_subjects_labels.push(element._id);
            });
            if(selected_subjects_labels.length > 0){
                url_params.subjects = selected_subjects_labels.toString();
            }
            // LANGUAGES
            $scope.selected_languages.forEach(function(element) {
                selected_languages_labels.push(element.value);
            });
            if(selected_languages_labels.length  > 0){
                url_params.languages = selected_languages_labels.toString();
            }

            //SEARCH WORD
            url_params.q = $scope.search_word;

            $location.search(url_params);

        };

        $scope.pageChanged = function(new_page_nr) {
            $location.search('page', new_page_nr);
            getSearchParamsAndSearch();
            document.body.scrollTop = 0;
        };

        $scope.isSortActive = function(tab){
            if(!$location.search().sort && tab === 'latest'){ return true; }
            if(tab === $location.search().sort){ return true; }
            return false;
        };

        $scope.updateSortList = function(tab){
            if(tab === 'latest ' || tab === 'popular' || tab === 'favorited' || tab === 'commented'){
                if($location.search().sort !== tab){
                    $location.search('sort', tab);
                }
                getSearchParamsAndSearch();
            }else{
                $location.search('sort', 'latest');
                getSearchParamsAndSearch();
            }
        };

    }]); // SearchController end
}());
<|endoftext|>


<commit_before>'use strict'

// THIS IS FOR LOCAL DEVELOPMENT
var URL_SERVER = 'http://localhost:3000';
var socket = io.connect(URL_SERVER);

// THIS IS FOR UPLOAD TO HEROKU
// var socket = io();

$(document).ready(function() {

    socket.on('connect', function() {

        // DISPLAY WELCOME MESSAGE
        $('#messages').append("
Welcome to the chat. Choose an option...
");

        // DISPLAY MESSAGES FROM SERVER
        socket.on('message', function(data) {
            $('#messages').append("
" + data.server + "
");
        });

        // SENDING UI INFO TO SERVER
        $('.ui-1').click(function() {
            socket.emit('nav', {
                ui: "learn"
            });
        });
        $('.ui-2').click(function() {
            $('input').click();
            socket.emit('nav', {
                ui: "camera"
            });
        });
        $('.ui-3').click(function() {
            socket.emit('nav', {
                ui: "account"
            });
        });

        // HANDLES SENDING THE FILE TO SERVER
        $('#file_upload').change(function(event){
          var file = event.target.files[0];
          var stream = ss.createStream();

          ss(socket).emit('file-upload', stream, {name: file.name, size: file.size});
          ss.createBlobReadStream(file).pipe(stream);
        });
    });

});
<commit_msg>Modify welcome test<commit_after>'use strict'

// THIS IS FOR LOCAL DEVELOPMENT
var URL_SERVER = 'http://localhost:3000';
var socket = io.connect(URL_SERVER);

// THIS IS FOR UPLOAD TO HEROKU
// var socket = io();

$(document).ready(function() {

    socket.on('connect', function() {

        // DISPLAY WELCOME MESSAGE
        $('#messages').append("
Welcome to Mobile Chat POS. Choose an option...
");

        // DISPLAY MESSAGES FROM SERVER
        socket.on('message', function(data) {
            $('#messages').append("
" + data.server + "
");
        });

        // SENDING UI INFO TO SERVER
        $('.ui-1').click(function() {
            socket.emit('nav', {
                ui: "learn"
            });
        });
        $('.ui-2').click(function() {
            $('input').click();
            socket.emit('nav', {
                ui: "camera"
            });
        });
        $('.ui-3').click(function() {
            socket.emit('nav', {
                ui: "account"
            });
        });

        // HANDLES SENDING THE FILE TO SERVER
        $('#file_upload').change(function(event){
          var file = event.target.files[0];
          var stream = ss.createStream();

          ss(socket).emit('file-upload', stream, {name: file.name, size: file.size});
          ss.createBlobReadStream(file).pipe(stream);
        });
    });

});
<|endoftext|>


<commit_before>var midas = midas || {};
midas.slicerappstore = midas.slicerappstore || {};
midas.slicerappstore.totalResults = -1;
midas.slicerappstore.pageOffset = 0;

/**
 * Called when a user clicks to view the extension page
 */
midas.slicerappstore.extensionClick = function() {
  var url = json.global.webroot+'/slicerappstore/extension/view?extensionId='+$(this).attr('element')+'&layout='+json.layout;
  window.location.assign(url);
}

/**
 * Render the extension result in the result list area
 * @param extension Json-ified slicerpackages_extension dao
 */
midas.slicerappstore.renderExtension = function(extension, index) {
    var extensionName = extension.productname;
    var extDiv = $('#extensionTemplate').clone()
      .attr('id', 'extensionWrapper_'+extension.slicerpackages_extension_id);
    extDiv.attr('element', extension.slicerpackages_extension_id)
    .attr('extensionname', extensionName);
    extDiv.find('a.extensionName').html(extensionName)
      .attr('qtip', extensionName)
      .attr('element', extension.slicerpackages_extension_id)
      .qtip({
          content: {
              attr: 'qtip'
          },
          position: {
              at: 'bottom left',
              my: 'top left',
              viewport: $(window),
              effect: true
          }
      })
      .click(midas.slicerappstore.extensionClick);
    extDiv.find('span.subtitle').html(extension.subtitle);
    extDiv.find('img.extensionIcon').attr('src', extension.icon)
      .attr('element', extension.slicerpackages_extension_id)
      .attr('extensionname', extensionName)
      .click(midas.slicerappstore.extensionClick);
    extDiv.find('input.extensionActionButton')
      .attr('element', extension.slicerpackages_extension_id)
      .attr('extensionname', extensionName);

    var average = Math.round(extension.ratings.average * 100) / 100;
    var starSelect = Math.round(average * 2);
    extDiv.find('div.extensionRatings').find('input[value="'+starSelect+'"]').attr('checked', 'checked');
    extDiv.find('div.extensionRatings').attr('id', 'rating_'+extension.slicerpackages_extension_id)
      .stars({
          disabled: true,
          split: 2
      });
    extDiv.find('span.totalVotes').html('('+extension.ratings.total+')');

    extDiv.appendTo('#extensionsContainer');

    midas.slicerappstore.updateExtensionButtonState(extensionName);

    extDiv.fadeIn(200 * index);
}

/**
 * Reset variables, clear 'extensionsContainer' and show loading image.
 */
midas.slicerappstore.resetFilter = function(){
  midas.slicerappstore.totalResults = -1;
  midas.slicerappstore.pageOffset = 0;
  $('.paginationMessage').hide();
  $('.loadingExtensions').show();
  $('#extensionsContainer').html('');
}

/**
 * Compute number of items to fetch based on available width and height.
 * If no items have been fetched, number of items filling the available space plus an
 * extra row will be returned.
 * If items have already been fetched, number of items filling one row will be returned.
 */
midas.slicerappstore.pageLimit = function(){
    itemWidth = $('#extensionTemplate').outerWidth(true);
    itemHeight = $('#extensionTemplate').outerHeight(true);
    horizontalCount = Math.floor($('#extensionsContainer').width() / itemWidth);
    verticalCount = Math.floor(($(window).height() - $('.extensionsHeader').height()) / itemHeight);
    pageLimit = 0;
    if (midas.slicerappstore.totalResults == -1){
        pageLimit = horizontalCount * (verticalCount +1);
    }
    else {
        pageLimit = horizontalCount;
    }
    return pageLimit;
}

/**
 * Based on the filter parameters, return a page of extension results
 */
midas.slicerappstore.applyFilter = function() {
    midas.slicerappstore.resetFilter();
    $('#extensionsContainer').startScrollPagination();
}

/**
 * Render the category tree based on tokens separated by . character
 */
midas.slicerappstore.showCategory = function(category) {
    var tokens = category.split('.');
    var lastToken = '';
    var name = '';
    $.each(tokens, function(k, token) {
        var tokenId = token.replace(/ /g, '_');
        var parentId = lastToken == '' ? 'categoriesList' : 'category_'+lastToken;

        name += token;
        if(lastToken != '') { //subcategory
            lastToken += '_';
            var id = 'category_'+lastToken+tokenId;
            if($('#'+id).length == 0) {
                var html = '
'+token+'
';
                html = '
'+html+'
';
                var el = $('#'+parentId);
                while(el.next().length > 0) {
                    el = el.next(); //insert as last child
                }
                el.after(html);
            }
        } else { //top level category
            var id = 'category_'+tokenId;
            if($('#'+id).length == 0) {
                var html = '
'+token+'
';
                $('#'+parentId).append(html);
            }
        }
        lastToken += tokenId;
        name += '.';
    });
}

$(document).ready(function() {

    midas.slicerappstore.os = json.os;
    midas.slicerappstore.arch = json.arch;
    midas.slicerappstore.release = json.release;
    midas.slicerappstore.revision = json.revision;
    midas.slicerappstore.category = json.category;

    $('#osSelect').val(json.os);
    $('#archSelect').val(json.arch);
    $('#releaseSelect').val(json.release);
    // TODO revision?

    if(json.layout != 'empty' ) {
        midas.slicerappstore.os = $('#osSelect').val();
        midas.slicerappstore.arch = $('#archSelect').val();
        midas.slicerappstore.release = $('#releaseSelect').val();

        // Enable filtering by OS
        $('#osSelect').change(function() {
            midas.slicerappstore.os = $(this).val();
            midas.slicerappstore.applyFilter();
        });

        // Enable filtering by architecture
        $('#archSelect').change(function() {
            midas.slicerappstore.arch = $(this).val();
            midas.slicerappstore.applyFilter();
        });

        // Enable filtering by release
        $('#releaseSelect').change(function() {
            midas.slicerappstore.release = $(this).val();
            midas.slicerappstore.applyFilter();
        });
    }

    // Render the category tree based on all available categories
    $.each(json.categories, function(k, category) {
        midas.slicerappstore.showCategory(category);
    });

    // Enable the "All" category filter
    midas.slicerappstore.selectedCategory = $('li#categoryAll').click(function() {
        midas.slicerappstore.category = '';
        midas.slicerappstore.selectedCategory.removeClass('selectedCategory');
        midas.slicerappstore.selectedCategory = $(this);
        $(this).addClass('selectedCategory');
        midas.slicerappstore.applyFilter();
    });

    // Enable filtering by specific categories
    $('li.categoryControl').click(function() {
        console.log("Enable filtering by specific categories");
        midas.slicerappstore.category = $(this).attr('name');
        midas.slicerappstore.selectedCategory.removeClass('selectedCategory');
        midas.slicerappstore.selectedCategory = $(this);
        $(this).addClass('selectedCategory');
        midas.slicerappstore.applyFilter();
    });

    var selector = midas.slicerappstore.category == '' ?
        'li#categoryAll' :
        'li.categoryControl[name="'+midas.slicerappstore.category+'"]';
    midas.slicerappstore.selectedCategory = $(selector).addClass('selectedCategory');

    // Setup scroll pagination and fetch results based on the initial settings
    midas.slicerappstore.resetFilter();
    $('#extensionsContainer').scrollPagination({
      'contentPage': json.global.webroot+'/slicerappstore/index/listextensions',
      'contentData': function(){
          pageLimit = midas.slicerappstore.pageLimit();
          contentData = {
            category: midas.slicerappstore.category,
            os: midas.slicerappstore.os,
            arch: midas.slicerappstore.arch,
            release: midas.slicerappstore.release,
            revision: midas.slicerappstore.revision,
            limit: pageLimit,
            offset: midas.slicerappstore.pageOffset
          };
          midas.slicerappstore.pageOffset += pageLimit;
          // Stop fetch on scroll if "not the first query" and "all items have been fetched"
          if (midas.slicerappstore.totalResults != -1 &&
              midas.slicerappstore.pageOffset >= midas.slicerappstore.totalResults){
              $('#extensionsContainer').stopScrollPagination();
          }
          return contentData;
      },
      'scrollTarget': $(window),
      'heightOffset': 20,
      'dataType':'json',
      'onSuccess': function(obj, data){
          midas.slicerappstore.totalResults = data.total;
          $.each(data.extensions, function(index, extension) {
              midas.slicerappstore.renderExtension(extension, index);
          });
          if(data.total == 0) {
              $('.paginationMessage').show().text('No extensions found');
          }
      },
      'afterLoad': function(elementsLoaded){
          $('.loadingExtensions').hide();
      }
    });
});
<commit_msg>Re-factor code adding methods "idealNumberOfHorizontalItems", "idealNumberOfVerticalItems" and "idealNumberOfItems"<commit_after>var midas = midas || {};
midas.slicerappstore = midas.slicerappstore || {};
midas.slicerappstore.totalResults = -1;
midas.slicerappstore.pageOffset = 0;

/**
 * Called when a user clicks to view the extension page
 */
midas.slicerappstore.extensionClick = function() {
  var url = json.global.webroot+'/slicerappstore/extension/view?extensionId='+$(this).attr('element')+'&layout='+json.layout;
  window.location.assign(url);
}

/**
 * Render the extension result in the result list area
 * @param extension Json-ified slicerpackages_extension dao
 */
midas.slicerappstore.renderExtension = function(extension, index) {
    var extensionName = extension.productname;
    var extDiv = $('#extensionTemplate').clone()
      .attr('id', 'extensionWrapper_'+extension.slicerpackages_extension_id);
    extDiv.attr('element', extension.slicerpackages_extension_id)
    .attr('extensionname', extensionName);
    extDiv.find('a.extensionName').html(extensionName)
      .attr('qtip', extensionName)
      .attr('element', extension.slicerpackages_extension_id)
      .qtip({
          content: {
              attr: 'qtip'
          },
          position: {
              at: 'bottom left',
              my: 'top left',
              viewport: $(window),
              effect: true
          }
      })
      .click(midas.slicerappstore.extensionClick);
    extDiv.find('span.subtitle').html(extension.subtitle);
    extDiv.find('img.extensionIcon').attr('src', extension.icon)
      .attr('element', extension.slicerpackages_extension_id)
      .attr('extensionname', extensionName)
      .click(midas.slicerappstore.extensionClick);
    extDiv.find('input.extensionActionButton')
      .attr('element', extension.slicerpackages_extension_id)
      .attr('extensionname', extensionName);

    var average = Math.round(extension.ratings.average * 100) / 100;
    var starSelect = Math.round(average * 2);
    extDiv.find('div.extensionRatings').find('input[value="'+starSelect+'"]').attr('checked', 'checked');
    extDiv.find('div.extensionRatings').attr('id', 'rating_'+extension.slicerpackages_extension_id)
      .stars({
          disabled: true,
          split: 2
      });
    extDiv.find('span.totalVotes').html('('+extension.ratings.total+')');

    extDiv.appendTo('#extensionsContainer');

    midas.slicerappstore.updateExtensionButtonState(extensionName);

    extDiv.fadeIn(200 * index);
}

/**
 * Reset variables, clear 'extensionsContainer' and show loading image.
 */
midas.slicerappstore.resetFilter = function(){
  midas.slicerappstore.totalResults = -1;
  midas.slicerappstore.pageOffset = 0;
  $('.paginationMessage').hide();
  $('.loadingExtensions').show();
  $('#extensionsContainer').html('');
}

/**
 * Return the ideal number of items required to fill the space horizontally.
 */
midas.slicerappstore.idealNumberOfHorizontalItems = function(){
  itemWidth = $('#extensionTemplate').outerWidth(true);
  horizontalCount = Math.floor($('#extensionsContainer').width() / itemWidth);
  return horizontalCount;
}

/**
 * Return the ideal number of items required to fill the space vertically.
 */
midas.slicerappstore.idealNumberOfVerticalItems = function(){
  itemHeight = $('#extensionTemplate').outerHeight(true);
  verticalCount = Math.floor(($(window).height() - $('.extensionsHeader').height()) / itemHeight);
  return verticalCount;
}

/**
 * Return the ideal number of items required to fill the space horizontally and vertically.
 */
midas.slicerappstore.idealNumberOfItems = function(){
  return midas.slicerappstore.idealNumberOfHorizontalItems() *
      midas.slicerappstore.idealNumberOfVerticalItems();
}

/**
 * Compute number of items to fetch based on available width and height.
 * If no items have been fetched, number of items filling the available space plus an
 * extra row will be returned.
 * If items have already been fetched, number of items filling one row will be returned.
 */
midas.slicerappstore.pageLimit = function(){
    pageLimit = midas.slicerappstore.idealNumberOfHorizontalItems();
    if (midas.slicerappstore.totalResults == -1){
        pageLimit += midas.slicerappstore.idealNumberOfItems();
    }
    return pageLimit;
}

/**
 * Based on the filter parameters, return a page of extension results
 */
midas.slicerappstore.applyFilter = function() {
    midas.slicerappstore.resetFilter();
    $('#extensionsContainer').startScrollPagination();
}

/**
 * Render the category tree based on tokens separated by . character
 */
midas.slicerappstore.showCategory = function(category) {
    var tokens = category.split('.');
    var lastToken = '';
    var name = '';
    $.each(tokens, function(k, token) {
        var tokenId = token.replace(/ /g, '_');
        var parentId = lastToken == '' ? 'categoriesList' : 'category_'+lastToken;

        name += token;
        if(lastToken != '') { //subcategory
            lastToken += '_';
            var id = 'category_'+lastToken+tokenId;
            if($('#'+id).length == 0) {
                var html = '
'+token+'
';
                html = '
'+html+'
';
                var el = $('#'+parentId);
                while(el.next().length > 0) {
                    el = el.next(); //insert as last child
                }
                el.after(html);
            }
        } else { //top level category
            var id = 'category_'+tokenId;
            if($('#'+id).length == 0) {
                var html = '
'+token+'
';
                $('#'+parentId).append(html);
            }
        }
        lastToken += tokenId;
        name += '.';
    });
}

$(document).ready(function() {

    midas.slicerappstore.os = json.os;
    midas.slicerappstore.arch = json.arch;
    midas.slicerappstore.release = json.release;
    midas.slicerappstore.revision = json.revision;
    midas.slicerappstore.category = json.category;

    $('#osSelect').val(json.os);
    $('#archSelect').val(json.arch);
    $('#releaseSelect').val(json.release);
    // TODO revision?

    if(json.layout != 'empty' ) {
        midas.slicerappstore.os = $('#osSelect').val();
        midas.slicerappstore.arch = $('#archSelect').val();
        midas.slicerappstore.release = $('#releaseSelect').val();

        // Enable filtering by OS
        $('#osSelect').change(function() {
            midas.slicerappstore.os = $(this).val();
            midas.slicerappstore.applyFilter();
        });

        // Enable filtering by architecture
        $('#archSelect').change(function() {
            midas.slicerappstore.arch = $(this).val();
            midas.slicerappstore.applyFilter();
        });

        // Enable filtering by release
        $('#releaseSelect').change(function() {
            midas.slicerappstore.release = $(this).val();
            midas.slicerappstore.applyFilter();
        });
    }

    // Render the category tree based on all available categories
    $.each(json.categories, function(k, category) {
        midas.slicerappstore.showCategory(category);
    });

    // Enable the "All" category filter
    midas.slicerappstore.selectedCategory = $('li#categoryAll').click(function() {
        midas.slicerappstore.category = '';
        midas.slicerappstore.selectedCategory.removeClass('selectedCategory');
        midas.slicerappstore.selectedCategory = $(this);
        $(this).addClass('selectedCategory');
        midas.slicerappstore.applyFilter();
    });

    // Enable filtering by specific categories
    $('li.categoryControl').click(function() {
        console.log("Enable filtering by specific categories");
        midas.slicerappstore.category = $(this).attr('name');
        midas.slicerappstore.selectedCategory.removeClass('selectedCategory');
        midas.slicerappstore.selectedCategory = $(this);
        $(this).addClass('selectedCategory');
        midas.slicerappstore.applyFilter();
    });

    var selector = midas.slicerappstore.category == '' ?
        'li#categoryAll' :
        'li.categoryControl[name="'+midas.slicerappstore.category+'"]';
    midas.slicerappstore.selectedCategory = $(selector).addClass('selectedCategory');

    // Setup scroll pagination and fetch results based on the initial settings
    midas.slicerappstore.resetFilter();
    $('#extensionsContainer').scrollPagination({
      'contentPage': json.global.webroot+'/slicerappstore/index/listextensions',
      'contentData': function(){
          pageLimit = midas.slicerappstore.pageLimit();
          contentData = {
            category: midas.slicerappstore.category,
            os: midas.slicerappstore.os,
            arch: midas.slicerappstore.arch,
            release: midas.slicerappstore.release,
            revision: midas.slicerappstore.revision,
            limit: pageLimit,
            offset: midas.slicerappstore.pageOffset
          };
          midas.slicerappstore.pageOffset += pageLimit;
          // Stop fetch on scroll if "not the first query" and "all items have been fetched"
          if (midas.slicerappstore.totalResults != -1 &&
              midas.slicerappstore.pageOffset >= midas.slicerappstore.totalResults){
              $('#extensionsContainer').stopScrollPagination();
          }
          return contentData;
      },
      'scrollTarget': $(window),
      'heightOffset': 20,
      'dataType':'json',
      'onSuccess': function(obj, data){
          midas.slicerappstore.totalResults = data.total;
          $.each(data.extensions, function(index, extension) {
              midas.slicerappstore.renderExtension(extension, index);
          });
          if(data.total == 0) {
              $('.paginationMessage').show().text('No extensions found');
          }
      },
      'afterLoad': function(elementsLoaded){
          $('.loadingExtensions').hide();
      }
    });
});
<|endoftext|>


<commit_before>;(function($, crud){

    var crud_actions = {
        open_form: function(elem)
        {
            crud.init_modal(elem.data("id"), elem.data("model"));
        }
    };

    crud.bind('page.start', function()
    {
        crud.add_actions(crud_actions);
        init_events();
    });

    function init_events()
    {
        $('#crud_form').modal({backdrop:'static', 'keyboard':false, 'show':false})

        $(crud.doc).on('change','.crud_checkbox', function () {

            var name = $(this).data('name');
            var hidden = $(this).parents('form').first().find('input[name='+name+']');
            if ($(this).prop('checked'))
            {
                hidden.val('1');
            } else
            {
                hidden.val('0');
            }
        });

        $(crud.doc).on('submit', '#crud_filter_form', function (e) {
            e.preventDefault();
            var $form = $(this);
            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit(
                {
                    type:'POST',
                    url: crud.format_setting("model_filter_url", {model: crud.crudObj['class_name'], context: $(this).data('crud_context')}),
                    //url: '/admin/crud/'+crud.crudObj['class_name']+'/filter/'+$(this).data('crud_context'),
                    dataType: 'json',
                    success: function (res) {
                        crud.toggle_form_progress($form)
                        crud.trigger('crud.filter_set', res);

                    }

                }
            );

        });

        $(crud.doc).on('reset', '#crud_filter_form', function (e) {
            //e.preventDefault();
            var $form = $(this);
            $('select', $form).each(function (){
               $(this).select2("val", null);
            });

            $('input', $form).each(function (){
                $(this).val('');
            });

            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit(
                {
                    type:'POST',
                    url: crud.format_setting('model_filter_url', {model: crud.crudObj['class_name'], context: $(this).data('crud_context')}),
                    //url: '/admin/crud/'+crud.crudObj['class_name']+'/filter/'+$(this).data('crud_context'),
                    dataType: 'json',
                    success: function (res) {
                        crud.toggle_form_progress($form)
                        crud.trigger('crud.filter_set',res);
                    }

                }
            );

        });

        $(crud.doc).on('click', '.crud_submit', function (e)
        {
            e.preventDefault();
            var frm = $(this).parents("form:first");
            var attrs = ['close', 'reload'];
            for (var i =0; i<attrs.length; i++)
            {
                if ($(this).data(attrs[i]) != undefined)
                {
                    frm.data(attrs[i], $(this).data(attrs[i]));
                }
            }
            frm.submit();

        });

        $(crud.doc).on('submit', 'form[data-crud_form=ajax]', function(e)
        {
            e.preventDefault();
            var $form = $(this);
            crud.toggle_editors_content($form);
            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit({
                type: $form.attr('method'),
                url: $form.attr('action'),
                dataType: 'json',
                success: function(res){
                    crud.toggle_form_progress($form);
                    if (res.success)
                    {
                        if ($form.data('crud_model'))
                        {
                            if ($form.data('close'))
                            {
                                crud.trigger('crud.update', res);
                            }
                            else
                            {
                                crud.trigger("crud.reload", res);
                                crud.init_modal(res.crud_id, $form.data("crud_model"));
                            }
                            $('#crud_form form').trigger('reset');
                            crud.reset_selects();
                        }
                        else
                        {
                            if (res.message)
                            {
                                alert(res.message);
                            }
                            crud.trigger('crud.submitted', {form_id: $form.attr('id'), res: res, frm: $form});
                        }
                        if ($form.data("close"))
                        {
                            $form.parents(".modal:first").modal('hide');
                        }
                        if ($form.data("reload"))
                        {
                            crud.loc.reload();
                        }
                    }
                    else
                    {
                        alert(format_error(res.error));
                    }
                },
                error: function(res){
                    crud.toggle_form_progress($form);
                    alert(format_error(res.responseJSON.error.message))
                }
            });
        });

        $(crud.doc).on('click', '*[data-clone_fragment]', function (e) {
            e.preventDefault();
            clone_fragment($(this).data('clone_fragment'),$(this).data('clone_container'));

        });

        function clone_fragment(tpl_id, container_id)
        {
            var $tpl = $('#'+tpl_id).clone(true).attr('id','');
            var qtyAdded = $('#'+container_id).find('*[data-added]').length;

            $tpl.find('*[name]').each(function ()
            {
                $(this).attr('disabled', false);
                var name = $(this).attr('name');
                if (name.indexOf('[]')>0)
                {
                    var newName = name.replace('[]','')+'[-'+(qtyAdded+1)+']';
                    $(this).attr('name', newName)
                }
            });
            $tpl.attr('data-added',1);
            //calc order
            var ord  = $('#'+container_id).find('*[data-order]:visible').length;
            $tpl.find('*[data-order]').val((ord+1));

            $tpl.appendTo($('#'+container_id)).show();

        }

        function format_error(error)
        {
            if (error.indexOf("SQLSTATE[23000]")>=0)
            {
                return 'Невозможно сохранить: ДУБЛИКАТ';
            }
            else
            {
                return 'Произошла ошибка: ' + error;
            }

        }

    }

})(jQuery, CRUD)<commit_msg>-- js refactor<commit_after>;(function($, crud){

    var crud_actions = {
        open_form: function(elem)
        {
            crud.init_modal(elem.data("id"), elem.data("model"));
        }
    };

    crud.bind('page.start', function()
    {
        crud.add_actions(crud_actions);
        init_events();
    });

    function init_events()
    {
        $('#crud_form').modal({backdrop:'static', 'keyboard':false, 'show':false})

        $(crud.doc).on('change','.crud_checkbox', function () {

            var name = $(this).data('name');
            var hidden = $(this).parents('form').first().find('input[name='+name+']');
            if ($(this).prop('checked'))
            {
                hidden.val('1');
            } else
            {
                hidden.val('0');
            }
        });

        $(crud.doc).on('submit', '#crud_filter_form', function (e) {
            e.preventDefault();
            var $form = $(this);
            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit(
                {
                    type:'POST',
                    url: crud.format_setting("model_filter_url", {model: crud.crudObj['class_name'], context: $(this).data('crud_context')}),
                    //url: '/admin/crud/'+crud.crudObj['class_name']+'/filter/'+$(this).data('crud_context'),
                    dataType: 'json',
                    success: function (res) {
                        crud.toggle_form_progress($form)
                        crud.trigger('crud.filter_set', res);

                    }

                }
            );

        });

        $(crud.doc).on('reset', '#crud_filter_form', function (e) {
            //e.preventDefault();
            var $form = $(this);
            $('select', $form).each(function (){
               $(this).select2("val", null);
            });

            $('input', $form).each(function (){
                $(this).val('');
            });

            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit(
                {
                    type:'POST',
                    url: crud.format_setting('model_filter_url', {model: crud.crudObj['class_name'], context: $(this).data('crud_context')}),
                    //url: '/admin/crud/'+crud.crudObj['class_name']+'/filter/'+$(this).data('crud_context'),
                    dataType: 'json',
                    success: function (res) {
                        crud.toggle_form_progress($form)
                        crud.trigger('crud.filter_set',res);
                    }

                }
            );

        });

        $(crud.doc).on('click', '.crud_submit', function (e)
        {
            e.preventDefault();
            var frm = $(this).parents("form:first");
            var attrs = ['close', 'reload'];
            for (var i =0; i<attrs.length; i++)
            {
                if ($(this).data(attrs[i]) != undefined)
                {
                    frm.data(attrs[i], $(this).data(attrs[i]));
                }
            }
            frm.submit();

        });

        $(crud.doc).on('submit', 'form[data-crud_form=ajax]', function(e)
        {
            e.preventDefault();
            var $form = $(this);
            crud.toggle_editors_content($form);
            crud.toggle_form_progress($form);
            crud.init_form_progress($form);
            $form.ajaxSubmit({
                type: $form.attr('method'),
                url: $form.attr('action'),
                dataType: 'json',
                success: function(res){
                    crud.toggle_form_progress($form);
                    if (res.success)
                    {
                        if ($form.data('crud_model'))
                        {
                            if ($form.data('close'))
                            {
                                crud.trigger('crud.update', res);
                            }
                            else
                            {
                                crud.trigger("crud.reload", res);
                                crud.init_modal(res.crud_id, $form.data("crud_model"));
                            }
                            $('#crud_form form').trigger('reset');
                            crud.reset_selects();
                        }
                        else
                        {
                            if (res.message)
                            {
                                alert(res.message);
                            }
                            if ($form.data('callback_event'))
                            {
                                crud.trigger($form.data('callback_event'));
                            }
                            crud.trigger('crud.submitted', {form_id: $form.attr('id'), res: res, frm: $form});
                        }
                        if ($form.data("close"))
                        {
                            $form.parents(".modal:first").modal('hide');
                        }
                        if ($form.data("reload"))
                        {
                            crud.loc.reload();
                        }
                    }
                    else
                    {
                        alert(format_error(res.error));
                    }
                },
                error: function(res){
                    crud.toggle_form_progress($form);
                    alert(format_error(res.responseJSON.error.message))
                }
            });
        });

        $(crud.doc).on('click', '*[data-clone_fragment]', function (e) {
            e.preventDefault();
            clone_fragment($(this).data('clone_fragment'),$(this).data('clone_container'));

        });

        function clone_fragment(tpl_id, container_id)
        {
            var $tpl = $('#'+tpl_id).clone(true).attr('id','');
            var qtyAdded = $('#'+container_id).find('*[data-added]').length;

            $tpl.find('*[name]').each(function ()
            {
                $(this).attr('disabled', false);
                var name = $(this).attr('name');
                if (name.indexOf('[]')>0)
                {
                    var newName = name.replace('[]','')+'[-'+(qtyAdded+1)+']';
                    $(this).attr('name', newName)
                }
            });
            $tpl.attr('data-added',1);
            //calc order
            var ord  = $('#'+container_id).find('*[data-order]:visible').length;
            $tpl.find('*[data-order]').val((ord+1));

            $tpl.appendTo($('#'+container_id)).show();

        }

        function format_error(error)
        {
            if (error.indexOf("SQLSTATE[23000]")>=0)
            {
                return 'Невозможно сохранить: ДУБЛИКАТ';
            }
            else
            {
                return 'Произошла ошибка: ' + error;
            }

        }

    }

})(jQuery, CRUD)<|endoftext|>


<commit_before>class CoreImageUtils {
  static resample(file, maxWidth, asBlob) {
    return new Promise((resolve, reject) => {
      const loadImage = window.loadImage;
      if (!loadImage) {
        reject("Failed to load image parse library");
        return;
      }
      loadImage.parseMetaData(file, (data) => {
        let orientation = 0;
        if (data.exif) {
          orientation = data.exif.get('Orientation');
        }
        let config = {
          canvas: true,
          orientation: orientation
        };
        if (maxWidth) {
          config.maxWidth = maxWidth;
        }
        loadImage(file, (canvas) => {
          if (asBlob) {
            canvas.toBlob((blob) => {
              resolve(blob);
            }, 'image/jpeg');
          } else {
            var base64data = canvas.toDataURL('image/jpeg');
            resolve(base64data);
          }
        }, config);
      });
    });
  }
}

class StorageService {
  getItem(key, json) {
    const result = this._getItemFromStorage(window.localStorage, key, json);
    if (result) {
      return result;
    }
    return this._getItemFromStorage(window.sessionStorage, key, json);
  }

  _getItemFromStorage(storage, key, json) {
    if (storage) {
      let stored = storage.getItem(key) || null;
      if (json) {
        if (stored) {
          return JSON.parse(stored);
        }
        return null;
      }
      return stored;
    } else {
      return null;
    }
  }

  setItem(key, value, trust) {
    this.clearItem(key);
    const storage = trust ? window.localStorage : window.sessionStorage;
    if (storage) {
      if (typeof value === "string") {
        storage.setItem(key, value);
      } else {
        storage.setItem(key, JSON.stringify(value));
      }
    }
  }

  clearItem(key) {
    if (window.localStorage) {
      window.localStorage.removeItem(key);
    }
    if (window.sessionStorage) {
      window.sessionStorage.removeItem(key);
    }
  }
}

class EncryptionUtils {
  static encryptString(value, password) {
    const vector = crypto.getRandomValues(new Uint8Array(16));
    const subtle = crypto.subtle || crypto.webkitSubtle;
    return subtle.digest({ name: "SHA-256" }, this._convertStringToArrayBufferView(password)).then((digest) => {
      return subtle.importKey("raw", digest, { name: "AES-CBC" }, false, ["encrypt"]).then((key) => {
        return subtle.encrypt({
          name: "AES-CBC",
          iv: vector
        },
          key,
          this._convertStringToArrayBufferView(value)
        ).then((encrypted) => {
          const buf = this._combineBuffers(vector, new Uint8Array(encrypted));
          return this.toHexString(buf);
        });
      });
    });
  }

  static decryptString(encryptedHex, password) {
    const combined = this.hexStringToByteArray(encryptedHex);
    const vector = combined.subarray(0, 16);
    const encrypted = combined.subarray(16);
    const subtle = crypto.subtle || crypto.webkitSubtle;
    return subtle.digest({ name: "SHA-256" }, this._convertStringToArrayBufferView(password)).then((digest) => {
      return subtle.importKey("raw", digest, { name: "AES-CBC" }, false, ["decrypt"]).then((key) => {
        return subtle.decrypt({
          name: "AES-CBC",
          iv: vector
        },
          key,
          encrypted
        ).then((decrypted) => {
          return this._convertArrayBufferViewtoString(new Uint8Array(decrypted));
        });
      });
    });
  }

  static toHexString(byteArray) {
    return Array.prototype.map.call(byteArray, function (byte) {
      return ('0' + (byte & 0xFF).toString(16)).slice(-2);
    }).join('');
  }

  static hexStringToByteArray(hexString) {
    var result = [];
    while (hexString.length >= 2) {
      result.push(parseInt(hexString.substring(0, 2), 16));
      hexString = hexString.substring(2, hexString.length);
    }
    return Uint8Array.from(result);
  }

  static _combineBuffers(a, b) {
    const c = new Uint8Array(a.length + b.length);
    c.set(a);
    c.set(b, a.length);
    return c;
  }

  static _convertStringToArrayBufferView(str) {
    const bytes = new Uint8Array(str.length);
    for (var iii = 0; iii < str.length; iii++) {
      bytes[iii] = str.charCodeAt(iii);
    }
    return bytes;
  }

  static _convertArrayBufferViewtoString(buffer) {
    let str = "";
    for (var iii = 0; iii < buffer.byteLength; iii++) {
      str += String.fromCharCode(buffer[iii]);
    }
    return str;
  }
}<commit_msg>if file being resampled is png, keep as png<commit_after>class CoreImageUtils {
  static resample(file, maxWidth, asBlob) {
    return new Promise((resolve, reject) => {
      const loadImage = window.loadImage;
      if (!loadImage) {
        reject("Failed to load image parse library");
        return;
      }
      loadImage.parseMetaData(file, (data) => {
        let orientation = 0;
        if (data.exif) {
          orientation = data.exif.get('Orientation');
        }
        let config = {
          canvas: true,
          orientation: orientation
        };
        if (maxWidth) {
          config.maxWidth = maxWidth;
        }
        loadImage(file, (canvas) => {
          let fileType = 'image/jpeg';
          if (file.type && file.type === 'image/png') {
            fileType = file.type;
          }
          if (asBlob) {
            canvas.toBlob((blob) => {
              resolve(blob);
            }, fileType);
          } else {
            var base64data = canvas.toDataURL(fileType);
            resolve(base64data);
          }
        }, config);
      });
    });
  }
}

class StorageService {
  getItem(key, json) {
    const result = this._getItemFromStorage(window.localStorage, key, json);
    if (result) {
      return result;
    }
    return this._getItemFromStorage(window.sessionStorage, key, json);
  }

  _getItemFromStorage(storage, key, json) {
    if (storage) {
      let stored = storage.getItem(key) || null;
      if (json) {
        if (stored) {
          return JSON.parse(stored);
        }
        return null;
      }
      return stored;
    } else {
      return null;
    }
  }

  setItem(key, value, trust) {
    this.clearItem(key);
    const storage = trust ? window.localStorage : window.sessionStorage;
    if (storage) {
      if (typeof value === "string") {
        storage.setItem(key, value);
      } else {
        storage.setItem(key, JSON.stringify(value));
      }
    }
  }

  clearItem(key) {
    if (window.localStorage) {
      window.localStorage.removeItem(key);
    }
    if (window.sessionStorage) {
      window.sessionStorage.removeItem(key);
    }
  }
}

class EncryptionUtils {
  static encryptString(value, password) {
    const vector = crypto.getRandomValues(new Uint8Array(16));
    const subtle = crypto.subtle || crypto.webkitSubtle;
    return subtle.digest({ name: "SHA-256" }, this._convertStringToArrayBufferView(password)).then((digest) => {
      return subtle.importKey("raw", digest, { name: "AES-CBC" }, false, ["encrypt"]).then((key) => {
        return subtle.encrypt({
          name: "AES-CBC",
          iv: vector
        },
          key,
          this._convertStringToArrayBufferView(value)
        ).then((encrypted) => {
          const buf = this._combineBuffers(vector, new Uint8Array(encrypted));
          return this.toHexString(buf);
        });
      });
    });
  }

  static decryptString(encryptedHex, password) {
    const combined = this.hexStringToByteArray(encryptedHex);
    const vector = combined.subarray(0, 16);
    const encrypted = combined.subarray(16);
    const subtle = crypto.subtle || crypto.webkitSubtle;
    return subtle.digest({ name: "SHA-256" }, this._convertStringToArrayBufferView(password)).then((digest) => {
      return subtle.importKey("raw", digest, { name: "AES-CBC" }, false, ["decrypt"]).then((key) => {
        return subtle.decrypt({
          name: "AES-CBC",
          iv: vector
        },
          key,
          encrypted
        ).then((decrypted) => {
          return this._convertArrayBufferViewtoString(new Uint8Array(decrypted));
        });
      });
    });
  }

  static toHexString(byteArray) {
    return Array.prototype.map.call(byteArray, function (byte) {
      return ('0' + (byte & 0xFF).toString(16)).slice(-2);
    }).join('');
  }

  static hexStringToByteArray(hexString) {
    var result = [];
    while (hexString.length >= 2) {
      result.push(parseInt(hexString.substring(0, 2), 16));
      hexString = hexString.substring(2, hexString.length);
    }
    return Uint8Array.from(result);
  }

  static _combineBuffers(a, b) {
    const c = new Uint8Array(a.length + b.length);
    c.set(a);
    c.set(b, a.length);
    return c;
  }

  static _convertStringToArrayBufferView(str) {
    const bytes = new Uint8Array(str.length);
    for (var iii = 0; iii < str.length; iii++) {
      bytes[iii] = str.charCodeAt(iii);
    }
    return bytes;
  }

  static _convertArrayBufferViewtoString(buffer) {
    let str = "";
    for (var iii = 0; iii < buffer.byteLength; iii++) {
      str += String.fromCharCode(buffer[iii]);
    }
    return str;
  }
}<|endoftext|>


<commit_before>/**
 * Collaborator.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/documentation/concepts/models-and-orm/models

 */
var _ = require('lodash');
var md5 = require('md5');

module.exports = {

  attributes: {
    name: {
      type: Sequelize.STRING,
      allowNull: false
    },

    email: {
      type: Sequelize.STRING,
      unique: true
    }

  },
  associations: function() {
    Collaborator.belongsToMany(PackageVersion, {as: 'authored_packages', through: 'Collaborations', foreignKey: 'author_id', timestamps: false});
    Collaborator.hasMany(PackageVersion, {as: 'maintained_packages', foreignKey: 'maintainer_id'});
  },

  options: {
    getterMethods: {
      api_uri: function()  {
        return '/api/collaborators/:id'
          .replace(':id', this.id);
      },
      uri: function()  {
        return '/collaborators/:id'
          .replace(':id', this.id);
      },
      gravatar_url: function(){
        return 'https://www.gravatar.com/avatar/' + md5(_.trim(this.email).toLowerCase());
      }
    },
    underscored: true,

    classMethods: {

      /**
      * author is an object with attributes name and optionnally email
      *
      */
      insertAuthor: function(author, options) {
        var where = author;

        var params = _.defaults({
          where: where,
          defaults: author,
          order: [['email', 'DESC']]
        }, options);

        return Collaborator.findOrCreate(params)
        .spread(function(instance, created) {
          if (instance.email === null && author.email) {
            return instance.update({email: author.email}, options);
          } else return instance;
        });
      }

    }

  }

};

<commit_msg>find on email if email exists<commit_after>/**
 * Collaborator.js
 *
 * @description :: TODO: You might write a short summary of how this model works and what it represents here.
 * @docs        :: http://sailsjs.org/documentation/concepts/models-and-orm/models

 */
var _ = require('lodash');
var md5 = require('md5');

module.exports = {

  attributes: {
    name: {
      type: Sequelize.STRING,
      allowNull: false
    },

    email: {
      type: Sequelize.STRING,
      unique: true
    }

  },
  associations: function() {
    Collaborator.belongsToMany(PackageVersion, {as: 'authored_packages', through: 'Collaborations', foreignKey: 'author_id', timestamps: false});
    Collaborator.hasMany(PackageVersion, {as: 'maintained_packages', foreignKey: 'maintainer_id'});
  },

  options: {
    getterMethods: {
      api_uri: function()  {
        return '/api/collaborators/:id'
          .replace(':id', this.id);
      },
      uri: function()  {
        return '/collaborators/:id'
          .replace(':id', this.id);
      },
      gravatar_url: function(){
        return 'https://www.gravatar.com/avatar/' + md5(_.trim(this.email).toLowerCase());
      }
    },
    underscored: true,

    classMethods: {

      /**
      * author is an object with attributes name and optionnally email
      *
      */
      insertAuthor: function(author, options) {
        var where = author;
        if(author.email) {
          where = {
            email: email
          };
        }

        var params = _.defaults({
          where: where,
          defaults: author,
          order: [['email', 'DESC']]
        }, options);

        return Collaborator.findOrCreate(params)
        .spread(function(instance, created) {
          if (instance.email === null && author.email) {
            return instance.update({email: author.email}, options);
          } else return instance;
        });
      }

    }

  }

};

<|endoftext|>