]>
git.proxmox.com Git - extjs.git/blob - extjs/modern/theme-device-base/.sencha/package/Microloader.js
1 // here, the extra check for window['Ext'] is needed for use with cmd-test
2 // code injection. we need to make that this file will sync up with page global
3 // scope to avoid duplicate Ext.Boot state. That check is after the initial Ext check
4 // to allow the sandboxing template to inject an appropriate Ext var and prevent the
6 var Ext
= Ext
|| window
[ 'Ext' ] || {};
9 //<editor-fold desc="Microloader">
11 * @Class Ext.Microloader
14 Ext
. Microloader
= Ext
. Microloader
|| ( function () {
17 _debug = function ( message
) {
18 //console.log(message);
21 _warn = function ( message
) {
22 console
. log ( "[WARN] " + message
);
24 _privatePrefix
= '_ext:' + location
. pathname
,
27 * The Following combination is used to create isolated local storage keys
28 * '_ext' is used to scope all the local storage keys that we internally by Ext
29 * 'location.pathname' is used to force each assets to cache by an absolute URL (/build/MyApp) (dev vs prod)
30 * 'url' is used to force each asset to cache relative to the page (app.json vs resources/app.css)
31 * 'profileId' is used to differentiate the builds of an application (neptune vs crisp)
32 * 'Microloader.appId' is unique to the application and will differentiate apps on the same host (dev mode running app watch against multiple apps)
34 getStorageKey = function ( url
, profileId
) {
35 return _privatePrefix
+ url
+ '-' + ( profileId
? profileId
+ '-' : '' ) + Microloader
. appId
;
37 postProcessor
, _storage
;
40 _storage
= window
[ 'localStorage' ];
45 var _cache
= window
[ 'applicationCache' ],
46 // Local Storage Controller
48 clearAllPrivate : function ( manifest
) {
51 //Remove the entry for the manifest first
52 _storage
. removeItem ( manifest
. key
);
56 suffix
= manifest
. profile
+ '-' + Microloader
. appId
,
58 for ( i
= 0 ; i
< ln
; i
++) {
59 key
= _storage
. key ( i
);
60 // If key starts with the private key and the suffix is present we can clear this entry
61 if ( key
. indexOf ( _privatePrefix
) === 0 && key
. indexOf ( suffix
) !== - 1 ) {
66 for ( i
in removeKeys
) {
68 _debug ( "Removing " + removeKeys
[ i
] + " from Local Storage" );
70 _storage
. removeItem ( removeKeys
[ i
]);
77 retrieveAsset : function ( key
) {
79 return _storage
. getItem ( key
);
82 // Private browsing mode
87 setAsset : function ( key
, content
) {
89 if ( content
=== null || content
== '' ) {
90 _storage
. removeItem ( key
);
92 _storage
. setItem ( key
, content
);
96 if ( _storage
&& e
. code
== e
. QUOTA_EXCEEDED_ERR
) {
98 _warn ( "LocalStorage Quota exceeded, cannot store " + key
+ " locally" );
105 var Asset = function ( cfg
) {
106 if ( typeof cfg
. assetConfig
=== 'string' ) {
108 path
: cfg
. assetConfig
111 this . assetConfig
= cfg
. assetConfig
;
114 this . type
= cfg
. type
;
115 this . key
= getStorageKey ( this . assetConfig
. path
, cfg
. manifest
. profile
);
117 if ( cfg
. loadFromCache
) {
118 this . loadFromCache ();
123 shouldCache : function () {
124 return _storage
&& this . assetConfig
. update
&& this . assetConfig
. hash
&& ! this . assetConfig
. remote
;
127 is : function ( asset
) {
128 return (!! asset
&& this . assetConfig
&& asset
. assetConfig
&& ( this . assetConfig
. hash
=== asset
. assetConfig
. hash
))
131 cache : function ( content
) {
132 if ( this . shouldCache ()) {
133 LocalStorage
. setAsset ( this . key
, content
|| this . content
);
137 uncache : function () {
138 LocalStorage
. setAsset ( this . key
, null );
141 updateContent : function ( content
) {
142 this . content
= content
;
145 getSize : function () {
146 return this . content
? this . content
. length
: 0 ;
149 loadFromCache : function () {
150 if ( this . shouldCache ()) {
151 this . content
= LocalStorage
. retrieveAsset ( this . key
);
156 var Manifest = function ( cfg
) {
157 if ( typeof cfg
. content
=== "string" ) {
158 this . content
= JSON
. parse ( cfg
. content
);
160 this . content
= cfg
. content
;
165 this . fromCache
= !! cfg
. cached
;
166 this . assetCache
= !( cfg
. assetCache
=== false );
167 this . key
= getStorageKey ( this . url
);
169 // Pull out select properties for repetitive use
170 this . profile
= this . content
. profile
;
171 this . hash
= this . content
. hash
;
172 this . loadOrder
= this . content
. loadOrder
;
173 this . deltas
= this . content
. cache
? this . content
. cache
. deltas
: null ;
174 this . cacheEnabled
= this . content
. cache
? this . content
. cache
. enable
: false ;
176 this . loadOrderMap
= ( this . loadOrder
) ? Boot
. createLoadOrderMap ( this . loadOrder
) : null ;
178 // Convert all assets into Assets
179 this . js
= this . processAssets ( this . content
. js
, 'js' );
180 this . css
= this . processAssets ( this . content
. css
, 'css' );
183 Manifest
. prototype = {
184 processAsset : function ( assetConfig
, type
) {
185 var processedAsset
= new Asset ({
187 assetConfig
: assetConfig
,
189 loadFromCache
: this . assetCache
191 this . assetMap
[ assetConfig
. path
] = processedAsset
;
192 return processedAsset
;
195 processAssets : function ( assets
, type
) {
200 for ( i
= 0 ; i
< ln
; i
++) {
201 assetConfig
= assets
[ i
];
202 results
. push ( this . processAsset ( assetConfig
, type
));
208 useAppCache : function () {
212 // Concatenate all assets for easy access
213 getAssets : function () {
214 return this . css
. concat ( this . js
);
217 getAsset : function ( path
) {
218 return this . assetMap
[ path
];
221 shouldCache : function () {
222 return this . hash
&& this . cacheEnabled
;
225 cache : function ( content
) {
226 if ( this . shouldCache ()) {
227 LocalStorage
. setAsset ( this . key
, JSON
. stringify ( content
|| this . content
));
231 _debug ( "Manifest caching is disabled." );
236 is : function ( manifest
) {
238 _debug ( "Testing Manifest: " + this . hash
+ " VS " + manifest
. hash
);
240 return this . hash
=== manifest
. hash
;
243 // Clear the manifest from local storage
244 uncache : function () {
245 LocalStorage
. setAsset ( this . key
, null );
248 exportContent : function () {
250 loadOrderMap
: this . loadOrderMap
264 Ext
. microloaded
= true ;
266 // data-app is in the dev template for an application and is also
267 // injected into the app my CMD for production
268 // We use this to prefix localStorage cache to prevent collisions
269 var microloaderElement
= document
. getElementById ( 'microloader' );
270 Microloader
. appId
= microloaderElement
? microloaderElement
. getAttribute ( 'data-app' ) : '' ;
272 if ( Ext
. beforeLoad
) {
273 postProcessor
= Ext
. beforeLoad ( Ext
. platformTags
);
276 var readyHandler
= Ext
. _beforereadyhandler
;
278 Ext
. _beforereadyhandler = function () {
279 if ( Ext
. Boot
!== Boot
) {
280 Ext
. apply ( Ext
. Boot
, Boot
);
291 var manifest
= Ext
. manifest
;
293 if ( typeof manifest
=== "string" ) {
294 var extension
= ".json" ,
295 url
= manifest
. indexOf ( extension
) === manifest
. length
- extension
. length
297 : manifest
+ ".json" ,
298 key
= getStorageKey ( url
),
299 content
= LocalStorage
. retrieveAsset ( key
);
301 // Manifest found in local storage, use this for immediate boot except in PhantomJS environments for building.
304 _debug ( "Manifest file, '" + url
+ "', was found in Local Storage" );
306 manifest
= new Manifest ({
312 postProcessor ( manifest
);
314 Microloader
. load ( manifest
);
317 // Manifest is not in local storage. Fetch it from the server
319 Boot
. fetch ( url
, function ( result
) {
321 _debug ( "Manifest file was not found in Local Storage, loading: " + url
);
323 manifest
= new Manifest ({
325 content
: result
. content
330 postProcessor ( manifest
);
332 Microloader
. load ( manifest
);
336 // Embedded Manifest into JS file
339 _debug ( "Manifest was embedded into application javascript file" );
341 manifest
= new Manifest ({
344 Microloader
. load ( manifest
);
350 * @param {Manifest} manifest
352 load : function ( manifest
) {
353 Microloader
. urls
= [];
354 Microloader
. manifest
= manifest
;
355 Ext
. manifest
= Microloader
. manifest
. exportContent ();
357 var assets
= manifest
. getAssets (),
359 asset
, i
, len
, include
, entry
;
361 for ( len
= assets
. length
, i
= 0 ; i
< len
; i
++) {
363 include
= Microloader
. filterAsset ( asset
);
365 // Asset is using the localStorage caching system
366 if ( manifest
. shouldCache () && asset
. shouldCache ()) {
367 // Asset already has content from localStorage, instantly seed that into boot
370 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was found in local storage. No remote load for this file" );
372 entry
= Boot
. registerContent ( asset
. assetConfig
. path
, asset
. type
, asset
. content
);
373 if ( entry
. evaluated
) {
374 _warn ( "Asset: " + asset
. assetConfig
. path
+ " was evaluated prior to local storage being consulted." );
376 //load via AJAX and seed content into Boot
379 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was NOT found in local storage. Adding to load queue" );
381 cachedAssets
. push ( asset
);
384 Microloader
. urls
. push ( asset
. assetConfig
. path
);
388 // If any assets are using the caching system and do not have local versions load them first via AJAX
389 if ( cachedAssets
. length
> 0 ) {
390 Microloader
. remainingCachedAssets
= cachedAssets
. length
;
391 while ( cachedAssets
. length
> 0 ) {
392 asset
= cachedAssets
. pop ();
394 _debug ( "Preloading/Fetching Cached Assets from: " + asset
. assetConfig
. path
);
396 Boot
. fetch ( asset
. assetConfig
. path
, ( function ( asset
) {
397 return function ( result
) {
398 Microloader
. onCachedAssetLoaded ( asset
, result
);
403 Microloader
. onCachedAssetsReady ();
407 // Load the asset and seed its content into Boot to be evaluated in sequence
408 onCachedAssetLoaded : function ( asset
, result
) {
410 result
= Microloader
. parseResult ( result
);
411 Microloader
. remainingCachedAssets
--;
414 checksum
= Microloader
. checksum ( result
. content
, asset
. assetConfig
. hash
);
416 _warn ( "Cached Asset '" + asset
. assetConfig
. path
+ "' has failed checksum. This asset will be uncached for future loading" );
418 // Un cache this asset so it is loaded next time
423 _debug ( "Checksum for Cached Asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
425 Boot
. registerContent ( asset
. assetConfig
. path
, asset
. type
, result
. content
);
426 asset
. updateContent ( result
. content
);
429 _warn ( "There was an error pre-loading the asset '" + asset
. assetConfig
. path
+ "'. This asset will be uncached for future loading" );
431 // Un cache this asset so it is loaded next time
435 if ( Microloader
. remainingCachedAssets
=== 0 ) {
436 Microloader
. onCachedAssetsReady ();
440 onCachedAssetsReady : function (){
442 url
: Microloader
. urls
,
443 loadOrder
: Microloader
. manifest
. loadOrder
,
444 loadOrderMap
: Microloader
. manifest
. loadOrderMap
,
446 success
: Microloader
. onAllAssetsReady
,
447 failure
: Microloader
. onAllAssetsReady
451 onAllAssetsReady : function () {
453 Microloader
. notify ();
455 if ( navigator
. onLine
!== false ) {
457 _debug ( "Application is online, checking for updates" );
459 Microloader
. checkAllUpdates ();
463 _debug ( "Application is offline, adding online listener to check for updates" );
465 if ( window
[ 'addEventListener' ]) {
466 window
. addEventListener ( 'online' , Microloader
. checkAllUpdates
, false );
471 onMicroloaderReady : function ( listener
) {
475 _listeners
. push ( listener
);
482 notify : function () {
484 _debug ( "notifying microloader ready listeners." );
487 while (( listener
= _listeners
. shift ())) {
492 // Delta patches content
493 patch : function ( content
, delta
) {
497 if ( delta
. length
=== 0 ) {
501 for ( i
= 0 , ln
= delta
. length
; i
< ln
; i
++) {
504 if ( typeof chunk
=== 'number' ) {
505 output
. push ( content
. substring ( chunk
, chunk
+ delta
[++ i
]));
512 return output
. join ( '' );
515 checkAllUpdates : function () {
517 _debug ( "Checking for All Updates" );
519 if ( window
[ 'removeEventListener' ]) {
520 window
. removeEventListener ( 'online' , Microloader
. checkAllUpdates
, false );
524 Microloader
. checkForAppCacheUpdate ();
527 // Manifest came from a cached instance, check for updates
528 if ( Microloader
. manifest
. fromCache
) {
529 Microloader
. checkForUpdates ();
533 checkForAppCacheUpdate : function () {
535 _debug ( "Checking App Cache status" );
537 if ( _cache
. status
=== _cache
. UPDATEREADY
|| _cache
. status
=== _cache
. OBSOLETE
) {
539 _debug ( "App Cache is already in an updated" );
541 Microloader
. appCacheState
= 'updated' ;
542 } else if ( _cache
. status
!== _cache
. IDLE
&& _cache
. status
!== _cache
. UNCACHED
) {
544 _debug ( "App Cache is checking or downloading updates, adding listeners" );
546 Microloader
. appCacheState
= 'checking' ;
547 _cache
. addEventListener ( 'error' , Microloader
. onAppCacheError
);
548 _cache
. addEventListener ( 'noupdate' , Microloader
. onAppCacheNotUpdated
);
549 _cache
. addEventListener ( 'cached' , Microloader
. onAppCacheNotUpdated
);
550 _cache
. addEventListener ( 'updateready' , Microloader
. onAppCacheReady
);
551 _cache
. addEventListener ( 'obsolete' , Microloader
. onAppCacheObsolete
);
554 _debug ( "App Cache is current or uncached" );
556 Microloader
. appCacheState
= 'current' ;
560 checkForUpdates : function () {
561 // Fetch the Latest Manifest from the server
563 _debug ( "Checking for updates at: " + Microloader
. manifest
. url
);
565 Boot
. fetch ( Microloader
. manifest
. url
, Microloader
. onUpdatedManifestLoaded
);
568 onAppCacheError : function ( e
) {
571 Microloader
. appCacheState
= 'error' ;
572 Microloader
. notifyUpdateReady ();
575 onAppCacheReady : function () {
577 Microloader
. appCacheUpdated ();
580 onAppCacheObsolete : function () {
581 Microloader
. appCacheUpdated ();
584 appCacheUpdated : function () {
586 _debug ( "App Cache Updated" );
588 Microloader
. appCacheState
= 'updated' ;
589 Microloader
. notifyUpdateReady ();
592 onAppCacheNotUpdated : function () {
594 _debug ( "App Cache Not Updated Callback" );
596 Microloader
. appCacheState
= 'current' ;
597 Microloader
. notifyUpdateReady ();
601 filterAsset : function ( asset
) {
602 var cfg
= ( asset
&& asset
. assetConfig
) || {};
603 if ( cfg
. platform
|| cfg
. exclude
) {
604 return Boot
. filterPlatform ( cfg
. platform
, cfg
. exclude
);
609 onUpdatedManifestLoaded : function ( result
) {
610 result
= Microloader
. parseResult ( result
);
613 var currentAssets
, newAssets
, currentAsset
, newAsset
, prop
,
614 assets
, deltas
, deltaPath
, include
,
616 manifest
= new Manifest ({
617 url
: Microloader
. manifest
. url
,
618 content
: result
. content
,
622 Microloader
. remainingUpdatingAssets
= 0 ;
623 Microloader
. updatedAssets
= [];
624 Microloader
. removedAssets
= [];
625 Microloader
. updatedManifest
= null ;
626 Microloader
. updatedAssetsReady
= false ;
628 // If the updated manifest has turned off caching we need to clear out all local storage
629 // and trigger a appupdate as all content is now uncached
630 if (! manifest
. shouldCache ()) {
632 _debug ( "New Manifest has caching disabled, clearing out any private storage" );
635 Microloader
. updatedManifest
= manifest
;
636 LocalStorage
. clearAllPrivate ( manifest
);
637 Microloader
. onAllUpdatedAssetsReady ();
641 // Manifest itself has changed
642 if (! Microloader
. manifest
. is ( manifest
)) {
643 Microloader
. updatedManifest
= manifest
;
645 currentAssets
= Microloader
. manifest
. getAssets ();
646 newAssets
= manifest
. getAssets ();
648 // Look through new assets for assets that do not exist or assets that have different versions
649 for ( prop
in newAssets
) {
650 newAsset
= newAssets
[ prop
];
651 currentAsset
= Microloader
. manifest
. getAsset ( newAsset
. assetConfig
. path
);
652 include
= Microloader
. filterAsset ( newAsset
);
654 if ( include
&& (! currentAsset
|| ( newAsset
. shouldCache () && (! currentAsset
. is ( newAsset
))))) {
656 _debug ( "New/Updated Version of Asset: " + newAsset
. assetConfig
. path
+ " was found in new manifest" );
658 updatingAssets
. push ({ _new
: newAsset
, _current
: currentAsset
});
662 // Look through current assets for stale/old assets that have been removed
663 for ( prop
in currentAssets
) {
664 currentAsset
= currentAssets
[ prop
];
665 newAsset
= manifest
. getAsset ( currentAsset
. assetConfig
. path
);
667 //New version of this asset has been filtered out
668 include
= ! Microloader
. filterAsset ( newAsset
);
670 if (! include
|| ! newAsset
|| ( currentAsset
. shouldCache () && ! newAsset
. shouldCache ())) {
672 _debug ( "Asset: " + currentAsset
. assetConfig
. path
+ " was not found in new manifest, has been filtered out or has been switched to not cache. Marked for removal" );
674 Microloader
. removedAssets
. push ( currentAsset
);
678 // Loop through all assets that need updating
679 if ( updatingAssets
. length
> 0 ) {
680 Microloader
. remainingUpdatingAssets
= updatingAssets
. length
;
681 while ( updatingAssets
. length
> 0 ) {
682 assets
= updatingAssets
. pop ();
683 newAsset
= assets
. _new
;
684 currentAsset
= assets
. _current
;
686 // Full Updates will simply download the file and replace its current content
687 if ( newAsset
. assetConfig
. update
=== "full" || ! currentAsset
) {
690 if ( newAsset
. assetConfig
. update
=== "delta" ) {
691 _debug ( "Delta updated asset found without current asset available: " + newAsset
. assetConfig
. path
+ " fetching full file" );
693 _debug ( "Full update found for: " + newAsset
. assetConfig
. path
+ " fetching" );
697 // Load the asset and cache its its content into Boot to be evaluated in sequence
698 Boot
. fetch ( newAsset
. assetConfig
. path
, ( function ( asset
) {
699 return function ( result
) {
700 Microloader
. onFullAssetUpdateLoaded ( asset
, result
)
705 // Delta updates will be given a delta patch
706 } else if ( newAsset
. assetConfig
. update
=== "delta" ) {
707 deltas
= manifest
. deltas
;
708 deltaPath
= deltas
+ "/" + newAsset
. assetConfig
. path
+ "/" + currentAsset
. assetConfig
. hash
+ ".json" ;
709 // Fetch the Delta Patch and update the contents of the asset
711 _debug ( "Delta update found for: " + newAsset
. assetConfig
. path
+ " fetching" );
713 Boot
. fetch ( deltaPath
,
714 ( function ( asset
, oldAsset
) {
715 return function ( result
) {
716 Microloader
. onDeltaAssetUpdateLoaded ( asset
, oldAsset
, result
)
718 }( newAsset
, currentAsset
))
724 _debug ( "No Assets needed updating" );
726 Microloader
. onAllUpdatedAssetsReady ();
730 _debug ( "Manifest files have matching hash's" );
732 Microloader
. onAllUpdatedAssetsReady ();
735 _warn ( "Error loading manifest file to check for updates" );
736 Microloader
. onAllUpdatedAssetsReady ();
740 onFullAssetUpdateLoaded : function ( asset
, result
) {
742 result
= Microloader
. parseResult ( result
);
743 Microloader
. remainingUpdatingAssets
--;
746 checksum
= Microloader
. checksum ( result
. content
, asset
. assetConfig
. hash
);
748 _debug ( "Checksum for Full asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
752 _debug ( "Full Update Asset: " + asset
. assetConfig
. path
+ " has failed checksum. This asset will be uncached for future loading" );
755 // uncache this asset as there is a new version somewhere that has not been loaded.
758 asset
. updateContent ( result
. content
);
759 Microloader
. updatedAssets
. push ( asset
);
763 _debug ( "Error loading file at" + asset
. assetConfig
. path
+ ". This asset will be uncached for future loading" );
766 // uncache this asset as there is a new version somewhere that has not been loaded.
770 if ( Microloader
. remainingUpdatingAssets
=== 0 ) {
771 Microloader
. onAllUpdatedAssetsReady ();
775 onDeltaAssetUpdateLoaded : function ( asset
, oldAsset
, result
) {
776 var json
, checksum
, content
;
777 result
= Microloader
. parseResult ( result
);
778 Microloader
. remainingUpdatingAssets
--;
782 _debug ( "Delta patch loaded successfully, patching content" );
785 json
= JSON
. parse ( result
. content
);
786 content
= Microloader
. patch ( oldAsset
. content
, json
);
787 checksum
= Microloader
. checksum ( content
, asset
. assetConfig
. hash
);
789 _debug ( "Checksum for Delta Patched asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
793 _debug ( "Delta Update Asset: " + asset
. assetConfig
. path
+ " has failed checksum. This asset will be uncached for future loading" );
796 // uncache this asset as there is a new version somewhere that has not been loaded.
799 asset
. updateContent ( content
);
800 Microloader
. updatedAssets
. push ( asset
);
803 _warn ( "Error parsing delta patch for " + asset
. assetConfig
. path
+ " with hash " + oldAsset
. assetConfig
. hash
+ " . This asset will be uncached for future loading" );
804 // uncache this asset as there is a new version somewhere that has not been loaded.
808 _warn ( "Error loading delta patch for " + asset
. assetConfig
. path
+ " with hash " + oldAsset
. assetConfig
. hash
+ " . This asset will be uncached for future loading" );
810 // uncache this asset as there is a new version somewhere that has not been loaded.
813 if ( Microloader
. remainingUpdatingAssets
=== 0 ) {
814 Microloader
. onAllUpdatedAssetsReady ();
818 //TODO: Make this all transaction based to allow for reverting if quota is exceeded
819 onAllUpdatedAssetsReady : function () {
821 Microloader
. updatedAssetsReady
= true ;
823 if ( Microloader
. updatedManifest
) {
824 while ( Microloader
. removedAssets
. length
> 0 ) {
825 asset
= Microloader
. removedAssets
. pop ();
827 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was removed, un-caching" );
832 if ( Microloader
. updatedManifest
) {
834 _debug ( "Manifest was updated, re-caching" );
836 Microloader
. updatedManifest
. cache ();
839 while ( Microloader
. updatedAssets
. length
> 0 ) {
840 asset
= Microloader
. updatedAssets
. pop ();
842 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was updated, re-caching" );
849 Microloader
. notifyUpdateReady ();
852 notifyUpdateReady : function () {
853 if ( Microloader
. appCacheState
!== 'checking' && Microloader
. updatedAssetsReady
) {
854 if ( Microloader
. appCacheState
=== 'updated' || Microloader
. updatedManifest
) {
856 _debug ( "There was an update here you will want to reload the app, trigger an event" );
858 Microloader
. appUpdate
= {
860 app
: Microloader
. appCacheState
=== 'updated' ,
861 manifest
: Microloader
. updatedManifest
&& Microloader
. updatedManifest
. exportContent ()
864 Microloader
. fireAppUpdate ();
868 _debug ( "AppCache and LocalStorage Cache are current, no updating needed" );
869 Microloader
. appUpdate
= {};
875 fireAppUpdate : function () {
876 if ( Ext
. GlobalEvents
) {
877 // We defer dispatching this event slightly in order to let the application finish loading
878 // as we are still very early in the lifecycle
879 Ext
. defer ( function () {
880 Ext
. GlobalEvents
. fireEvent ( 'appupdate' , Microloader
. appUpdate
);
885 checksum : function ( content
, hash
) {
886 if (! content
|| ! hash
) {
891 hashLn
= hash
. length
,
892 checksumType
= content
. substring ( 0 , 1 );
894 if ( checksumType
== '/' ) {
895 if ( content
. substring ( 2 , hashLn
+ 2 ) !== hash
) {
898 } else if ( checksumType
== 'f' ) {
899 if ( content
. substring ( 10 , hashLn
+ 10 ) !== hash
) {
902 } else if ( checksumType
== '.' ) {
903 if ( content
. substring ( 1 , hashLn
+ 1 ) !== hash
) {
909 parseResult : function ( result
) {
911 if (( result
. exception
|| result
. status
=== 0 ) && ! Boot
. env
. phantom
) {
913 } else if (( result
. status
>= 200 && result
. status
< 300 ) || result
. status
=== 304
915 || ( result
. status
=== 0 && result
. content
. length
> 0 )
917 rst
. content
= result
. content
;
929 * @type {String/Object}
931 Ext
. manifest
= Ext
. manifest
|| "bootstrap" ;
933 Ext
. Microloader
. run ();