6 description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash.
8 license: MIT-style license.
10 requires: [Array, Function, Number, String]
12 provides: [Browser, Window, Document]
19 var document = this.document;
20 var window = document.window = this;
22 var parse = function(ua, platform){
23 ua = ua.toLowerCase();
24 platform = (platform ? platform.toLowerCase() : '');
26 // chrome is included in the edge UA, so need to check for edge first,
27 // before checking if it's chrome.
28 var UA = ua.match(/(edge)[\s\/:]([\w\d\.]+)/);
30 UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [null, 'unknown', 0];
33 if (UA[1] == 'trident'){
35 if (UA[4]) UA[2] = UA[4];
36 } else if (UA[1] == 'crios'){
40 platform = ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || ua.match(/mac|win|linux/) || ['other'])[0];
41 if (platform == 'win') platform = 'windows';
44 extend: Function.prototype.extend,
45 name: (UA[1] == 'version') ? UA[3] : UA[1],
46 version: parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
51 var Browser = this.Browser = parse(navigator.userAgent, navigator.platform);
53 if (Browser.name == 'ie' && document.documentMode){
54 Browser.version = document.documentMode;
59 xpath: !!(document.evaluate),
60 air: !!(window.runtime),
61 query: !!(document.querySelector),
68 Browser[Browser.name] = true;
69 Browser[Browser.name + parseInt(Browser.version, 10)] = true;
71 if (Browser.name == 'ie' && Browser.version >= '11'){
75 var platform = Browser.platform;
76 if (platform == 'windows'){
82 Browser.Platform[platform] = true;
87 Browser.Request = (function(){
89 var XMLHTTP = function(){
90 return new XMLHttpRequest();
93 var MSXML2 = function(){
94 return new ActiveXObject('MSXML2.XMLHTTP');
97 var MSXML = function(){
98 return new ActiveXObject('Microsoft.XMLHTTP');
101 return Function.attempt(function(){
114 Browser.Features.xhr = !!(Browser.Request);
120 var version = (Function.attempt(function(){
121 return navigator.plugins['Shockwave Flash'].description;
123 return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
124 }) || '0 r0').match(/\d+/g);
128 version: Number(version[0] || '0.' + version[1]) || 0,
129 build: Number(version[2]) || 0
137 Browser.exec = function(text){
138 if (!text) return text;
139 if (window.execScript){
140 window.execScript(text);
142 var script = document.createElement('script');
143 script.setAttribute('type', 'text/javascript');
145 document.head.appendChild(script);
146 document.head.removeChild(script);
151 String.implement('stripScripts', function(exec){
153 var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
154 scripts += code + '\n';
157 if (exec === true) Browser.exec(scripts);
158 else if (typeOf(exec) == 'function') exec(scripts, text);
165 Document: this.Document,
167 Element: this.Element,
171 this.Window = this.$constructor = new Type('Window', function(){});
173 this.$family = Function.from('window').hide();
175 Window.mirror(function(name, method){
176 window[name] = method;
179 this.Document = document.$constructor = new Type('Document', function(){});
181 document.$family = Function.from('document').hide();
183 Document.mirror(function(name, method){
184 document[name] = method;
187 document.html = document.documentElement;
188 if (!document.head) document.head = document.getElementsByTagName('head')[0];
190 if (document.execCommand) try {
191 document.execCommand("BackgroundImageCache", false, true);
195 if (this.attachEvent && !this.addEventListener){
196 var unloadEvent = function(){
197 this.detachEvent('onunload', unloadEvent);
198 document.head = document.html = document.window = null;
199 window = this.Window = document = null;
201 this.attachEvent('onunload', unloadEvent);
204 // IE fails on collections and <select>.options (refers to <select>)
205 var arrayFrom = Array.from;
207 arrayFrom(document.html.childNodes);
209 Array.from = function(item){
210 if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
211 var i = item.length, array = new Array(i);
212 while (i--) array[i] = item[i];
215 return arrayFrom(item);
218 var prototype = Array.prototype,
219 slice = prototype.slice;
220 ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
221 var method = prototype[name];
222 Array[name] = function(item){
223 return method.apply(Array.from(item), slice.call(arguments, 1));
231 if (Browser.Platform.ios) Browser.Platform.ipod = true;
235 var setEngine = function(name, version){
236 Browser.Engine.name = name;
237 Browser.Engine[name + version] = true;
238 Browser.Engine.version = version;
242 Browser.Engine.trident = true;
244 switch (Browser.version){
245 case 6: setEngine('trident', 4); break;
246 case 7: setEngine('trident', 5); break;
247 case 8: setEngine('trident', 6);
251 if (Browser.firefox){
252 Browser.Engine.gecko = true;
254 if (Browser.version >= 3) setEngine('gecko', 19);
255 else setEngine('gecko', 18);
258 if (Browser.safari || Browser.chrome){
259 Browser.Engine.webkit = true;
261 switch (Browser.version){
262 case 2: setEngine('webkit', 419); break;
263 case 3: setEngine('webkit', 420); break;
264 case 4: setEngine('webkit', 525);
269 Browser.Engine.presto = true;
271 if (Browser.version >= 9.6) setEngine('presto', 960);
272 else if (Browser.version >= 9.5) setEngine('presto', 950);
273 else setEngine('presto', 925);
276 if (Browser.name == 'unknown'){
277 switch ((navigator.userAgent.toLowerCase().match(/(?:webkit|khtml|gecko)/) || [])[0]){
280 Browser.Engine.webkit = true;
283 Browser.Engine.gecko = true;
287 this.$exec = Browser.exec;