###** Browser support =============== Unpoly supports all modern browsers. Chrome, Firefox, Edge, Safari : Full support Internet Explorer 11 : Full support with a `Promise` polyfill like [es6-promise](https://github.com/stefanpenner/es6-promise) (2.4 KB). Internet Explorer 10 or lower : Unpoly prevents itself from booting itself, leaving you with a classic server-side application. @module up.browser ### up.browser = do -> u = up.util ###** @method up.browser.navigate @param {string} url @param {string} [options.method='get'] @param {object|Array|FormData|string} [options.params] @internal ### navigate = (url, options) -> requestOpts = u.merge(options, { url }) request = new up.Request(requestOpts) request.navigate() ###** For mocking in specs. @method submitForm ### submitForm = (form) -> form.submit() url = -> location.href isIE10OrWorse = u.memoize -> !window.atob isIE11 = u.memoize -> 'ActiveXObject' of window # this is undefined, but the key is set ###** Returns whether this browser supports manipulation of the current URL via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState). When `pushState` (e.g. through [`up.follow()`](/up.follow)), it will gracefully fall back to a full page load. Note that Unpoly will not use `pushState` if the initial page was loaded with a request method other than GET. @function up.browser.canPushState @return {boolean} @experimental ### canPushState = -> # We cannot use pushState if the initial request method is a POST for two reasons: # # 1. Unpoly replaces the initial state so it can handle the pop event when the # user goes back to the initial URL later. If the initial request was a POST, # Unpoly will wrongly assumed that it can restore the state by reloading with GET. # # 2. Some browsers have a bug where the initial request method is used for all # subsequently pushed states. That means if the user reloads the page on a later # GET state, the browser will wrongly attempt a POST request. # This issue affects Safari 9 and 10 (last tested in 2017-08). # Modern Firefoxes, Chromes and IE10+ don't have this behavior. # # The way that we work around this is that we don't support pushState if the # initial request method was anything other than GET (but allow the rest of the # Unpoly framework to work). This way Unpoly will fall back to full page loads until # the framework was booted from a GET request. u.isDefined(history.pushState) && up.protocol.initialRequestMethod() == 'get' ###** Returns whether this browser supports animation using [CSS transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions). When Unpoly is asked to animate history on a browser that doesn't support CSS transitions (e.g. through [`up.animate()`](/up.animate)), it will skip the animation by instantly jumping to the last frame. @function up.browser.canCssTransition @return {boolean} @internal ### canCssTransition = u.memoize -> 'transition' of document.documentElement.style ###** Returns whether this browser supports the DOM event [`input`](https://developer.mozilla.org/de/docs/Web/Events/input). @function up.browser.canInputEvent @return {boolean} @internal ### canInputEvent = u.memoize -> 'oninput' of document.createElement('input') ###** Returns whether this browser supports promises. @function up.browser.canPromise @return {boolean} @internal ### canPromise = u.memoize -> !!window.Promise ###** Returns whether this browser supports the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) interface. @function up.browser.canFormData @return {boolean} @experimental ### canFormData = u.memoize -> !!window.FormData ###** @function up.browser.canInspectFormData @return {boolean} @internal ### canInspectFormData = u.memoize -> canFormData() && !!FormData.prototype.entries ###** Returns whether this browser supports the [`DOMParser`](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser) interface. @function up.browser.canDOMParser @return {boolean} @internal ### canDOMParser = u.memoize -> !!window.DOMParser ###** Returns whether this browser supports the [`debugging console`](https://developer.mozilla.org/en-US/docs/Web/API/Console). @function up.browser.canConsole @return {boolean} @internal ### canConsole = u.memoize -> window.console && console.debug && console.info && console.warn && console.error && console.group && console.groupCollapsed && console.groupEnd canCustomElements = u.memoize -> !!window.customElements canAnimationFrame = u.memoize -> 'requestAnimationFrame' of window canControlScrollRestoration = u.memoize -> 'scrollRestoration' of history # Don't memoize so a build may publish window.jQuery after Unpoly was loaded canJQuery = -> !!window.jQuery popCookie = (name) -> value = document.cookie.match(new RegExp(name+"=(\\w+)"))?[1] if u.isPresent(value) document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/' value ###** @function up,browser.whenConfirmed @return {Promise} @param {string} options.confirm @param {boolean} options.preload @internal ### whenConfirmed = (options) -> if options.preload || u.isBlank(options.confirm) || window.confirm(options.confirm) Promise.resolve() else Promise.reject(new Error('User canceled action')) ###** Returns whether Unpoly supports the current browser. If this returns `false` Unpoly will prevent itself from [booting](/up.boot) and ignores all registered [event handlers](/up.on) and [compilers](/up.compiler). This leaves you with a classic server-side application. This is usually a better fallback than loading incompatible Javascript and causing many errors on load. @function up.browser.isSupported @stable ### isSupported = -> !isIE10OrWorse() && canConsole() && # We don't require pushState in order to cater for Safari booting Unpoly with a non-GET method. # canPushState() && canDOMParser() && canFormData() && canCssTransition() && canInputEvent() && canPromise() && canAnimationFrame() callJQuery = (args...) -> canJQuery() or up.fail("jQuery must be published as window.jQuery") return jQuery(args...) <% if ENV['JS_KNIFE'] %>knife: eval(Knife.point)<% end %> url: url navigate: navigate submitForm: submitForm canPushState: canPushState canFormData: canFormData canInspectFormData: canInspectFormData canCustomElements: canCustomElements canControlScrollRestoration: canControlScrollRestoration canJQuery: canJQuery whenConfirmed: whenConfirmed isSupported: isSupported popCookie: popCookie jQuery: callJQuery isIE11: isIE11