/** * this code can only run at browser environment * @ignore * @author lifesinger@gmail.com, yiminghe@gmail.com */ (function (S, undefined) { var win = S.Env.host, logger = S.getLogger('s/web'), UA = S.UA, doc = win['document'], docElem = doc && doc.documentElement, location = win.location, EMPTY = '', readyDefer = new S.Defer(), readyPromise = readyDefer.promise, // The number of poll times. POLL_RETIRES = 500, // The poll interval in milliseconds. POLL_INTERVAL = 40, // #id or id RE_ID_STR = /^#?([\w-]+)$/, RE_NOT_WHITESPACE = /\S/, standardEventModel = !!(doc && doc.addEventListener), DOM_READY_EVENT = 'DOMContentLoaded', READY_STATE_CHANGE_EVENT = 'readystatechange', LOAD_EVENT = 'load', COMPLETE = 'complete', addEventListener = standardEventModel ? function (el, type, fn) { el.addEventListener(type, fn, false); } : function (el, type, fn) { el.attachEvent('on' + type, fn); }, removeEventListener = standardEventModel ? function (el, type, fn) { el.removeEventListener(type, fn, false); } : function (el, type, fn) { el.detachEvent('on' + type, fn); }; S.mix(S, { /** * A crude way of determining if an object is a window * @member KISSY */ isWindow: function (obj) { return obj != null && obj == obj.window; }, /** * get xml representation of data * @param {String} data * @member KISSY */ parseXML: function (data) { // already a xml if (data.documentElement) { return data; } var xml; try { // Standard if (win['DOMParser']) { xml = new DOMParser().parseFromString(data, 'text/xml'); } else { // IE xml = new ActiveXObject('Microsoft.XMLDOM'); xml.async = false; xml.loadXML(data); } } catch (e) { logger.error('parseXML error :'); logger.error(e); xml = undefined; } if (!xml || !xml.documentElement || xml.getElementsByTagName('parsererror').length) { S.error('Invalid XML: ' + data); } return xml; }, /** * Evaluates a script in a global context. * @member KISSY */ globalEval: function (data) { if (data && RE_NOT_WHITESPACE.test(data)) { // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context // http://msdn.microsoft.com/en-us/library/ie/ms536420(v=vs.85).aspx always return null ( win.execScript || function (data) { win[ 'eval' ].call(win, data); } )(data); } }, /** * Specify a function to execute when the Dom is fully loaded. * @param fn {Function} A function to execute after the Dom is ready * @chainable * @member KISSY */ ready: function (fn) { readyPromise.done(fn); return this; }, /** * Executes the supplied callback when the item with the supplied id is found. * @param id {String} The id of the element, or an array of ids to look for. * @param fn {Function} What to execute when the element is found. * @member KISSY */ available: function (id, fn) { id = (id + EMPTY).match(RE_ID_STR)[1]; var retryCount = 1; var timer = S.later(function () { if (++retryCount > POLL_RETIRES) { timer.cancel(); return; } var node = doc.getElementById(id); if (node) { fn(node); timer.cancel(); } }, POLL_INTERVAL, true); } }); function fireReady() { // nodejs if (doc && !UA.nodejs) { removeEventListener(win, LOAD_EVENT, fireReady); } readyDefer.resolve(S); } // Binds ready events. function bindReady() { // Catch cases where ready() is called after the // browser event has already occurred. if (!doc || doc.readyState === COMPLETE) { fireReady(); return; } // A fallback to window.onload, that will always work addEventListener(win, LOAD_EVENT, fireReady); // w3c mode if (standardEventModel) { var domReady = function () { removeEventListener(doc, DOM_READY_EVENT, domReady); fireReady(); }; addEventListener(doc, DOM_READY_EVENT, domReady); } // IE event model is used else { var stateChange = function () { if (doc.readyState === COMPLETE) { removeEventListener(doc, READY_STATE_CHANGE_EVENT, stateChange); fireReady(); } }; // ensure firing before onload (but completed after all inner iframes is loaded) // maybe late but safe also for iframes addEventListener(doc, READY_STATE_CHANGE_EVENT, stateChange); // If IE and not a frame // continually check to see if the document is ready var notframe, doScroll = docElem && docElem.doScroll; try { notframe = (win['frameElement'] === null); } catch (e) { notframe = false; } // can not use in iframe,parent window is dom ready so doScroll is ready too if (doScroll && notframe) { var readyScroll = function () { try { // Ref: http://javascript.nwbox.com/IEContentLoaded/ doScroll('left'); fireReady(); } catch (ex) { setTimeout(readyScroll, POLL_INTERVAL); } }; readyScroll(); } } } // If url contains '?ks-debug', debug mode will turn on automatically. if (location && (location.search || EMPTY).indexOf('ks-debug') !== -1) { S.Config.debug = true; } // bind on start // in case when you bind but the DOMContentLoaded has triggered // then you has to wait onload // worst case no callback at all bindReady(); if (UA.ie) { try { doc.execCommand('BackgroundImageCache', false, true); } catch (e) { } } })(KISSY, undefined);