Skip to content

Commit 007f52e

Browse files
author
Lanny McNie
committed
Merge branch 'master' into GMC_0.6.2
2 parents f4e49cc + 39e50b9 commit 007f52e

File tree

11 files changed

+321
-88
lines changed

11 files changed

+321
-88
lines changed

VERSIONS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CRITICAL
1010
- documentation updates
1111
- added a reuseable scratch buffer, instead of recreating each time (thanks @konistehrad)
1212
- added automatic "playEmptySound" support on iOS to unlock the WebAudio context
13+
- bug fixes
1314

1415

1516
Version 0.6.1-HOTFIX [October 8, 2015]

docs/soundjs_docs-NEXT.zip

4.28 KB
Binary file not shown.

lib/soundjs-NEXT.combined.js

Lines changed: 159 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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 () {

lib/soundjs-NEXT.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)