Mootools源码分析 — Browser



            /*
浏览器相关特性,1.2之前附加到window对象中,并不合理
利用各浏览器的专有特征判断
*/
var Browser = new Hash({
//浏览器内核及版本
Engine: {name: 'unknown', version: ''},
//当前系统平台
Platform: {name: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
//浏览器特性,是否支持xpath及air,使用!!将表达式转为布尔值
Features: {xpath: !!(document.evaluate), air: !!(window.runtime)},
//浏览器插件
Plugins: {}
});
//Opera
if (window.opera) Browser.Engine = {name: ‘presto’, version: (document.getElementsByClassName) ? 950 : 925};
//IE
else if (window.ActiveXObject) Browser.Engine = {name: ‘trident’, version: (window.XMLHttpRequest) ? 5 : 4};
//Safari
else if (!navigator.taintEnabled) Browser.Engine = {name: ‘webkit’, version: (Browser.Features.xpath) ? 420 : 419};
//Mozilla
else if (document.getBoxObjectFor != null) Browser.Engine = {name: ‘gecko’, version: (document.getElementsByClassName) ? 19 : 18};
/*
加上判断引擎及版本的属性快捷方式,在没有这行代码之前,
判断是否IE只能用
Browser.Engine.name == 'trident'  为真;
如果要判断IE7则需要
(Browser.Engine.name == 'trident' && Browser.Engine.version == 5)为真;
而现在,判断IE只需要
Browser.Engine.trident 为真
判断IE7只需要
Browser.Engine.trident5 为真,同理可推
*/
Browser.Engine[Browser.Engine.name] = Browser.Engine[Browser.Engine.name + Browser.Engine.version] = true;
//使用iPod
if (window.orientation != undefined) Browser.Platform.name = 'ipod';
//与内核及版本的快捷方式类似,快速判断系统平台的方式
Browser.Platform[Browser.Platform.name] = true;
//XMLHttp的请求,按照语义放到Browser对象中,同时使用$try自动选择浏览器支持的对象
Browser.Request = function(){
return $try(function(){
  return new XMLHttpRequest();
}, function(){
  return new ActiveXObject('MSXML2.XMLHTTP');
});
};
//是否支持XMLHttpRequest
Browser.Features.xhr = !!(Browser.Request());
//Flash插件信息
Browser.Plugins.Flash = (function(){
var version = ($try(function(){
  //非IE下的插件获取方式
  return navigator.plugins['Shockwave Flash'].description;
}, function(){
  //IE下的插件获取方式
  return new ActiveXObject(’ShockwaveFlash.ShockwaveFlash’).GetVariable(’$version’);
}) || ‘0 r0′).match(/\d+/g);
return {version: parseInt(version[0] || 0 + ‘.’ + version[1] || 0), build: parseInt(version[2] || 0)};
})();
//将指定字符串作为脚本执行
function $exec(text){
if (!text) return text;
if (window.execScript){ //IE
  window.execScript(text);
} else { //非IE
  var script = document.createElement('script');
  script.setAttribute('type', 'text/javascript');
  script.text = text;
  document.head.appendChild(script);
  //注意DOM节点的移除,脚本执行之后已经没有存在的必要了
  document.head.removeChild(script);
}
return text;
};
//对象实例唯一标识
Native.UID = 1;
/*
唯一标识生成器
三目中使用函数而不是函数中使用三目运算的原因在于舍空间求时间,不必每次执行方法时都判断
*/
var $uid = (Browser.Engine.trident) ? function(item){
return (item.uid || (item.uid = [Native.UID++]))[0];
} : function(item){
return item.uid || (item.uid = Native.UID++);
};
//Window对象,对window对象的扩展
var Window = new Native({
//族名,为$type提供精准类型判断
name: 'Window',
//扩展原型
legacy: (Browser.Engine.trident) ? null: window.Window,
initialize: function(win){
  //生成唯一标识
  $uid(win);
  if (!win.Element){
  win.Element = $empty;
  if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2
  win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]”] : {};
  }
  return $extend(win, Window.Prototype);
},
//同时对当前window对象进行扩展
afterImplement: function(property, value){
  window[property] = Window.Prototype[property] = value;
}
});
Window.Prototype = {$family: {name: 'window'}};
new Window(window);
//Document对象,对document对象的扩展
var Document = new Native({
//族名,为$type提供精准类型判断
name: 'Document',
//扩展原型
legacy: (Browser.Engine.trident) ? null: window.Document,
initialize: function(doc){
  //生成唯一标识
  $uid(doc);
  //建立两个快捷方式
  doc.head = doc.getElementsByTagName('head')[0];
  doc.html = doc.getElementsByTagName(’html’)[0];
  //对当前文档所属window的快捷方式
  doc.window = doc.defaultView || doc.parentWindow;
  if (Browser.Engine.trident4) $try(function(){
  //修正IE6以下不缓存背景图片的Bug
  doc.execCommand("BackgroundImageCache", false, true);
  });
  return $extend(doc, Document.Prototype);
},
//同时对当前window对象进行扩展
afterImplement: function(property, value){
  document[property] = Document.Prototype[property] = value;
}
});
Document.Prototype = {$family: {name: 'document'}};
new Document(document);
                                                         


金鳞岂是池中物,一遇风云便化龙