UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

1,516 lines (1,252 loc) 74.6 kB
/* * jQuery Mobile v1.3.1 * http://jquerymobile.com * * Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license. * http://jquery.org/license * */ (function ( root, doc, factory ) { if ( typeof define === "function" && define.amd ) { // AMD. Register as an anonymous module. define( [ "jquery" ], function ( $ ) { factory( $, root, doc ); return $.mobile; }); } else { // Browser globals factory( root.jQuery, root, doc ); } }( this, document, function ( jQuery, window, document, undefined ) { // Script: jQuery hashchange event // // *Version: 1.3, Last updated: 7/21/2010* // // Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ // GitHub - http://github.com/cowboy/jquery-hashchange/ // Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js // (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) // // About: License // // Copyright (c) 2010 "Cowboy" Ben Alman, // Dual licensed under the MIT and GPL licenses. // http://benalman.com/about/license/ // // About: Examples // // These working examples, complete with fully commented code, illustrate a few // ways in which this plugin can be used. // // hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ // document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ // // About: Support and Testing // // Information about what version or versions of jQuery this plugin has been // tested with, what browsers it has been tested in, and where the unit tests // reside (so you can test it yourself). // // jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 // Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, // Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. // Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ // // About: Known issues // // While this jQuery hashchange event implementation is quite stable and // robust, there are a few unfortunate browser bugs surrounding expected // hashchange event-based behaviors, independent of any JavaScript // window.onhashchange abstraction. See the following examples for more // information: // // Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ // Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ // WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ // Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ // // Also note that should a browser natively support the window.onhashchange // event, but not report that it does, the fallback polling loop will be used. // // About: Release History // // 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more // "removable" for mobile-only development. Added IE6/7 document.title // support. Attempted to make Iframe as hidden as possible by using // techniques from http://www.paciellogroup.com/blog/?p=604. Added // support for the "shortcut" format $(window).hashchange( fn ) and // $(window).hashchange() like jQuery provides for built-in events. // Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and // lowered its default value to 50. Added <jQuery.fn.hashchange.domain> // and <jQuery.fn.hashchange.src> properties plus document-domain.html // file to address access denied issues when setting document.domain in // IE6/7. // 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin // from a page on another domain would cause an error in Safari 4. Also, // IE6/7 Iframe is now inserted after the body (this actually works), // which prevents the page from scrolling when the event is first bound. // Event can also now be bound before DOM ready, but it won't be usable // before then in IE6/7. // 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug // where browser version is incorrectly reported as 8.0, despite // inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. // 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special // window.onhashchange functionality into a separate plugin for users // who want just the basic event & back button support, without all the // extra awesomeness that BBQ provides. This plugin will be included as // part of jQuery BBQ, but also be available separately. (function( $, window, undefined ) { // Reused string. var str_hashchange = 'hashchange', // Method / object references. doc = document, fake_onhashchange, special = $.event.special, // Does the browser support window.onhashchange? Note that IE8 running in // IE7 compatibility mode reports true for 'onhashchange' in window, even // though the event isn't supported, so also test document.documentMode. doc_mode = doc.documentMode, supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); // Get location.hash (or what you'd expect location.hash to be) sans any // leading #. Thanks for making this necessary, Firefox! function get_fragment( url ) { url = url || location.href; return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); }; // Method: jQuery.fn.hashchange // // Bind a handler to the window.onhashchange event or trigger all bound // window.onhashchange event handlers. This behavior is consistent with // jQuery's built-in event handlers. // // Usage: // // > jQuery(window).hashchange( [ handler ] ); // // Arguments: // // handler - (Function) Optional handler to be bound to the hashchange // event. This is a "shortcut" for the more verbose form: // jQuery(window).bind( 'hashchange', handler ). If handler is omitted, // all bound window.onhashchange event handlers will be triggered. This // is a shortcut for the more verbose // jQuery(window).trigger( 'hashchange' ). These forms are described in // the <hashchange event> section. // // Returns: // // (jQuery) The initial jQuery collection of elements. // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and // $(elem).hashchange() for triggering, like jQuery does for built-in events. $.fn[ str_hashchange ] = function( fn ) { // MODIFIED BY SAP: replace deprecated API .bind -> .on return fn ? this.on( str_hashchange, fn ) : this.trigger( str_hashchange ); }; // Property: jQuery.fn.hashchange.delay // // The numeric interval (in milliseconds) at which the <hashchange event> // polling loop executes. Defaults to 50. // Property: jQuery.fn.hashchange.domain // // If you're setting document.domain in your JavaScript, and you want hash // history to work in IE6/7, not only must this property be set, but you must // also set document.domain BEFORE jQuery is loaded into the page. This // property is only applicable if you are supporting IE6/7 (or IE8 operating // in "IE7 compatibility" mode). // // In addition, the <jQuery.fn.hashchange.src> property must be set to the // path of the included "document-domain.html" file, which can be renamed or // modified if necessary (note that the document.domain specified must be the // same in both your main JavaScript as well as in this file). // // Usage: // // jQuery.fn.hashchange.domain = document.domain; // Property: jQuery.fn.hashchange.src // // If, for some reason, you need to specify an Iframe src file (for example, // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can // do so using this property. Note that when using this property, history // won't be recorded in IE6/7 until the Iframe src file loads. This property // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 // compatibility" mode). // // Usage: // // jQuery.fn.hashchange.src = 'path/to/file.html'; $.fn[ str_hashchange ].delay = 50; /* $.fn[ str_hashchange ].domain = null; $.fn[ str_hashchange ].src = null; */ // Event: hashchange event // // Fired when location.hash changes. In browsers that support it, the native // HTML5 window.onhashchange event is used, otherwise a polling loop is // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to // see if the hash has changed. // // Usage as described in <jQuery.fn.hashchange>: // // > // Bind an event handler. // > jQuery(window).hashchange( function(e) { // > var hash = location.hash; // > ... // > }); // > // > // Manually trigger the event handler. // > jQuery(window).hashchange(); // // A more verbose usage that allows for event namespacing: // // > // Bind an event handler. // > jQuery(window).bind( 'hashchange', function(e) { // > var hash = location.hash; // > ... // > }); // > // > // Manually trigger the event handler. // > jQuery(window).trigger( 'hashchange' ); // // Additional Notes: // // * The polling loop and Iframe are not created until at least one handler // is actually bound to the 'hashchange' event. // * If you need the bound handler(s) to execute immediately, in cases where // a location.hash exists on page load, via bookmark or page refresh for // example, use jQuery(window).hashchange() or the more verbose // jQuery(window).trigger( 'hashchange' ). // * The event can be bound before DOM ready, but since it won't be usable // before then in IE6/7 (due to the necessary Iframe), recommended usage is // to bind it inside a DOM ready handler. // Override existing $.event.special.hashchange methods (allowing this plugin // to be defined after jQuery BBQ in BBQ's source code). special[ str_hashchange ] = $.extend( special[ str_hashchange ], { // Called only when the first 'hashchange' event is bound to window. setup: function() { // If window.onhashchange is supported natively, there's nothing to do.. if ( supports_onhashchange ) { return false; } // Otherwise, we need to create our own. And we don't want to call this // until the user binds to the event, just in case they never do, since it // will create a polling loop and possibly even a hidden Iframe. $( fake_onhashchange.start ); }, // Called only when the last 'hashchange' event is unbound from window. teardown: function() { // If window.onhashchange is supported natively, there's nothing to do.. if ( supports_onhashchange ) { return false; } // Otherwise, we need to stop ours (if possible). $( fake_onhashchange.stop ); } }); // fake_onhashchange does all the work of triggering the window.onhashchange // event for browsers that don't natively support it, including creating a // polling loop to watch for hash changes. fake_onhashchange = (function() { var self = {}, timeout_id, // Remember the initial hash so it doesn't get triggered immediately. last_hash = get_fragment(), fn_retval = function( val ) { return val; }, history_set = fn_retval, history_get = fn_retval; // Start the polling loop. self.start = function() { timeout_id || poll(); }; // Stop the polling loop. self.stop = function() { timeout_id && clearTimeout( timeout_id ); timeout_id = undefined; }; // This polling loop checks every $.fn.hashchange.delay milliseconds to see // if location.hash has changed, and triggers the 'hashchange' event on // window when necessary. function poll() { var hash = get_fragment(), history_hash = history_get( last_hash ); if ( hash !== last_hash ) { history_set( last_hash = hash, history_hash ); $(window).trigger( str_hashchange ); } else if ( history_hash !== last_hash ) { location.href = location.href.replace( /#.*/, '' ) + history_hash; } timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); }; // MODIFIED BY SAP - IE 6/7/8compat support was removed. return self; })(); })(jQuery,this); (function( $ ) { $.mobile = {}; // MODIFIED BY SAP // To enable using the native orientation change event instead of faking the event by jQuery mobile jQuery.mobile.orientationChangeEnabled = true; }( jQuery )); (function( $, window, undefined ) { var nsNormalizeDict = {}; // jQuery.mobile configurable options $.mobile = $.extend($.mobile, { // Version of the jQuery Mobile Framework version: "1.3.1", // Namespace used framework-wide for data-attrs. Default is no namespace ns: "", // Define the url parameter used for referencing widget-generated sub-pages. // Translates to to example.html&ui-page=subpageIdentifier // hash segment before &ui-page= is used to make Ajax request subPageUrlKey: "ui-page", // Class assigned to page currently in view, and during transitions activePageClass: "ui-page-active", // Class used for "active" button state, from CSS framework activeBtnClass: "ui-btn-active", // Class used for "focus" form element state, from CSS framework focusClass: "ui-focus", // Automatically handle clicks and form submissions through Ajax, when same-domain ajaxEnabled: true, // Automatically load and show pages based on location.hash hashListeningEnabled: true, // disable to prevent jquery from bothering with links linkBindingEnabled: true, // Set default page transition - 'none' for no transitions defaultPageTransition: "fade", // Set maximum window width for transitions to apply - 'false' for no limit maxTransitionWidth: false, // Minimum scroll distance that will be remembered when returning to a page minScrollBack: 250, // DEPRECATED: the following property is no longer in use, but defined until 2.0 to prevent conflicts touchOverflowEnabled: false, // Set default dialog transition - 'none' for no transitions defaultDialogTransition: "pop", // Error response message - appears when an Ajax page request fails pageLoadErrorMessage: "Error Loading Page", // For error messages, which theme does the box uses? pageLoadErrorMessageTheme: "e", // replace calls to window.history.back with phonegaps navigation helper // where it is provided on the window object phonegapNavigationEnabled: false, //automatically initialize the DOM when it's ready autoInitializePage: true, pushStateEnabled: true, // allows users to opt in to ignoring content by marking a parent element as // data-ignored ignoreContentEnabled: false, // turn of binding to the native orientationchange due to android orientation behavior orientationChangeEnabled: true, buttonMarkup: { hoverDelay: 200 }, // define the window and the document objects window: $( window ), document: $( document ), // TODO might be useful upstream in jquery itself ? keyCode: { ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, // COMMAND COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, // COMMAND_RIGHT NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108, NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91 // COMMAND }, // Place to store various widget extensions behaviors: {}, // Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value silentScroll: function( ypos ) { // MODIFIED BY SAP: replace deprecated API if ( typeof ypos !== "number" ) { ypos = $.mobile.defaultHomeScroll; } // prevent scrollstart and scrollstop events $.event.special.scrollstart.enabled = false; setTimeout( function() { window.scrollTo( 0, ypos ); $.mobile.document.trigger( "silentscroll", { x: 0, y: ypos }); }, 20 ); setTimeout( function() { $.event.special.scrollstart.enabled = true; }, 150 ); }, // Expose our cache for testing purposes. nsNormalizeDict: nsNormalizeDict, // Take a data attribute property, prepend the namespace // and then camel case the attribute string. Add the result // to our nsNormalizeDict so we don't have to do this again. nsNormalize: function( prop ) { if ( !prop ) { return; } return nsNormalizeDict[ prop ] || ( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) ); }, // Find the closest parent with a theme class on it. Note that // we are not using $.fn.closest() on purpose here because this // method gets called quite a bit and we need it to be as fast // as possible. getInheritedTheme: function( el, defaultTheme ) { var e = el[ 0 ], ltr = "", re = /ui-(bar|body|overlay)-([a-z])\b/, c, m; while ( e ) { c = e.className || ""; if ( c && ( m = re.exec( c ) ) && ( ltr = m[ 2 ] ) ) { // We found a parent with a theme class // on it so bail from this loop. break; } e = e.parentNode; } // Return the theme letter we found, if none, return the // specified default. return ltr || defaultTheme || "a"; }, // TODO the following $ and $.fn extensions can/probably should be moved into jquery.mobile.core.helpers // // Find the closest javascript page element to gather settings data jsperf test // http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit // possibly naive, but it shows that the parsing overhead for *just* the page selector vs // the page and dialog selector is negligable. This could probably be speed up by // doing a similar parent node traversal to the one found in the inherited theme code above closestPageData: function( $target ) { return $target .closest( ':jqmData(role="page"), :jqmData(role="dialog")' ) .data( "mobile-page" ); }, enhanceable: function( $set ) { return this.haveParents( $set, "enhance" ); }, hijackable: function( $set ) { return this.haveParents( $set, "ajax" ); }, haveParents: function( $set, attr ) { if ( !$.mobile.ignoreContentEnabled ) { return $set; } var count = $set.length, $newSet = $(), e, $element, excluded; for ( var i = 0; i < count; i++ ) { $element = $set.eq( i ); excluded = false; e = $set[ i ]; while ( e ) { var c = e.getAttribute ? e.getAttribute( "data-" + $.mobile.ns + attr ) : ""; if ( c === "false" ) { excluded = true; break; } e = e.parentNode; } if ( !excluded ) { $newSet = $newSet.add( $element ); } } return $newSet; }, getScreenHeight: function() { // Native innerHeight returns more accurate value for this across platforms, // jQuery version is here as a normalized fallback for platforms like Symbian return window.innerHeight || $.mobile.window.height(); } }, $.mobile ); // Mobile version of data and removeData and hasData methods // ensures all data is set and retrieved using jQuery Mobile's data namespace $.fn.jqmData = function( prop, value ) { var result; if ( typeof prop !== "undefined" ) { if ( prop ) { prop = $.mobile.nsNormalize( prop ); } // undefined is permitted as an explicit input for the second param // in this case it returns the value and does not set it to undefined if( arguments.length < 2 || value === undefined ){ result = this.data( prop ); } else { result = this.data( prop, value ); } } return result; }; $.jqmData = function( elem, prop, value ) { var result; if ( typeof prop !== "undefined" ) { result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value ); } return result; }; $.fn.jqmRemoveData = function( prop ) { return this.removeData( $.mobile.nsNormalize( prop ) ); }; $.jqmRemoveData = function( elem, prop ) { return $.removeData( elem, $.mobile.nsNormalize( prop ) ); }; $.fn.removeWithDependents = function() { $.removeWithDependents( this ); }; $.removeWithDependents = function( elem ) { var $elem = $( elem ); ( $elem.jqmData( 'dependents' ) || $() ).remove(); $elem.remove(); }; $.fn.addDependents = function( newDependents ) { $.addDependents( $( this ), newDependents ); }; $.addDependents = function( elem, newDependents ) { var dependents = $( elem ).jqmData( 'dependents' ) || $(); $( elem ).jqmData( 'dependents', $.merge( dependents, newDependents ) ); }; // note that this helper doesn't attempt to handle the callback // or setting of an html element's text, its only purpose is // to return the html encoded version of the text in all cases. (thus the name) $.fn.getEncodedText = function() { return $( "<div/>" ).text( $( this ).text() ).html(); }; // fluent helper function for the mobile namespaced equivalent $.fn.jqmEnhanceable = function() { return $.mobile.enhanceable( this ); }; $.fn.jqmHijackable = function() { return $.mobile.hijackable( this ); }; // Monkey-patching Sizzle to filter the :jqmData selector var oldFind = $.find, jqmDataRE = /:jqmData\(([^)]*)\)/g; $.find = function( selector, context, ret, extra ) { selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" ); return oldFind.call( this, selector, context, ret, extra ); }; $.extend( $.find, oldFind ); // MODIFIED BY SAP: the following two functions "$.find.matches" and "$.find.matchesSelector" are commented out // because they are not compatible with the existing version before overwritten when a focused DIV element is // checked by using jQuery(oneDIVElement).is(":focus"). it returns false instead of true. We use the check in // sap.ui.core.FocusHandler to store the previous focused control before it gets rerendered. Therefore they are // commented out in order to make the restoring of focus after rerendering still work. // // $.find.matches = function( expr, set ) { // return $.find( expr, null, null, set ); // }; // // $.find.matchesSelector = function( node, expr ) { // return $.find( expr, null, null, [ node ] ).length > 0; // }; })( jQuery, this ); (function( $, undefined ) { /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ window.matchMedia = window.matchMedia || (function( doc, undefined ) { var bool, docElem = doc.documentElement, refNode = docElem.firstElementChild || docElem.firstChild, // fakeBody required for <FF4 when executed in <head> fakeBody = doc.createElement( "body" ), div = doc.createElement( "div" ); div.id = "mq-test-1"; div.style.cssText = "position:absolute;top:-100em"; fakeBody.style.background = "none"; fakeBody.appendChild(div); return function(q){ div.innerHTML = "&shy;<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>"; docElem.insertBefore( fakeBody, refNode ); bool = div.offsetWidth === 42; docElem.removeChild( fakeBody ); return { matches: bool, media: q }; }; }( document )); // $.mobile.media uses matchMedia to return a boolean. $.mobile.media = function( q ) { return window.matchMedia( q ).matches; }; })(jQuery); (function( $, undefined ) { var support = { touch: "ontouchend" in document }; // MODIFIED BY SAP // => if the device API is loaded we override the touch detection // MS Internet Explorer and MS Edge do not fire 'touchstart' and 'touchend' events // Therefore $.mobile.support should not be overriden with the actual device screen capability if (window.sap && sap.ui && sap.ui.Device && sap.ui.Device.support && !(sap.ui.Device.browser.msie || sap.ui.Device.browser.edge)) { support.touch = sap.ui.Device.support.touch } $.mobile.support = $.mobile.support || {}; $.extend( $.support, support ); $.extend( $.mobile.support, support ); }( jQuery )); (function( $, undefined ) { $.extend( $.support, { orientation: "orientation" in window && "onorientationchange" in window }); }( jQuery )); (function( $, undefined ) { // thx Modernizr function propExists( prop ) { var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ), props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " ); for ( var v in props ) { if ( fbCSS[ props[ v ] ] !== undefined ) { return true; } } } var fakeBody = $( "<body>" ).prependTo( "html" ), fbCSS = fakeBody[ 0 ].style, vendors = [ "Webkit", "Moz", "O" ], webos = "palmGetResource" in window, //only used to rule out scrollTop opera = window.opera, operamini = window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]", bb = window.blackberry && !propExists( "-webkit-transform" ); //only used to rule out box shadow, as it's filled opaque on BB 5 and lower function validStyle( prop, value, check_vend ) { var div = document.createElement( 'div' ), uc = function( txt ) { return txt.charAt( 0 ).toUpperCase() + txt.substr( 1 ); }, vend_pref = function( vend ) { if( vend === "" ) { return ""; } else { return "-" + vend.charAt( 0 ).toLowerCase() + vend.substr( 1 ) + "-"; } }, check_style = function( vend ) { var vend_prop = vend_pref( vend ) + prop + ": " + value + ";", uc_vend = uc( vend ), propStyle = uc_vend + ( uc_vend === "" ? prop : uc( prop ) ); // ##### BEGIN: MODIFIED BY SAP // CSP Modification - remove inline style // div.setAttribute( "style", vend_prop ); div.style = vend_prop; // ##### END: MODIFIED BY SAP if ( !!div.style[ propStyle ] ) { ret = true; } }, check_vends = check_vend ? check_vend : vendors, ret; for( var i = 0; i < check_vends.length; i++ ) { check_style( check_vends[i] ); } return !!ret; } function transform3dTest() { var mqProp = "transform-3d", // Because the `translate3d` test below throws false positives in Android: ret = $.mobile.media( "(-" + vendors.join( "-" + mqProp + "),(-" ) + "-" + mqProp + "),(" + mqProp + ")" ); if( ret ) { return !!ret; } var el = document.createElement( "div" ), transforms = { // We’re omitting Opera for the time being; MS uses unprefixed. 'MozTransform':'-moz-transform', 'transform':'transform' }; fakeBody.append( el ); for ( var t in transforms ) { if( el.style[ t ] !== undefined ){ el.style[ t ] = 'translate3d( 100px, 1px, 1px )'; ret = window.getComputedStyle( el ).getPropertyValue( transforms[ t ] ); } } return ( !!ret && ret !== "none" ); } // ##### MODIFIED BY SAP - Removed base tag support check function, because this function leads to CSP violations in some browsers. // Thanks Modernizr function cssPointerEventsTest() { var element = document.createElement( 'x' ), documentElement = document.documentElement, getComputedStyle = window.getComputedStyle, // ##### BEGIN: MODIFIED BY SAP computed = getComputedStyle && getComputedStyle(element, ''), // ##### END: MODIFIED BY SAP supports; if ( !( 'pointerEvents' in element.style ) ) { return false; } element.style.pointerEvents = 'auto'; element.style.pointerEvents = 'x'; documentElement.appendChild( element ); // ##### BEGIN: MODIFIED BY SAP //supports = getComputedStyle && //getComputedStyle( element, '' ).pointerEvents === 'auto'; supports = computed && computed.pointerEvents === 'auto'; // ##### END: MODIFIED BY SAP documentElement.removeChild( element ); return !!supports; } function boundingRect() { var div = document.createElement( "div" ); return typeof div.getBoundingClientRect !== "undefined"; } // non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683 // allows for inclusion of IE 6+, including Windows Mobile 7 $.extend( $.mobile, { browser: {} } ); $.mobile.browser.oldIE = (function() { var v = 3, div = document.createElement( "div" ), a = div.all || []; do { div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->"; } while( a[0] ); return v > 4 ? v : !v; })(); function fixedPosition() { var w = window, ua = navigator.userAgent, platform = navigator.platform, // Rendering engine is Webkit, and capture major version wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ ), wkversion = !!wkmatch && wkmatch[ 1 ], ffmatch = ua.match( /Fennec\/([0-9]+)/ ), ffversion = !!ffmatch && ffmatch[ 1 ], operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ ), omversion = !!operammobilematch && operammobilematch[ 1 ]; if( // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5) ( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1 || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 ) || // Opera Mini ( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" ) || ( operammobilematch && omversion < 7458 ) || //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2) ( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 ) || // Firefox Mobile before 6.0 - ( ffversion && ffversion < 6 ) || // WebOS less than 3 ( "palmGetResource" in window && wkversion && wkversion < 534 ) || // MeeGo ( ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1 ) ) { return false; } return true; } $.extend( $.support, { cssTransitions: "WebKitTransitionEvent" in window || validStyle( 'transition', 'height 100ms linear', [ "Webkit", "Moz", "" ] ) && !$.mobile.browser.oldIE && !opera, // Note, Chrome for iOS has an extremely quirky implementation of popstate. // We've chosen to take the shortest path to a bug fix here for issue #5426 // See the following link for information about the regex chosen // https://developers.google.com/chrome/mobile/docs/user-agent#chrome_for_ios_user-agent pushState: "pushState" in history && "replaceState" in history && // When running inside a FF iframe, calling replaceState causes an error !( window.navigator.userAgent.indexOf( "Firefox" ) >= 0 && window.top !== window ) && ( window.navigator.userAgent.search(/CriOS/) === -1 ), mediaquery: $.mobile.media( "only all" ), cssPseudoElement: !!propExists( "content" ), touchOverflow: !!propExists( "overflowScrolling" ), cssTransform3d: transform3dTest(), boxShadow: !!propExists( "boxShadow" ) && !bb, fixedPosition: fixedPosition(), scrollTop: ("pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ]) && !webos && !operamini, dynamicBaseTag: true, // ##### MODIFIED BY SAP - Removed base tag support check function, because this function leads to CSP violations in some browsers. cssPointerEvents: cssPointerEventsTest(), boundingRect: boundingRect() }); fakeBody.remove(); // $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian) // or that generally work better browsing in regular http for full page refreshes (Opera Mini) // Note: This detection below is used as a last resort. // We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible var nokiaLTE7_3 = (function() { var ua = window.navigator.userAgent; //The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older return ua.indexOf( "Nokia" ) > -1 && ( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) && ua.indexOf( "AppleWebKit" ) > -1 && ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ ); })(); // Support conditions that must be met in order to proceed // default enhanced qualifications are media query support OR IE 7+ $.mobile.gradeA = function() { return ( $.support.mediaquery || $.mobile.browser.oldIE && $.mobile.browser.oldIE >= 7 ) && ( $.support.boundingRect || $.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/) !== null ); }; $.mobile.ajaxBlacklist = // BlackBerry browsers, pre-webkit window.blackberry && !window.WebKitPoint || // Opera Mini operamini || // Symbian webkits pre 7.3 nokiaLTE7_3; // Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices // to render the stylesheets when they're referenced before this script, as we'd recommend doing. // This simply reappends the CSS in place, which for some reason makes it apply if ( nokiaLTE7_3 ) { $(function() { $( "head link[rel='stylesheet']" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" ); }); } // For ruling out shadows via css if ( !$.support.boxShadow ) { $( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); } })( jQuery ); (function( $, undefined ) { var $win = $.mobile.window, self, history; $.event.special.navigate = self = { bound: false, pushStateEnabled: true, originalEventName: undefined, // If pushstate support is present and push state support is defined to // be true on the mobile namespace. isPushStateEnabled: function() { return $.support.pushState && $.mobile.pushStateEnabled === true && this.isHashChangeEnabled(); }, // !! assumes mobile namespace is present isHashChangeEnabled: function() { return $.mobile.hashListeningEnabled === true; }, // TODO a lot of duplication between popstate and hashchange popstate: function( event ) { var newEvent = new $.Event( "navigate" ), beforeNavigate = new $.Event( "beforenavigate" ), state = event.originalEvent.state || {}, href = location.href; $win.trigger( beforeNavigate ); if( beforeNavigate.isDefaultPrevented() ){ return; } if( event.historyState ){ $.extend(state, event.historyState); } // Make sure the original event is tracked for the end // user to inspect incase they want to do something special newEvent.originalEvent = event; // NOTE we let the current stack unwind because any assignment to // location.hash will stop the world and run this event handler. By // doing this we create a similar behavior to hashchange on hash // assignment setTimeout(function() { $win.trigger( newEvent, { state: state }); }, 0); }, hashchange: function( event, data ) { var newEvent = new $.Event( "navigate" ), beforeNavigate = new $.Event( "beforenavigate" ); $win.trigger( beforeNavigate ); if( beforeNavigate.isDefaultPrevented() ){ return; } // Make sure the original event is tracked for the end // user to inspect incase they want to do something special newEvent.originalEvent = event; // Trigger the hashchange with state provided by the user // that altered the hash $win.trigger( newEvent, { // Users that want to fully normalize the two events // will need to do history management down the stack and // add the state to the event before this binding is fired // TODO consider allowing for the explicit addition of callbacks // to be fired before this value is set to avoid event timing issues state: event.hashchangeState || {} }); }, // TODO We really only want to set this up once // but I'm not clear if there's a beter way to achieve // this with the jQuery special event structure setup: function( data, namespaces ) { if( self.bound ) { return; } self.bound = true; if( self.isPushStateEnabled() ) { self.originalEventName = "popstate"; // MODIFIED BY SAP: replace deprecated API .bind -> .on $win.on( "popstate.navigate", self.popstate ); } else if ( self.isHashChangeEnabled() ){ self.originalEventName = "hashchange"; // MODIFIED BY SAP: replace deprecated API .bind -> .on $win.on( "hashchange.navigate", self.hashchange ); } } }; })( jQuery ); // throttled resize event (function( $ ) { $.event.special.throttledresize = { setup: function() { // MODIFIED BY SAP: replace deprecated API .bind -> .on $( this ).on( "resize", handler ); }, teardown: function() { // MODIFIED BY SAP: replace deprecated API .unbind -> .off $( this ).off( "resize", handler ); } }; var throttle = 250, handler = function() { curr = ( new Date() ).getTime(); diff = curr - lastCall; if ( diff >= throttle ) { lastCall = curr; $( this ).trigger( "throttledresize" ); } else { if ( heldCall ) { clearTimeout( heldCall ); } // Promise a held call will still execute heldCall = setTimeout( handler, throttle - diff ); } }, lastCall = 0, heldCall, curr, diff; })( jQuery ); (function( $, window ) { var win = $( window ), event_name = "orientationchange", special_event, get_orientation, last_orientation, initial_orientation_is_landscape, initial_orientation_is_default, portrait_map = { "0": true, "180": true }; // It seems that some device/browser vendors use window.orientation values 0 and 180 to // denote the "default" orientation. For iOS devices, and most other smart-phones tested, // the default orientation is always "portrait", but in some Android and RIM based tablets, // the default orientation is "landscape". The following code attempts to use the window // dimensions to figure out what the current orientation is, and then makes adjustments // to the to the portrait_map if necessary, so that we can properly decode the // window.orientation value whenever get_orientation() is called. // // Note that we used to use a media query to figure out what the orientation the browser // thinks it is in: // // initial_orientation_is_landscape = $.mobile.media("all and (orientation: landscape)"); // // but there was an iPhone/iPod Touch bug beginning with iOS 4.2, up through iOS 5.1, // where the browser *ALWAYS* applied the landscape media query. This bug does not // happen on iPad. if ( $.support.orientation ) { // Check the window width and height to figure out what the current orientation // of the device is at this moment. Note that we've initialized the portrait map // values to 0 and 180, *AND* we purposely check for landscape so that if we guess // wrong, , we default to the assumption that portrait is the default orientation. // We use a threshold check below because on some platforms like iOS, the iPhone // form-factor can report a larger width than height if the user turns on the // developer console. The actual threshold value is somewhat arbitrary, we just // need to make sure it is large enough to exclude the developer console case. var ww = window.innerWidth || win.width(), wh = window.innerHeight || win.height(), landscape_threshold = 50; initial_orientation_is_landscape = ww > wh && ( ww - wh ) > landscape_threshold; // Now check to see if the current window.orientation is 0 or 180. initial_orientation_is_default = portrait_map[ window.orientation ]; // If the initial orientation is landscape, but window.orientation reports 0 or 180, *OR* // if the initial orientation is portrait, but window.orientation reports 90 or -90, we // need to flip our portrait_map values because landscape is the default orientation for // this device/browser. if ( ( initial_orientation_is_landscape && initial_orientation_is_default ) || ( !initial_orientation_is_landscape && !initial_orientation_is_default ) ) { portrait_map = { "-90": true, "90": true }; } } $.event.special.orientationchange = $.extend( {}, $.event.special.orientationchange, { setup: function() { // If the event is supported natively, return false so that jQuery // will bind to the event using DOM methods. if ( $.support.orientation && !$.event.special.orientationchange.disabled ) { return false; } // Get the current orientation to avoid initial double-triggering. last_orientation = get_orientation(); // Because the orientationchange event doesn't exist, simulate the // event by testing window dimensions on resize. // MODIFIED BY SAP: replace deprecated API .bind -> .on win.on( "throttledresize", handler ); }, teardown: function() { // If the event is not supported natively, return false so that // jQuery will unbind the event using DOM methods. if ( $.support.orientation && !$.event.special.orientationchange.disabled ) { return false; } // Because the orientationchange event doesn't exist, unbind the // resize event handler. // MODIFIED BY SAP: replace deprecated API .unbind -> .off win.off( "throttledresize", handler ); }, add: function( handleObj ) { // Save a reference to the bound event handler. var old_handler = handleObj.handler; handleObj.handler = function( event ) { // Modify event object, adding the .orientation property. event.orientation = get_orientation(); // Call the originally-bound event handler and return its result. return old_handler.apply( this, arguments ); }; } }); // If the event is not supported natively, this handler will be bound to // the window resize event to simulate the orientationchange event. function handler() { // Get the current orientation. var orientation = get_orientation(); if ( orientation !== last_orientation ) { // The orientation has changed, so trigger the orientationchange event. last_orientation = orientation; win.trigger( event_name ); } } // Get the current page orientation. This method is exposed publicly, should it // be needed, as jQuery.event.special.orientationchange.orientation() $.event.special.orientationchange.orientation = get_orientation = function() { var isPortrait = true, elem = document.documentElement; // prefer window orientation to the calculation based on screensize as // the actual screen resize takes place before or after the orientation change event // has been fired depending on implementation (eg android 2.3 is before, iphone after). // More testing is required to determine if a more reliable method of determining the new screensize // is possible when orientationchange is fired. (eg, use media queries + element + opacity) if ( $.support.orientation ) { // if the window orientation registers as 0 or 180 degrees report // portrait, otherwise landscape isPortrait = portrait_map[ window.orientation ]; } else { isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1; } return isPortrait ? "portrait" : "landscape"; }; $.fn[ event_name ] = function( fn ) { // MODIFIED BY SAP: replace deprecated API .bind -> .on return fn ? this.on( event_name, fn ) : this.trigger( event_name ); }; // jQuery < 1.8 if ( $.attrFn ) { $.attrFn[ event_name ] = true; } }( jQuery, this )); // This plugin is an experiment for abstracting away the touch and mouse // events so that developers don't have to worry about which method of input // the device their document is loaded on supports. // // The idea here is to allow the developer to register listeners for the // basic mouse events, such as mousedown, mousemove, mouseup, and click, // and the plugin will take care of registering the correct listeners // behind the scenes to invoke the listener at the fastest possible time // for that device, while still retaining the order of event firing in // the traditional mouse environment, should multiple handlers be registered // on the same element for different events. // // The current version exposes the following virtual events to jQuery bind methods: // "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" (function( $, window, document, undefined ) { var dataPropertyName = "virtualMouseBindings", touchTargetPropertyName = "virtualTouchID", virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], // ##### BEGIN: MODIFIED BY SAP // Replace the usage of $.event.props because it's removed since jQuery version 3.x.x // Code is partically taken from jquery.mobile/js/vmouse.js version 1.4.5 generalProps = ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ), mouseEventProps = generalProps.concat( mouseHookProps ), // ##### END: MODIFIED BY SAP activeDocHandlers = {}, resetTimerID = 0, startX = 0, startY = 0, didScroll = false, clickBlockList = [], blockMouseTriggers = false, blockTouchTriggers = false, eventCaptureSupported = "addEventListener" in document, $document = $( document ), nextTouchID = 1, lastTouchID = 0, threshold; $.vmouse = { moveDistanceThreshold: 10, clickDistanceThreshold: 10, resetTimerDuration: 1500 }; function getNativeEvent( event ) { while ( event && typeof event.originalEvent !== "undefined" ) { event = event.originalEvent; } return event; } function createVirtualEvent( event, eventType ) { var t = event.type, oe, props, ne, prop, ct, touch, i, j, len; event = $.Event( event ); event.type = eventType; oe = event.originalEvent; // ##### BEGIN: MODIFIED BY SAP // Replace the usage of $.event.props because it's removed since jQuery version 3.x.x // Code is partically taken from jquery.mobile/js/vmouse.js version 1.4.5 props = generalProps; // ##### END: MODIFIED BY SAP // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 // https://github.com/jquery/jquery-mobile/issues/3280 if ( t.search( /^(mouse|click)/ ) > -1 ) { props = mouseEventProps; } // copy original event properties over to the new event // this would happen if we could call $.event.fix instead of $.Event // but we don't have a way to force an event to be fixed multiple times if ( oe ) { for ( i = props.length, prop; i; ) { prop = props[ --i ]; event[ prop ] = oe[ prop ]; } } // make sure that if the mouse and click virtual events are generated // without a .which one is defined if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) { event.which = 1; } if ( t.search(/^touch/) !== -1 ) { ne = getNativeEvent( oe ); t = ne.touches; ct = ne.changedTouches; touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined ); if ( touch ) { for ( j = 0, len = touchEventProps.length; j < len; j++) { prop = touchEventProps[ j ]; event[ prop ] = touch[ prop ]; } } } return event; } function getVirtualBindingFlags( element ) { var flags = {}, b, k; while ( element ) { b = $.data( element, dataPropertyName ); for ( k in b ) { if ( b[ k ] ) { flags[ k ] = flags.hasVirtualBinding = true; } } element = element.parentNode; } return flags; } function getClosestElementWithVirtualBinding( element, eventType ) { var b; while ( element ) { b = $.data( element, dataPropertyName ); if ( b && ( !eventType || b[ eventType ] ) ) { return element; } element = element.parentNode; } return null; } function enableTouchBindings() { blockTouchTriggers = false; } function disableTouchBindings() { blockTouchTriggers = true; } function enableMouseBindings() { lastTouchID = 0; clickBlockList.length = 0; blockMouseTriggers = false; // When mouse bindings are enabled, our // touch bindings are disabled. disableTouchBindings(); } function disableMouseBindings() { // When mouse bindings are disabled, our // touch bindings are enabled. enableTouchBindings(); } function startResetTimer() { clearResetTimer(); resetTimerID = setTimeout( function() { resetTimerID = 0; enableMouseBindings(); }, $.vmouse.resetTimerDuration ); } function clearResetTimer() { if ( resetTimerID ) { clearTimeout( resetTimerID ); resetTimerID = 0; } } function triggerVirtualEvent( eventType, event, flags ) { var ve; if ( ( flags && flags[ eventType ] ) || ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { ve = createVirtualEvent( event, eventType ); $( event.target).trigger( ve ); } return ve; } function mouseEventCallback( event ) { var touchID = $.data( event.target, touchTargetPropertyName ); if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){ var ve = triggerVirtualEvent( "v" + event.type, event ); if ( ve ) { if ( ve.isDefaultPrevented() ) { event.preventDefault(); } if ( ve.isPropagationStopped() ) { event.stopPropagation(); } if ( ve.isImmediatePropagationStopped() ) { event.stopImmediatePropagation(); } } } } function handleTouchStart( event ) { var touches = getNativeEvent( event ).touches, target, flags; if ( touches && touches.length === 1 ) { target = event.target; flags = getVirtualBindingFlags( target ); if ( flags.hasVirtualBinding ) { lastTouchID = nextTouchID++; $.data( target, touchTargetPropertyName, lastTouchID ); clearResetTimer(); disableMouseBindings(); didScroll = false; var t = getNativeEvent( event ).touches[ 0 ]; startX = t.pageX; startY = t.pageY; triggerVirtualEvent( "vmouseover", event, flags ); triggerVirtualEvent( "vmousedown", event, flags ); } } } function handleScroll( event ) { if ( blockTouchTriggers ) { return; } if ( !didScroll ) { trigg