UNPKG

6.75 kBJavaScriptView Raw
1import * as Util from './Util';
2import {svgCreate} from '../layer/vector/SVG.Util';
3
4/*
5 * @namespace Browser
6 * @aka L.Browser
7 *
8 * A namespace with static properties for browser/feature detection used by Leaflet internally.
9 *
10 * @example
11 *
12 * ```js
13 * if (L.Browser.ielt9) {
14 * alert('Upgrade your browser, dude!');
15 * }
16 * ```
17 */
18
19var style = document.documentElement.style;
20
21// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).
22export var ie = 'ActiveXObject' in window;
23
24// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.
25export var ielt9 = ie && !document.addEventListener;
26
27// @property edge: Boolean; `true` for the Edge web browser.
28export var edge = 'msLaunchUri' in navigator && !('documentMode' in document);
29
30// @property webkit: Boolean;
31// `true` for webkit-based browsers like Chrome and Safari (including mobile versions).
32export var webkit = userAgentContains('webkit');
33
34// @property android: Boolean
35// `true` for any browser running on an Android platform.
36export var android = userAgentContains('android');
37
38// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.
39export var android23 = userAgentContains('android 2') || userAgentContains('android 3');
40
41/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */
42var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit
43// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)
44export var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);
45
46// @property opera: Boolean; `true` for the Opera browser
47export var opera = !!window.opera;
48
49// @property chrome: Boolean; `true` for the Chrome browser.
50export var chrome = userAgentContains('chrome');
51
52// @property gecko: Boolean; `true` for gecko-based browsers like Firefox.
53export var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;
54
55// @property safari: Boolean; `true` for the Safari browser.
56export var safari = !chrome && userAgentContains('safari');
57
58export var phantom = userAgentContains('phantom');
59
60// @property opera12: Boolean
61// `true` for the Opera browser supporting CSS transforms (version 12 or later).
62export var opera12 = 'OTransition' in style;
63
64// @property win: Boolean; `true` when the browser is running in a Windows platform
65export var win = navigator.platform.indexOf('Win') === 0;
66
67// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.
68export var ie3d = ie && ('transition' in style);
69
70// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.
71export var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;
72
73// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.
74export var gecko3d = 'MozPerspective' in style;
75
76// @property any3d: Boolean
77// `true` for all browsers supporting CSS transforms.
78export var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;
79
80// @property mobile: Boolean; `true` for all browsers running in a mobile device.
81export var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');
82
83// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.
84export var mobileWebkit = mobile && webkit;
85
86// @property mobileWebkit3d: Boolean
87// `true` for all webkit-based browsers in a mobile device supporting CSS transforms.
88export var mobileWebkit3d = mobile && webkit3d;
89
90// @property msPointer: Boolean
91// `true` for browsers implementing the Microsoft touch events model (notably IE10).
92export var msPointer = !window.PointerEvent && window.MSPointerEvent;
93
94// @property pointer: Boolean
95// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).
96export var pointer = !webkit && !!(window.PointerEvent || msPointer);
97
98// @property touch: Boolean
99// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
100// This does not necessarily mean that the browser is running in a computer with
101// a touchscreen, it only means that the browser is capable of understanding
102// touch events.
103export var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window ||
104 (window.DocumentTouch && document instanceof window.DocumentTouch));
105
106// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.
107export var mobileOpera = mobile && opera;
108
109// @property mobileGecko: Boolean
110// `true` for gecko-based browsers running in a mobile device.
111export var mobileGecko = mobile && gecko;
112
113// @property retina: Boolean
114// `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%.
115export var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;
116
117// @property passiveEvents: Boolean
118// `true` for browsers that support passive events.
119export var passiveEvents = (function () {
120 var supportsPassiveOption = false;
121 try {
122 var opts = Object.defineProperty({}, 'passive', {
123 get: function () {
124 supportsPassiveOption = true;
125 }
126 });
127 window.addEventListener('testPassiveEventSupport', Util.falseFn, opts);
128 window.removeEventListener('testPassiveEventSupport', Util.falseFn, opts);
129 } catch (e) {
130 // Errors can safely be ignored since this is only a browser support test.
131 }
132 return supportsPassiveOption;
133});
134
135// @property canvas: Boolean
136// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
137export var canvas = (function () {
138 return !!document.createElement('canvas').getContext;
139}());
140
141// @property svg: Boolean
142// `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).
143export var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect);
144
145// @property vml: Boolean
146// `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).
147export var vml = !svg && (function () {
148 try {
149 var div = document.createElement('div');
150 div.innerHTML = '<v:shape adj="1"/>';
151
152 var shape = div.firstChild;
153 shape.style.behavior = 'url(#default#VML)';
154
155 return shape && (typeof shape.adj === 'object');
156
157 } catch (e) {
158 return false;
159 }
160}());
161
162
163function userAgentContains(str) {
164 return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
165}