]>
git.proxmox.com Git - extjs.git/blob - extjs/classic/theme-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 var tags
= this . content
. tags
,
179 platformTags
= Ext
. platformTags
;
182 if ( tags
instanceof Array
) {
183 for ( var i
= 0 ; i
< tags
. length
; i
++) {
184 platformTags
[ tags
[ i
]] = true ;
187 Boot
. apply ( platformTags
, tags
);
190 // re-apply the query parameters, so that the params as specified
191 // in the url always has highest priority
192 Boot
. apply ( platformTags
, Boot
. loadPlatformsParam ());
195 // Convert all assets into Assets
196 this . js
= this . processAssets ( this . content
. js
, 'js' );
197 this . css
= this . processAssets ( this . content
. css
, 'css' );
200 Manifest
. prototype = {
201 processAsset : function ( assetConfig
, type
) {
202 var processedAsset
= new Asset ({
204 assetConfig
: assetConfig
,
206 loadFromCache
: this . assetCache
208 this . assetMap
[ assetConfig
. path
] = processedAsset
;
209 return processedAsset
;
212 processAssets : function ( assets
, type
) {
217 for ( i
= 0 ; i
< ln
; i
++) {
218 assetConfig
= assets
[ i
];
219 results
. push ( this . processAsset ( assetConfig
, type
));
225 useAppCache : function () {
229 // Concatenate all assets for easy access
230 getAssets : function () {
231 return this . css
. concat ( this . js
);
234 getAsset : function ( path
) {
235 return this . assetMap
[ path
];
238 shouldCache : function () {
239 return this . hash
&& this . cacheEnabled
;
242 cache : function ( content
) {
243 if ( this . shouldCache ()) {
244 LocalStorage
. setAsset ( this . key
, JSON
. stringify ( content
|| this . content
));
248 _debug ( "Manifest caching is disabled." );
253 is : function ( manifest
) {
255 _debug ( "Testing Manifest: " + this . hash
+ " VS " + manifest
. hash
);
257 return this . hash
=== manifest
. hash
;
260 // Clear the manifest from local storage
261 uncache : function () {
262 LocalStorage
. setAsset ( this . key
, null );
265 exportContent : function () {
267 loadOrderMap
: this . loadOrderMap
281 Ext
. microloaded
= true ;
283 // data-app is in the dev template for an application and is also
284 // injected into the app my CMD for production
285 // We use this to prefix localStorage cache to prevent collisions
286 var microloaderElement
= document
. getElementById ( 'microloader' );
287 Microloader
. appId
= microloaderElement
? microloaderElement
. getAttribute ( 'data-app' ) : '' ;
289 if ( Ext
. beforeLoad
) {
290 postProcessor
= Ext
. beforeLoad ( Ext
. platformTags
);
293 var readyHandler
= Ext
. _beforereadyhandler
;
295 Ext
. _beforereadyhandler = function () {
296 if ( Ext
. Boot
!== Boot
) {
297 Ext
. apply ( Ext
. Boot
, Boot
);
306 applyCacheBuster : function ( url
) {
307 var tstamp
= new Date (). getTime (),
308 sep
= url
. indexOf ( '?' ) === - 1 ? '?' : '&' ;
309 url
= url
+ sep
+ "_dc=" + tstamp
;
315 var manifest
= Ext
. manifest
;
317 if ( typeof manifest
=== "string" ) {
318 var extension
= ".json" ,
319 url
= manifest
. indexOf ( extension
) === manifest
. length
- extension
. length
321 : manifest
+ ".json" ,
322 key
= getStorageKey ( url
),
323 content
= LocalStorage
. retrieveAsset ( key
);
325 // Manifest found in local storage, use this for immediate boot except in PhantomJS environments for building.
328 _debug ( "Manifest file, '" + url
+ "', was found in Local Storage" );
330 manifest
= new Manifest ({
336 postProcessor ( manifest
);
338 Microloader
. load ( manifest
);
341 // Manifest is not in local storage. Fetch it from the server
343 Boot
. fetch ( Microloader
. applyCacheBuster ( url
), function ( result
) {
345 _debug ( "Manifest file was not found in Local Storage, loading: " + url
);
347 manifest
= new Manifest ({
349 content
: result
. content
354 postProcessor ( manifest
);
356 Microloader
. load ( manifest
);
360 // Embedded Manifest into JS file
363 _debug ( "Manifest was embedded into application javascript file" );
365 manifest
= new Manifest ({
368 Microloader
. load ( manifest
);
374 * @param {Manifest} manifest
376 load : function ( manifest
) {
377 Microloader
. urls
= [];
378 Microloader
. manifest
= manifest
;
379 Ext
. manifest
= Microloader
. manifest
. exportContent ();
381 var assets
= manifest
. getAssets (),
383 asset
, i
, len
, include
, entry
;
385 for ( len
= assets
. length
, i
= 0 ; i
< len
; i
++) {
387 include
= Microloader
. filterAsset ( asset
);
389 // Asset is using the localStorage caching system
390 if ( manifest
. shouldCache () && asset
. shouldCache ()) {
391 // Asset already has content from localStorage, instantly seed that into boot
394 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was found in local storage. No remote load for this file" );
396 entry
= Boot
. registerContent ( asset
. assetConfig
. path
, asset
. type
, asset
. content
);
397 if ( entry
. evaluated
) {
398 _warn ( "Asset: " + asset
. assetConfig
. path
+ " was evaluated prior to local storage being consulted." );
400 //load via AJAX and seed content into Boot
403 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was NOT found in local storage. Adding to load queue" );
405 cachedAssets
. push ( asset
);
408 Microloader
. urls
. push ( asset
. assetConfig
. path
);
409 Boot
. assetConfig
[ asset
. assetConfig
. path
] = Boot
. apply ({ type
: asset
. type
}, asset
. assetConfig
);
413 // If any assets are using the caching system and do not have local versions load them first via AJAX
414 if ( cachedAssets
. length
> 0 ) {
415 Microloader
. remainingCachedAssets
= cachedAssets
. length
;
416 while ( cachedAssets
. length
> 0 ) {
417 asset
= cachedAssets
. pop ();
419 _debug ( "Preloading/Fetching Cached Assets from: " + asset
. assetConfig
. path
);
421 Boot
. fetch ( asset
. assetConfig
. path
, ( function ( asset
) {
422 return function ( result
) {
423 Microloader
. onCachedAssetLoaded ( asset
, result
);
428 Microloader
. onCachedAssetsReady ();
432 // Load the asset and seed its content into Boot to be evaluated in sequence
433 onCachedAssetLoaded : function ( asset
, result
) {
435 result
= Microloader
. parseResult ( result
);
436 Microloader
. remainingCachedAssets
--;
439 checksum
= Microloader
. checksum ( result
. content
, asset
. assetConfig
. hash
);
441 _warn ( "Cached Asset '" + asset
. assetConfig
. path
+ "' has failed checksum. This asset will be uncached for future loading" );
443 // Un cache this asset so it is loaded next time
448 _debug ( "Checksum for Cached Asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
450 Boot
. registerContent ( asset
. assetConfig
. path
, asset
. type
, result
. content
);
451 asset
. updateContent ( result
. content
);
454 _warn ( "There was an error pre-loading the asset '" + asset
. assetConfig
. path
+ "'. This asset will be uncached for future loading" );
456 // Un cache this asset so it is loaded next time
460 if ( Microloader
. remainingCachedAssets
=== 0 ) {
461 Microloader
. onCachedAssetsReady ();
465 onCachedAssetsReady : function (){
467 url
: Microloader
. urls
,
468 loadOrder
: Microloader
. manifest
. loadOrder
,
469 loadOrderMap
: Microloader
. manifest
. loadOrderMap
,
471 success
: Microloader
. onAllAssetsReady
,
472 failure
: Microloader
. onAllAssetsReady
476 onAllAssetsReady : function () {
478 Microloader
. notify ();
480 if ( navigator
. onLine
!== false ) {
482 _debug ( "Application is online, checking for updates" );
484 Microloader
. checkAllUpdates ();
488 _debug ( "Application is offline, adding online listener to check for updates" );
490 if ( window
[ 'addEventListener' ]) {
491 window
. addEventListener ( 'online' , Microloader
. checkAllUpdates
, false );
496 onMicroloaderReady : function ( listener
) {
500 _listeners
. push ( listener
);
507 notify : function () {
509 _debug ( "notifying microloader ready listeners." );
512 while (( listener
= _listeners
. shift ())) {
517 // Delta patches content
518 patch : function ( content
, delta
) {
522 if ( delta
. length
=== 0 ) {
526 for ( i
= 0 , ln
= delta
. length
; i
< ln
; i
++) {
529 if ( typeof chunk
=== 'number' ) {
530 output
. push ( content
. substring ( chunk
, chunk
+ delta
[++ i
]));
537 return output
. join ( '' );
540 checkAllUpdates : function () {
542 _debug ( "Checking for All Updates" );
544 if ( window
[ 'removeEventListener' ]) {
545 window
. removeEventListener ( 'online' , Microloader
. checkAllUpdates
, false );
549 Microloader
. checkForAppCacheUpdate ();
552 // Manifest came from a cached instance, check for updates
553 if ( Microloader
. manifest
. fromCache
) {
554 Microloader
. checkForUpdates ();
558 checkForAppCacheUpdate : function () {
560 _debug ( "Checking App Cache status" );
562 if ( _cache
. status
=== _cache
. UPDATEREADY
|| _cache
. status
=== _cache
. OBSOLETE
) {
564 _debug ( "App Cache is already in an updated" );
566 Microloader
. appCacheState
= 'updated' ;
567 } else if ( _cache
. status
!== _cache
. IDLE
&& _cache
. status
!== _cache
. UNCACHED
) {
569 _debug ( "App Cache is checking or downloading updates, adding listeners" );
571 Microloader
. appCacheState
= 'checking' ;
572 _cache
. addEventListener ( 'error' , Microloader
. onAppCacheError
);
573 _cache
. addEventListener ( 'noupdate' , Microloader
. onAppCacheNotUpdated
);
574 _cache
. addEventListener ( 'cached' , Microloader
. onAppCacheNotUpdated
);
575 _cache
. addEventListener ( 'updateready' , Microloader
. onAppCacheReady
);
576 _cache
. addEventListener ( 'obsolete' , Microloader
. onAppCacheObsolete
);
579 _debug ( "App Cache is current or uncached" );
581 Microloader
. appCacheState
= 'current' ;
585 checkForUpdates : function () {
586 // Fetch the Latest Manifest from the server
588 _debug ( "Checking for updates at: " + Microloader
. manifest
. url
);
590 Boot
. fetch ( Microloader
. applyCacheBuster ( Microloader
. manifest
. url
), Microloader
. onUpdatedManifestLoaded
);
593 onAppCacheError : function ( e
) {
596 Microloader
. appCacheState
= 'error' ;
597 Microloader
. notifyUpdateReady ();
600 onAppCacheReady : function () {
602 Microloader
. appCacheUpdated ();
605 onAppCacheObsolete : function () {
606 Microloader
. appCacheUpdated ();
609 appCacheUpdated : function () {
611 _debug ( "App Cache Updated" );
613 Microloader
. appCacheState
= 'updated' ;
614 Microloader
. notifyUpdateReady ();
617 onAppCacheNotUpdated : function () {
619 _debug ( "App Cache Not Updated Callback" );
621 Microloader
. appCacheState
= 'current' ;
622 Microloader
. notifyUpdateReady ();
626 filterAsset : function ( asset
) {
627 var cfg
= ( asset
&& asset
. assetConfig
) || {};
628 if ( cfg
. platform
|| cfg
. exclude
) {
629 return Boot
. filterPlatform ( cfg
. platform
, cfg
. exclude
);
634 onUpdatedManifestLoaded : function ( result
) {
635 result
= Microloader
. parseResult ( result
);
638 var currentAssets
, newAssets
, currentAsset
, newAsset
, prop
,
639 assets
, deltas
, deltaPath
, include
,
641 manifest
= new Manifest ({
642 url
: Microloader
. manifest
. url
,
643 content
: result
. content
,
647 Microloader
. remainingUpdatingAssets
= 0 ;
648 Microloader
. updatedAssets
= [];
649 Microloader
. removedAssets
= [];
650 Microloader
. updatedManifest
= null ;
651 Microloader
. updatedAssetsReady
= false ;
653 // If the updated manifest has turned off caching we need to clear out all local storage
654 // and trigger a appupdate as all content is now uncached
655 if (! manifest
. shouldCache ()) {
657 _debug ( "New Manifest has caching disabled, clearing out any private storage" );
660 Microloader
. updatedManifest
= manifest
;
661 LocalStorage
. clearAllPrivate ( manifest
);
662 Microloader
. onAllUpdatedAssetsReady ();
666 // Manifest itself has changed
667 if (! Microloader
. manifest
. is ( manifest
)) {
668 Microloader
. updatedManifest
= manifest
;
670 currentAssets
= Microloader
. manifest
. getAssets ();
671 newAssets
= manifest
. getAssets ();
673 // Look through new assets for assets that do not exist or assets that have different versions
674 for ( prop
in newAssets
) {
675 newAsset
= newAssets
[ prop
];
676 currentAsset
= Microloader
. manifest
. getAsset ( newAsset
. assetConfig
. path
);
677 include
= Microloader
. filterAsset ( newAsset
);
679 if ( include
&& (! currentAsset
|| ( newAsset
. shouldCache () && (! currentAsset
. is ( newAsset
))))) {
681 _debug ( "New/Updated Version of Asset: " + newAsset
. assetConfig
. path
+ " was found in new manifest" );
683 updatingAssets
. push ({ _new
: newAsset
, _current
: currentAsset
});
687 // Look through current assets for stale/old assets that have been removed
688 for ( prop
in currentAssets
) {
689 currentAsset
= currentAssets
[ prop
];
690 newAsset
= manifest
. getAsset ( currentAsset
. assetConfig
. path
);
692 //New version of this asset has been filtered out
693 include
= ! Microloader
. filterAsset ( newAsset
);
695 if (! include
|| ! newAsset
|| ( currentAsset
. shouldCache () && ! newAsset
. shouldCache ())) {
697 _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" );
699 Microloader
. removedAssets
. push ( currentAsset
);
703 // Loop through all assets that need updating
704 if ( updatingAssets
. length
> 0 ) {
705 Microloader
. remainingUpdatingAssets
= updatingAssets
. length
;
706 while ( updatingAssets
. length
> 0 ) {
707 assets
= updatingAssets
. pop ();
708 newAsset
= assets
. _new
;
709 currentAsset
= assets
. _current
;
711 // Full Updates will simply download the file and replace its current content
712 if ( newAsset
. assetConfig
. update
=== "full" || ! currentAsset
) {
715 if ( newAsset
. assetConfig
. update
=== "delta" ) {
716 _debug ( "Delta updated asset found without current asset available: " + newAsset
. assetConfig
. path
+ " fetching full file" );
718 _debug ( "Full update found for: " + newAsset
. assetConfig
. path
+ " fetching" );
722 // Load the asset and cache its its content into Boot to be evaluated in sequence
723 Boot
. fetch ( newAsset
. assetConfig
. path
, ( function ( asset
) {
724 return function ( result
) {
725 Microloader
. onFullAssetUpdateLoaded ( asset
, result
)
730 // Delta updates will be given a delta patch
731 } else if ( newAsset
. assetConfig
. update
=== "delta" ) {
732 deltas
= manifest
. deltas
;
733 deltaPath
= deltas
+ "/" + newAsset
. assetConfig
. path
+ "/" + currentAsset
. assetConfig
. hash
+ ".json" ;
734 // Fetch the Delta Patch and update the contents of the asset
736 _debug ( "Delta update found for: " + newAsset
. assetConfig
. path
+ " fetching" );
738 Boot
. fetch ( deltaPath
,
739 ( function ( asset
, oldAsset
) {
740 return function ( result
) {
741 Microloader
. onDeltaAssetUpdateLoaded ( asset
, oldAsset
, result
)
743 }( newAsset
, currentAsset
))
749 _debug ( "No Assets needed updating" );
751 Microloader
. onAllUpdatedAssetsReady ();
755 _debug ( "Manifest files have matching hash's" );
757 Microloader
. onAllUpdatedAssetsReady ();
760 _warn ( "Error loading manifest file to check for updates" );
761 Microloader
. onAllUpdatedAssetsReady ();
765 onFullAssetUpdateLoaded : function ( asset
, result
) {
767 result
= Microloader
. parseResult ( result
);
768 Microloader
. remainingUpdatingAssets
--;
771 checksum
= Microloader
. checksum ( result
. content
, asset
. assetConfig
. hash
);
773 _debug ( "Checksum for Full asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
777 _debug ( "Full Update Asset: " + asset
. assetConfig
. path
+ " has failed checksum. This asset will be uncached for future loading" );
780 // uncache this asset as there is a new version somewhere that has not been loaded.
783 asset
. updateContent ( result
. content
);
784 Microloader
. updatedAssets
. push ( asset
);
788 _debug ( "Error loading file at" + asset
. assetConfig
. path
+ ". This asset will be uncached for future loading" );
791 // uncache this asset as there is a new version somewhere that has not been loaded.
795 if ( Microloader
. remainingUpdatingAssets
=== 0 ) {
796 Microloader
. onAllUpdatedAssetsReady ();
800 onDeltaAssetUpdateLoaded : function ( asset
, oldAsset
, result
) {
801 var json
, checksum
, content
;
802 result
= Microloader
. parseResult ( result
);
803 Microloader
. remainingUpdatingAssets
--;
807 _debug ( "Delta patch loaded successfully, patching content" );
810 json
= JSON
. parse ( result
. content
);
811 content
= Microloader
. patch ( oldAsset
. content
, json
);
812 checksum
= Microloader
. checksum ( content
, asset
. assetConfig
. hash
);
814 _debug ( "Checksum for Delta Patched asset: " + asset
. assetConfig
. path
+ " is " + checksum
);
818 _debug ( "Delta Update Asset: " + asset
. assetConfig
. path
+ " has failed checksum. This asset will be uncached for future loading" );
821 // uncache this asset as there is a new version somewhere that has not been loaded.
824 asset
. updateContent ( content
);
825 Microloader
. updatedAssets
. push ( asset
);
828 _warn ( "Error parsing delta patch for " + asset
. assetConfig
. path
+ " with hash " + oldAsset
. assetConfig
. hash
+ " . This asset will be uncached for future loading" );
829 // uncache this asset as there is a new version somewhere that has not been loaded.
833 _warn ( "Error loading delta patch for " + asset
. assetConfig
. path
+ " with hash " + oldAsset
. assetConfig
. hash
+ " . This asset will be uncached for future loading" );
835 // uncache this asset as there is a new version somewhere that has not been loaded.
838 if ( Microloader
. remainingUpdatingAssets
=== 0 ) {
839 Microloader
. onAllUpdatedAssetsReady ();
843 //TODO: Make this all transaction based to allow for reverting if quota is exceeded
844 onAllUpdatedAssetsReady : function () {
846 Microloader
. updatedAssetsReady
= true ;
848 if ( Microloader
. updatedManifest
) {
849 while ( Microloader
. removedAssets
. length
> 0 ) {
850 asset
= Microloader
. removedAssets
. pop ();
852 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was removed, un-caching" );
857 if ( Microloader
. updatedManifest
) {
859 _debug ( "Manifest was updated, re-caching" );
861 Microloader
. updatedManifest
. cache ();
864 while ( Microloader
. updatedAssets
. length
> 0 ) {
865 asset
= Microloader
. updatedAssets
. pop ();
867 _debug ( "Asset: " + asset
. assetConfig
. path
+ " was updated, re-caching" );
874 Microloader
. notifyUpdateReady ();
877 notifyUpdateReady : function () {
878 if ( Microloader
. appCacheState
!== 'checking' && Microloader
. updatedAssetsReady
) {
879 if ( Microloader
. appCacheState
=== 'updated' || Microloader
. updatedManifest
) {
881 _debug ( "There was an update here you will want to reload the app, trigger an event" );
883 Microloader
. appUpdate
= {
885 app
: Microloader
. appCacheState
=== 'updated' ,
886 manifest
: Microloader
. updatedManifest
&& Microloader
. updatedManifest
. exportContent ()
889 Microloader
. fireAppUpdate ();
893 _debug ( "AppCache and LocalStorage Cache are current, no updating needed" );
894 Microloader
. appUpdate
= {};
900 fireAppUpdate : function () {
901 if ( Ext
. GlobalEvents
) {
902 // We defer dispatching this event slightly in order to let the application finish loading
903 // as we are still very early in the lifecycle
904 Ext
. defer ( function () {
905 Ext
. GlobalEvents
. fireEvent ( 'appupdate' , Microloader
. appUpdate
);
910 checksum : function ( content
, hash
) {
911 if (! content
|| ! hash
) {
916 hashLn
= hash
. length
,
917 checksumType
= content
. substring ( 0 , 1 );
919 if ( checksumType
== '/' ) {
920 if ( content
. substring ( 2 , hashLn
+ 2 ) !== hash
) {
923 } else if ( checksumType
== 'f' ) {
924 if ( content
. substring ( 10 , hashLn
+ 10 ) !== hash
) {
927 } else if ( checksumType
== '.' ) {
928 if ( content
. substring ( 1 , hashLn
+ 1 ) !== hash
) {
934 parseResult : function ( result
) {
936 if (( result
. exception
|| result
. status
=== 0 ) && ! Boot
. env
. phantom
) {
938 } else if (( result
. status
>= 200 && result
. status
< 300 ) || result
. status
=== 304
940 || ( result
. status
=== 0 && result
. content
. length
> 0 )
942 rst
. content
= result
. content
;
954 * @type {String/Object}
956 Ext
. manifest
= Ext
. manifest
|| "bootstrap" ;
958 Ext
. Microloader
. run ();