UNPKG

fmd.js

Version:

another module writing system

156 lines (117 loc) 4.84 kB
/** * @module fmd/request * @author Edgar <mail@edgar.im> * @version v0.4 * @date 170105 * */ fmd( 'request', ['global','config','event'], function( global, config, event ){ 'use strict'; /** * Thanks to: * SeaJS, https://github.com/seajs/seajs/blob/master/src/util-request.js * https://github.com/seajs/seajs/blob/master/tests/research/load-js-css/test.html * https://github.com/seajs/seajs/blob/master/tests/research/load-js-css/load-css.html * YUI3, https://github.com/yui/yui3/blob/v3.13.0/src/get/js/get.js * HeadJS, https://github.com/headjs/headjs/blob/master/src/load.js * lazyload, https://github.com/rgrove/lazyload/blob/master/lazyload.js * RequireJS, https://github.com/jrburke/requirejs/blob/master/require.js * cujo.js, https://github.com/cujojs/curl/blob/master/src/curl.js * curl css! plugin, https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js * cssx, https://github.com/unscriptable/cssx/blob/master/src/cssx/css.js * LABjs, https://github.com/getify/LABjs/blob/2.0/LAB.src.js * */ var doc = global.document, setTimeout = global.setTimeout; var rStyle = /\.css(?:\?|$)/i, rReadyStates = /loaded|complete/, rLoadXdSheetError = /security|denied/i, rWebKit = /.*webkit\/?(\d+)\..*/, rMobile = /mobile/; var UA = global.navigator.userAgent.toLowerCase(); var webkitVersion = UA.match( rWebKit ), isOldWebKit = webkitVersion ? webkitVersion[1] * 1 < 536 : false, isPollCSS = isOldWebKit || ( !webkitVersion && rMobile.test( UA ) ); var head = doc && ( doc.head || doc.getElementsByTagName('head')[0] || doc.documentElement ); var createNode = function( asset, isStyle ){ var node; if ( isStyle ){ node = doc.createElement('link'); node.rel = 'stylesheet'; node.href = asset.url; } else { node = doc.createElement('script'); node.async = true; node.src = asset.url; } config.get( 'charset' ) && ( node.charset = config.get( 'charset' ) ); event.emit( 'createNode', node, asset ); return node; }, poll = function( node, callback, asset ){ var isLoaded = false, sheet, rules; try { sheet = node.sheet; if ( sheet ){ rules = sheet.cssRules; isLoaded = rules ? rules.length > 0 : rules !== undefined; } } catch( ex ){ isLoaded = rLoadXdSheetError.test( ex.message ); } setTimeout( function(){ if ( isLoaded ){ callback && callback(); event.emit( 'requested', asset ); } else { poll( node, callback, asset ); } }, 20 ); }; var onLoadAsset = function( node, callback, isSupportOnload, asset, isStyle ){ if ( isSupportOnload ){ node.onload = function(){ finish(); event.emit( 'requested', asset ); }; node.onerror = function(){ finish(); event.emit( 'requestError', asset ); }; } else { node.onreadystatechange = function(){ if ( rReadyStates.test( node.readyState ) ){ finish(); event.emit( 'requested', asset ); } }; } function finish(){ node.onload = node.onreadystatechange = node.onerror = null; if ( !isStyle && !config.get('debug') ){ node.parentNode && node.parentNode.removeChild( node ); } node = undefined; callback && callback(); } }, onLoadStyle = function( node, callback, isSupportOnload, asset ){ if ( !isSupportOnload || isPollCSS ){ setTimeout( function(){ poll( node, callback, asset ); }, 1 ); return; } onLoadAsset( node, callback, isSupportOnload, asset, true ); }, request = function( asset, callback ){ var isStyle = rStyle.test( asset.url ), node = createNode( asset, isStyle ), isSupportOnload = 'onload' in node; isStyle ? onLoadStyle( node, callback, isSupportOnload, asset ) : onLoadAsset( node, callback, isSupportOnload, asset ); head.appendChild( node ); }; return request; } );