@@ -57,7 +57,7 @@ this.createjs = this.createjs || {};
5757 * @type String
5858 * @static
5959 **/
60- s . buildDate = /*=date*/ "Thu, 29 Oct 2015 03:02:56 GMT" ; // injected by build process
60+ s . buildDate = /*=date*/ "Wed, 25 Nov 2015 19:26:51 GMT" ; // injected by build process
6161
6262} ) ( ) ;
6363
@@ -78,7 +78,7 @@ this.createjs = this.createjs||{};
7878 *
7979 * function MySubClass() {}
8080 * createjs.extend(MySubClass, MySuperClass);
81- * ClassB .prototype.doSomething = function() { }
81+ * MySubClass .prototype.doSomething = function() { }
8282 *
8383 * var foo = new MySubClass();
8484 * console.log(foo instanceof MySuperClass); // true
@@ -346,7 +346,12 @@ this.createjs = this.createjs||{};
346346 * console.log(instance == this); // true, "on" uses dispatcher scope by default.
347347 * });
348348 *
349- * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage scope.
349+ * If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage
350+ * scope.
351+ *
352+ * <b>Browser support</b>
353+ * The event model in CreateJS can be used separately from the suite in any project, however the inheritance model
354+ * requires modern browsers (IE9+).
350355 *
351356 *
352357 * @class EventDispatcher
@@ -449,7 +454,11 @@ this.createjs = this.createjs||{};
449454 * only run once, associate arbitrary data with the listener, and remove the listener.
450455 *
451456 * This method works by creating an anonymous wrapper function and subscribing it with addEventListener.
452- * The created anonymous function is returned for use with .removeEventListener (or .off).
457+ * The wrapper function is returned for use with `removeEventListener` (or `off`).
458+ *
459+ * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener, or use
460+ * {{#crossLink "Event/remove"}}{{/crossLink}}. Likewise, each time you call `on` a NEW wrapper function is subscribed, so multiple calls
461+ * to `on` with the same params will create multiple listeners.
453462 *
454463 * <h4>Example</h4>
455464 *
@@ -519,6 +528,9 @@ this.createjs = this.createjs||{};
519528 /**
520529 * A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the
521530 * .on method.
531+ *
532+ * <b>IMPORTANT:</b> To remove a listener added with `on`, you must pass in the returned wrapper function as the listener. See
533+ * {{#crossLink "EventDispatcher/on"}}{{/crossLink}} for an example.
522534 *
523535 * @method off
524536 * @param {String } type The string type of the event.
@@ -564,19 +576,24 @@ this.createjs = this.createjs||{};
564576 * @method dispatchEvent
565577 * @param {Object | String | Event } eventObj An object with a "type" property, or a string type.
566578 * While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,
567- * dispatchEvent will construct an Event instance with the specified type.
568- * @return {Boolean } Returns the value of eventObj.defaultPrevented.
579+ * dispatchEvent will construct an Event instance if necessary with the specified type. This latter approach can
580+ * be used to avoid event object instantiation for non-bubbling events that may not have any listeners.
581+ * @param {Boolean } [bubbles] Specifies the `bubbles` value when a string was passed to eventObj.
582+ * @param {Boolean } [cancelable] Specifies the `cancelable` value when a string was passed to eventObj.
583+ * @return {Boolean } Returns false if `preventDefault()` was called on a cancelable event, true otherwise.
569584 **/
570- p . dispatchEvent = function ( eventObj ) {
585+ p . dispatchEvent = function ( eventObj , bubbles , cancelable ) {
571586 if ( typeof eventObj == "string" ) {
572- // won't bubble, so skip everything if there's no listeners:
587+ // skip everything if there's no listeners and it doesn't bubble :
573588 var listeners = this . _listeners ;
574- if ( ! listeners || ! listeners [ eventObj ] ) { return false ; }
575- eventObj = new createjs . Event ( eventObj ) ;
589+ if ( ! bubbles && ( ! listeners || ! listeners [ eventObj ] ) ) { return true ; }
590+ eventObj = new createjs . Event ( eventObj , bubbles , cancelable ) ;
576591 } else if ( eventObj . target && eventObj . clone ) {
577592 // redispatching an active event object, so clone it:
578593 eventObj = eventObj . clone ( ) ;
579594 }
595+
596+ // TODO: it would be nice to eliminate this. Maybe in favour of evtObj instanceof Event? Or !!evtObj.createEvent
580597 try { eventObj . target = this ; } catch ( e ) { } // try/catch allows redispatching of native events
581598
582599 if ( ! eventObj . bubbles || ! this . parent ) {
@@ -595,7 +612,7 @@ this.createjs = this.createjs||{};
595612 list [ i ] . _dispatchEvent ( eventObj , 3 ) ;
596613 }
597614 }
598- return eventObj . defaultPrevented ;
615+ return ! eventObj . defaultPrevented ;
599616 } ;
600617
601618 /**
@@ -820,11 +837,11 @@ this.createjs = this.createjs||{};
820837 */
821838 // p.initialize = function() {}; // searchable for devs wondering where it is.
822839
823-
824840// public methods:
825841 /**
826- * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true.
827- * Mirrors the DOM event standard.
842+ * Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true if the event is cancelable.
843+ * Mirrors the DOM level 2 event standard. In general, cancelable events that have `preventDefault()` called will
844+ * cancel the default behaviour associated with the event.
828845 * @method preventDefault
829846 **/
830847 p . preventDefault = function ( ) {
@@ -1022,7 +1039,7 @@ this.createjs = this.createjs || {};
10221039
10231040 /**
10241041 * All loaders accept an item containing the properties defined in this class. If a raw object is passed instead,
1025- * it will not be affected, but it must contain at least a {{#crossLink "LoadItem/ src:property"}}{{/crossLink}} property. A
1042+ * it will not be affected, but it must contain at least a {{#crossLink "src:property"}}{{/crossLink}} property. A
10261043 * string path or HTML tag is also acceptable, but it will be automatically converted to a LoadItem using the
10271044 * {{#crossLink "create"}}{{/crossLink}} method by {{#crossLink "AbstractLoader"}}{{/crossLink}}
10281045 * @class LoadItem
@@ -1548,6 +1565,7 @@ this.createjs = this.createjs || {};
15481565 * @property canceled
15491566 * @type {Boolean }
15501567 * @default false
1568+ * @readonly
15511569 */
15521570 this . canceled = false ;
15531571
@@ -1582,7 +1600,18 @@ this.createjs = this.createjs || {};
15821600 * can be overridden to provide custom formatting.
15831601 *
15841602 * Optionally, a resultFormatter can return a callback function in cases where the formatting needs to be
1585- * asynchronous, such as creating a new image.
1603+ * asynchronous, such as creating a new image. The callback function is passed 2 parameters, which are callbacks
1604+ * to handle success and error conditions in the resultFormatter. Note that the resultFormatter method is
1605+ * called in the current scope, as well as the success and error callbacks.
1606+ *
1607+ * <h4>Example asynchronous resultFormatter</h4>
1608+ *
1609+ * function _formatResult(loader) {
1610+ * return function(success, error) {
1611+ * if (errorCondition) { error(errorDetailEvent); }
1612+ * success(result);
1613+ * }
1614+ * }
15861615 * @property resultFormatter
15871616 * @type {Function }
15881617 * @default null
@@ -2136,7 +2165,7 @@ this.createjs = this.createjs || {};
21362165 * @return {Object } The formatted result
21372166 * @since 0.6.0
21382167 */
2139- p . resultFormatter = null ; //TODO: Add support for async formatting.
2168+ p . resultFormatter = null ;
21402169
21412170 /**
21422171 * Handle events from internal requests. By default, loaders will handle, and redispatch the necessary events, but
@@ -2151,12 +2180,11 @@ this.createjs = this.createjs || {};
21512180 case "complete" :
21522181 this . _rawResult = event . target . _response ;
21532182 var result = this . resultFormatter && this . resultFormatter ( this ) ;
2154- var _this = this ;
21552183 if ( result instanceof Function ) {
2156- result ( function ( result ) {
2157- _this . _result = result ;
2158- _this . _sendComplete ( ) ;
2159- } ) ;
2184+ result . call ( this ,
2185+ createjs . proxy ( this . _resultFormatSuccess , this ) ,
2186+ createjs . proxy ( this . _resultFormatFailed , this )
2187+ ) ;
21602188 } else {
21612189 this . _result = result || this . _rawResult ;
21622190 this . _sendComplete ( ) ;
@@ -2174,12 +2202,35 @@ this.createjs = this.createjs || {};
21742202 case "abort" :
21752203 case "timeout" :
21762204 if ( ! this . _isCanceled ( ) ) {
2177- this . dispatchEvent ( event . type ) ;
2205+ this . dispatchEvent ( new createjs . ErrorEvent ( "PRELOAD_" + event . type . toUpperCase ( ) + "_ERROR" ) ) ;
21782206 }
21792207 break ;
21802208 }
21812209 } ;
21822210
2211+ /**
2212+ * The "success" callback passed to {{#crossLink "AbstractLoader/resultFormatter"}}{{/crossLink}} asynchronous
2213+ * functions.
2214+ * @method _resultFormatSuccess
2215+ * @param {Object } result The formatted result
2216+ * @private
2217+ */
2218+ p . _resultFormatSuccess = function ( result ) {
2219+ this . _result = result ;
2220+ this . _sendComplete ( ) ;
2221+ } ;
2222+
2223+ /**
2224+ * The "error" callback passed to {{#crossLink "AbstractLoader/resultFormatter"}}{{/crossLink}} asynchronous
2225+ * functions.
2226+ * @method _resultFormatSuccess
2227+ * @param {Object } error The error event
2228+ * @private
2229+ */
2230+ p . _resultFormatFailed = function ( event ) {
2231+ this . _sendError ( event ) ;
2232+ } ;
2233+
21832234 /**
21842235 * @method buildPath
21852236 * @protected
@@ -2230,6 +2281,8 @@ this.createjs = this.createjs || {};
22302281
22312282 // protected properties
22322283 this . _tagSrcAttribute = "src" ;
2284+
2285+ this . on ( "initialize" , this . _updateXHR , this ) ;
22332286 } ;
22342287
22352288 var p = createjs . extend ( AbstractMediaLoader , createjs . AbstractLoader ) ;
@@ -2265,6 +2318,20 @@ this.createjs = this.createjs || {};
22652318 }
22662319 } ;
22672320
2321+ // protected methods
2322+ /**
2323+ * Before the item loads, set its mimeType and responseType.
2324+ * @property _updateXHR
2325+ * @param {Event } event
2326+ * @private
2327+ */
2328+ p . _updateXHR = function ( event ) {
2329+ // Only exists for XHR
2330+ if ( event . loader . setResponseType ) {
2331+ event . loader . setResponseType ( "blob" ) ;
2332+ }
2333+ } ;
2334+
22682335 /**
22692336 * The result formatter for media files.
22702337 * @method _formatResult
@@ -2276,7 +2343,10 @@ this.createjs = this.createjs || {};
22762343 this . _tag . removeEventListener && this . _tag . removeEventListener ( "canplaythrough" , this . _loadedHandler ) ;
22772344 this . _tag . onstalled = null ;
22782345 if ( this . _preferXHR ) {
2279- loader . getTag ( ) . src = loader . getResult ( true ) ;
2346+ var URL = window . URL || window . webkitURL ;
2347+ var result = loader . getResult ( true ) ;
2348+
2349+ loader . getTag ( ) . src = URL . createObjectURL ( result ) ;
22802350 }
22812351 return loader . getTag ( ) ;
22822352 } ;
@@ -2632,7 +2702,7 @@ this.createjs = this.createjs || {};
26322702 * for an overview of supported file properties.
26332703 * @extends AbstractLoader
26342704 */
2635- function XHRRequest ( item ) {
2705+ function XHRRequest ( item ) {
26362706 this . AbstractRequest_constructor ( item ) ;
26372707
26382708 // protected properties
@@ -2759,15 +2829,28 @@ this.createjs = this.createjs || {};
27592829 }
27602830
27612831 //Events
2762- this . _request . addEventListener ( "loadstart" , this . _handleLoadStartProxy , false ) ;
2763- this . _request . addEventListener ( "progress" , this . _handleProgressProxy , false ) ;
2764- this . _request . addEventListener ( "abort" , this . _handleAbortProxy , false ) ;
2765- this . _request . addEventListener ( "error" , this . _handleErrorProxy , false ) ;
2766- this . _request . addEventListener ( "timeout" , this . _handleTimeoutProxy , false ) ;
2832+ if ( this . _request . addEventListener != null ) {
2833+ this . _request . addEventListener ( "loadstart" , this . _handleLoadStartProxy , false ) ;
2834+ this . _request . addEventListener ( "progress" , this . _handleProgressProxy , false ) ;
2835+ this . _request . addEventListener ( "abort" , this . _handleAbortProxy , false ) ;
2836+ this . _request . addEventListener ( "error" , this . _handleErrorProxy , false ) ;
2837+ this . _request . addEventListener ( "timeout" , this . _handleTimeoutProxy , false ) ;
2838+
2839+ // Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these.
2840+ this . _request . addEventListener ( "load" , this . _handleLoadProxy , false ) ;
2841+ this . _request . addEventListener ( "readystatechange" , this . _handleReadyStateChangeProxy , false ) ;
2842+ } else {
2843+ // IE9 support
2844+ this . _request . onloadstart = this . _handleLoadStartProxy ;
2845+ this . _request . onprogress = this . _handleProgressProxy ;
2846+ this . _request . onabort = this . _handleAbortProxy ;
2847+ this . _request . onerror = this . _handleErrorProxy ;
2848+ this . _request . ontimeout = this . _handleTimeoutProxy ;
27672849
2768- // Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these.
2769- this . _request . addEventListener ( "load" , this . _handleLoadProxy , false ) ;
2770- this . _request . addEventListener ( "readystatechange" , this . _handleReadyStateChangeProxy , false ) ;
2850+ // Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these.
2851+ this . _request . onload = this . _handleLoadProxy ;
2852+ this . _request . onreadystatechange = this . _handleReadyStateChangeProxy ;
2853+ }
27712854
27722855 // Set up a timeout if we don't have XHR2
27732856 if ( this . _xhrLevel == 1 ) {
@@ -2787,6 +2870,11 @@ this.createjs = this.createjs || {};
27872870 } ;
27882871
27892872 p . setResponseType = function ( type ) {
2873+ // Some old browsers doesn't support blob, so we convert arraybuffer to blob after response is downloaded
2874+ if ( type === 'blob' ) {
2875+ type = window . URL ? 'blob' : 'arraybuffer' ;
2876+ this . _responseType = type ;
2877+ }
27902878 this . _request . responseType = type ;
27912879 } ;
27922880
@@ -2909,6 +2997,21 @@ this.createjs = this.createjs || {};
29092997 }
29102998
29112999 this . _response = this . _getResponse ( ) ;
3000+ // Convert arraybuffer back to blob
3001+ if ( this . _responseType === 'arraybuffer' ) {
3002+ try {
3003+ this . _response = new Blob ( [ this . _response ] ) ;
3004+ } catch ( e ) {
3005+ // Fallback to use BlobBuilder if Blob constructor is not supported
3006+ // Tested on Android 2.3 ~ 4.2 and iOS5 safari
3007+ window . BlobBuilder = window . BlobBuilder || window . WebKitBlobBuilder || window . MozBlobBuilder || window . MSBlobBuilder ;
3008+ if ( e . name === 'TypeError' && window . BlobBuilder ) {
3009+ var builder = new BlobBuilder ( ) ;
3010+ builder . append ( this . _response ) ;
3011+ this . _response = builder . getBlob ( ) ;
3012+ }
3013+ }
3014+ }
29123015 this . _clean ( ) ;
29133016
29143017 this . dispatchEvent ( new createjs . Event ( "complete" ) ) ;
@@ -3011,11 +3114,14 @@ this.createjs = this.createjs || {};
30113114 for ( var i = 0 , l = s . ACTIVEX_VERSIONS . length ; i < l ; i ++ ) {
30123115 var axVersion = s . ACTIVEX_VERSIONS [ i ] ;
30133116 try {
3014- req = new ActiveXObject ( axVersions ) ;
3117+ req = new ActiveXObject ( axVersion ) ;
30153118 break ;
3016- } catch ( e ) { }
3119+ } catch ( e ) {
3120+ }
3121+ }
3122+ if ( req == null ) {
3123+ return false ;
30173124 }
3018- if ( req == null ) { return false ; }
30193125 }
30203126
30213127 // Default to utf-8 for Text requests.
@@ -3081,13 +3187,23 @@ this.createjs = this.createjs || {};
30813187 p . _clean = function ( ) {
30823188 clearTimeout ( this . _loadTimeout ) ;
30833189
3084- this . _request . removeEventListener ( "loadstart" , this . _handleLoadStartProxy ) ;
3085- this . _request . removeEventListener ( "progress" , this . _handleProgressProxy ) ;
3086- this . _request . removeEventListener ( "abort" , this . _handleAbortProxy ) ;
3087- this . _request . removeEventListener ( "error" , this . _handleErrorProxy ) ;
3088- this . _request . removeEventListener ( "timeout" , this . _handleTimeoutProxy ) ;
3089- this . _request . removeEventListener ( "load" , this . _handleLoadProxy ) ;
3090- this . _request . removeEventListener ( "readystatechange" , this . _handleReadyStateChangeProxy ) ;
3190+ if ( this . _request . removeEventListener != null ) {
3191+ this . _request . removeEventListener ( "loadstart" , this . _handleLoadStartProxy ) ;
3192+ this . _request . removeEventListener ( "progress" , this . _handleProgressProxy ) ;
3193+ this . _request . removeEventListener ( "abort" , this . _handleAbortProxy ) ;
3194+ this . _request . removeEventListener ( "error" , this . _handleErrorProxy ) ;
3195+ this . _request . removeEventListener ( "timeout" , this . _handleTimeoutProxy ) ;
3196+ this . _request . removeEventListener ( "load" , this . _handleLoadProxy ) ;
3197+ this . _request . removeEventListener ( "readystatechange" , this . _handleReadyStateChangeProxy ) ;
3198+ } else {
3199+ this . _request . onloadstart = null ;
3200+ this . _request . onprogress = null ;
3201+ this . _request . onabort = null ;
3202+ this . _request . onerror = null ;
3203+ this . _request . ontimeout = null ;
3204+ this . _request . onload = null ;
3205+ this . _request . onreadystatechange = null ;
3206+ }
30913207 } ;
30923208
30933209 p . toString = function ( ) {
0 commit comments