/**
* @ignore
* dom
* @author yiminghe@gmail.com, lifesinger@gmail.com
*/
KISSY.add('dom/base/api', function (S) {
var WINDOW = S.Env.host || {},
DOCUMENT = WINDOW.document,
UA = S.UA,
RE_NUM = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,
/**
* Dom Element node type.
* @enum {Number} KISSY.DOM.NodeType
*/
NodeType = {
/**
* element type
*/
ELEMENT_NODE: 1,
/**
* attribute node type
*/
'ATTRIBUTE_NODE': 2,
/**
* text node type
*/
TEXT_NODE: 3,
/**
* cdata node type
*/
'CDATA_SECTION_NODE': 4,
/**
* entity reference node type
*/
'ENTITY_REFERENCE_NODE': 5,
/**
* entity node type
*/
'ENTITY_NODE': 6,
/**
* processing instruction node type
*/
'PROCESSING_INSTRUCTION_NODE': 7,
* comment node type
*/
COMMENT_NODE: 8,
/**
* document node type
*/
DOCUMENT_NODE: 9,
/**
* document type
*/
'DOCUMENT_TYPE_NODE': 10,
/**
* document fragment type
*/
DOCUMENT_FRAGMENT_NODE: 11,
/**
* notation type
*/
'NOTATION_NODE': 12
},
/**
* KISSY Dom Utils.
* Provides Dom helper methods.
* @class KISSY.DOM
* @singleton
*/
Dom = {
/**
* Whether has been set a custom domain.
* Note not perfect: localhost:8888, domain='localhost'
* @param {Window} [win] Test window. Default current window.
* @return {Boolean}
*/
isCustomDomain: function (win) {
win = win || WINDOW;
win = Dom.get(win);
var domain = win.document.domain,
hostname = win.location.hostname;
return domain != hostname &&
domain != ( '[' + hostname + ']' ); // IPv6 IP support
},
/**
* Get appropriate src for new empty iframe.
* Consider custom domain.
* @param {Window} [win] Window new iframe will be inserted into.
* @return {String} Src for iframe.
*/
getEmptyIframeSrc: function (win) {
win = win || WINDOW;
win = Dom.get(win);
if (UA['ie'] && Dom.isCustomDomain(win)) {
return 'javascript:void(function(){' + encodeURIComponent(
'document.open();' +
"document.domain='" +
win.document.domain
+ "';" +
'document.close();') + '}())';
}
return '';
},
NodeType: NodeType,
/**
* Return corresponding window if elem is document or window.
* Return global window if elem is undefined
* Else return false.
* @param {undefined|Window|HTMLDocument} [elem]
* @return {Window|Boolean}
*/
getWindow: function (elem) {
if (!elem) {
return WINDOW;
}
elem = Dom.get(elem);
if (S.isWindow(elem)) {
return elem;
}
var doc = elem;
if (doc.nodeType !== NodeType.DOCUMENT_NODE) {
doc = elem.ownerDocument;
}
return doc.defaultView || doc.parentWindow;
},
/**
* Return corresponding document of this element.
* @param {HTMLElement|Window|HTMLDocument} [elem]
* @return {HTMLDocument}
*/
getDocument: function (elem) {
if (!elem) {
return DOCUMENT;
}
elem = Dom.get(elem);
return S.isWindow(elem) ?
elem['document'] :
(elem.nodeType == NodeType.DOCUMENT_NODE ?
elem :
elem.ownerDocument);
},
isDomNodeList: function (o) {
// 注1:ie 下,有 window.item, typeof node.item 在 ie 不同版本下,返回值不同
// 注2:select 等元素也有 item, 要用 !node.nodeType 排除掉
// 注3:通过 namedItem 来判断不可靠
// 注4:getElementsByTagName 和 querySelectorAll 返回的集合不同
// 注5: 考虑 iframe.contentWindow
return o && !o.nodeType && o.item && !o.setTimeout;
},
/**
* Get node 's nodeName in lowercase.
* @param {HTMLElement[]|String|HTMLElement} selector Matched elements.
* @return {String} el 's nodeName in lowercase
*/
nodeName: function (selector) {
var el = Dom.get(selector),
nodeName = el.nodeName.toLowerCase();
// http://msdn.microsoft.com/en-us/library/ms534388(VS.85).aspx
if (UA['ie']) {
var scopeName = el['scopeName'];
if (scopeName && scopeName != 'HTML') {
nodeName = scopeName.toLowerCase() + ':' + nodeName;
}
}
return nodeName;
},
_RE_NUM_NO_PX: new RegExp("^(" + RE_NUM + ")(?!px)[a-z%]+$", "i")
};
S.mix(Dom, NodeType);
return Dom;
});
/*
2011-08
- 添加节点类型枚举值,方便依赖程序清晰
*/