mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-15 16:06:41 +03:00
Simplify FakeEvent and FakeEventTarget
We now avoid tricky things like CustomEvent and setting properties on native Events. This gives us better cross-browser compatibility and less complexity. Change-Id: Idc9fcc69c33257e4540d956bcbc949de6d992cf0
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
# Polyfills used to emulate missing browsers features.
|
||||
|
||||
+../../lib/polyfill/customevent.js
|
||||
+../../lib/polyfill/fullscreen.js
|
||||
+../../lib/polyfill/mediakeys.js
|
||||
+../../lib/polyfill/patchedmediakeys_20140218.js
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
goog.provide('shaka.polyfill.CustomEvent');
|
||||
|
||||
goog.require('shaka.polyfill.register');
|
||||
|
||||
|
||||
/**
|
||||
* @namespace shaka.polyfill.CustomEvent
|
||||
* @exportDoc
|
||||
*
|
||||
* @summary A polyfill to implement the CustomEvent constructor on browsers
|
||||
* which don't have one or don't allow its direct use.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Install the polyfill if needed.
|
||||
*/
|
||||
shaka.polyfill.CustomEvent.install = function() {
|
||||
var present = 'CustomEvent' in window;
|
||||
|
||||
if (present) {
|
||||
try {
|
||||
new CustomEvent('');
|
||||
} catch (exception) {
|
||||
present = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!present) {
|
||||
window['CustomEvent'] = shaka.polyfill.CustomEvent.ctor_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @this {CustomEvent}
|
||||
* @constructor
|
||||
* @param {string} type
|
||||
* @param {CustomEventInit=} opt_init
|
||||
* @private
|
||||
*/
|
||||
shaka.polyfill.CustomEvent.ctor_ = function(type, opt_init) {
|
||||
var event = /** @type {!CustomEvent} */(document.createEvent('CustomEvent'));
|
||||
var init = opt_init || { bubbles: false, cancelable: false, detail: null };
|
||||
event.initCustomEvent(type, !!init.bubbles, !!init.cancelable, init.detail);
|
||||
return event;
|
||||
};
|
||||
|
||||
|
||||
shaka.polyfill.register(shaka.polyfill.CustomEvent.install);
|
||||
@@ -369,7 +369,7 @@ shaka.polyfill.PatchedMediaKeys.v20140218.MediaKeys.prototype.
|
||||
shaka.polyfill.PatchedMediaKeys.v20140218.
|
||||
MediaKeySession = function(nativeMediaKeys, sessionType) {
|
||||
shaka.log.debug('v20140218.MediaKeySession');
|
||||
shaka.util.FakeEventTarget.call(this, null);
|
||||
shaka.util.FakeEventTarget.call(this);
|
||||
|
||||
// Native MediaKeySession, which will be created in generateRequest
|
||||
/** @private {MSMediaKeySession} */
|
||||
@@ -520,8 +520,7 @@ shaka.polyfill.PatchedMediaKeys.v20140218.onMsNeedKey_ = function(event) {
|
||||
// Alias
|
||||
var v20140218 = shaka.polyfill.PatchedMediaKeys.v20140218;
|
||||
|
||||
var event2 = shaka.util.FakeEvent.create({
|
||||
type: 'encrypted',
|
||||
var event2 = new shaka.util.FakeEvent('encrypted', {
|
||||
initDataType: 'cenc',
|
||||
initData: v20140218.NormaliseInitData_(event.initData)
|
||||
});
|
||||
@@ -615,8 +614,7 @@ shaka.polyfill.PatchedMediaKeys.v20140218.MediaKeySession.prototype.
|
||||
|
||||
var isNew = this.keyStatuses.getStatus() == undefined;
|
||||
|
||||
var event2 = shaka.util.FakeEvent.create({
|
||||
type: 'message',
|
||||
var event2 = new shaka.util.FakeEvent('message', {
|
||||
messageType: isNew ? 'licenserequest' : 'licenserenewal',
|
||||
message: event.message.buffer
|
||||
});
|
||||
@@ -711,7 +709,7 @@ shaka.polyfill.PatchedMediaKeys.v20140218.MediaKeySession.prototype.
|
||||
shaka.polyfill.PatchedMediaKeys.v20140218.MediaKeySession.prototype.
|
||||
updateKeyStatus_ = function(status) {
|
||||
this.keyStatuses.setStatus(status);
|
||||
var event = shaka.util.FakeEvent.create({type: 'keystatuseschange'});
|
||||
var event = new shaka.util.FakeEvent('keystatuseschange');
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
|
||||
@@ -404,8 +404,7 @@ shaka.polyfill.PatchedMediaKeys.v01b.MediaKeys.prototype.onWebkitNeedKey_ =
|
||||
shaka.log.debug('v01b.onWebkitNeedKey_', event);
|
||||
shaka.asserts.assert(this.media_, 'media_ not set in onWebkitNeedKey_');
|
||||
|
||||
var event2 = shaka.util.FakeEvent.create({
|
||||
type: 'encrypted',
|
||||
var event2 = new shaka.util.FakeEvent('encrypted', {
|
||||
initDataType: 'webm', // not used by v0.1b EME, but given a valid value
|
||||
initData: event.initData
|
||||
});
|
||||
@@ -430,8 +429,7 @@ shaka.polyfill.PatchedMediaKeys.v01b.MediaKeys.prototype.onWebkitKeyMessage_ =
|
||||
|
||||
var isNew = session.keyStatuses.getStatus() == undefined;
|
||||
|
||||
var event2 = shaka.util.FakeEvent.create({
|
||||
type: 'message',
|
||||
var event2 = new shaka.util.FakeEvent('message', {
|
||||
messageType: isNew ? 'licenserequest' : 'licenserenewal',
|
||||
message: event.message
|
||||
});
|
||||
@@ -514,7 +512,7 @@ shaka.polyfill.PatchedMediaKeys.v01b.MediaKeys.prototype.findSession_ =
|
||||
shaka.polyfill.PatchedMediaKeys.v01b.MediaKeySession =
|
||||
function(media, keySystem, sessionType) {
|
||||
shaka.log.debug('v01b.MediaKeySession');
|
||||
shaka.util.FakeEventTarget.call(this, null);
|
||||
shaka.util.FakeEventTarget.call(this);
|
||||
|
||||
/** @private {!HTMLMediaElement} */
|
||||
this.media_ = media;
|
||||
@@ -788,7 +786,7 @@ shaka.polyfill.PatchedMediaKeys.v01b.MediaKeySession.prototype.update_ =
|
||||
shaka.polyfill.PatchedMediaKeys.v01b.MediaKeySession.prototype.
|
||||
updateKeyStatus_ = function(status) {
|
||||
this.keyStatuses.setStatus(status);
|
||||
var event = shaka.util.FakeEvent.create({type: 'keystatuseschange'});
|
||||
var event = new shaka.util.FakeEvent('keystatuseschange');
|
||||
this.dispatchEvent(event);
|
||||
};
|
||||
|
||||
|
||||
+74
-24
@@ -17,35 +17,85 @@
|
||||
|
||||
goog.provide('shaka.util.FakeEvent');
|
||||
|
||||
goog.require('shaka.asserts');
|
||||
|
||||
|
||||
/**
|
||||
* @namespace shaka.util.FakeEvent
|
||||
* @summary A utility to simplify the creation of fake events.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Return an Event object based on the dictionary.
|
||||
* Create an Event work-alike object based on the dictionary.
|
||||
* The event should contain all of the same properties from the dict.
|
||||
* @param {!Object} dict
|
||||
* @return {!Event}
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {Object=} opt_dict
|
||||
* @constructor
|
||||
* @extends {Event}
|
||||
*/
|
||||
shaka.util.FakeEvent.create = function(dict) {
|
||||
var event = new CustomEvent(dict.type, {
|
||||
detail: dict.detail,
|
||||
bubbles: !!dict.bubbles
|
||||
});
|
||||
// NOTE: In strict mode, we can't overwrite existing properties, so we only
|
||||
// set properties on "event" which don't exist yet. If a property does exist
|
||||
// on "event", we assert that it has the correct value already.
|
||||
shaka.util.FakeEvent = function(type, opt_dict) {
|
||||
// Take properties from dict if present.
|
||||
var dict = opt_dict || {};
|
||||
for (var key in dict) {
|
||||
if (key in event) {
|
||||
shaka.asserts.assert(event[key] == dict[key], 'key = ' + key);
|
||||
} else {
|
||||
event[key] = dict[key];
|
||||
}
|
||||
this[key] = dict[key];
|
||||
}
|
||||
return event;
|
||||
|
||||
|
||||
// These Properties below cannot be set by dict. They are all provided for
|
||||
// compatibility with native events.
|
||||
|
||||
/** @const {boolean} */
|
||||
this.bubbles = false;
|
||||
|
||||
/** @const {boolean} */
|
||||
this.cancelable = false;
|
||||
|
||||
/** @const {boolean} */
|
||||
this.defaultPrevented = false;
|
||||
|
||||
/**
|
||||
* According to MDN, Chrome uses high-res timers instead of epoch time.
|
||||
* Follow suit so that timeStamps on FakeEvents use the same base as
|
||||
* on native Events.
|
||||
* @const {number}
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp
|
||||
*/
|
||||
this.timeStamp = window.performance ? window.performance.now() : Date.now();
|
||||
|
||||
/** @const {string} */
|
||||
this.type = type;
|
||||
|
||||
/** @const {boolean} */
|
||||
this.isTrusted = false;
|
||||
|
||||
/** @type {EventTarget} */
|
||||
this.currentTarget = null;
|
||||
|
||||
/** @type {EventTarget} */
|
||||
this.target = null;
|
||||
|
||||
|
||||
/**
|
||||
* Non-standard property read by FakeEventTarget to stop processing listeners.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.stopped = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Does nothing, since FakeEvents have no default. Provided for compatibility
|
||||
* with native Events.
|
||||
*/
|
||||
shaka.util.FakeEvent.prototype.preventDefault = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Stops processing event listeners for this event. Provided for compatibility
|
||||
* with native Events.
|
||||
*/
|
||||
shaka.util.FakeEvent.prototype.stopImmediatePropagation = function() {
|
||||
this.stopped = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Does nothing, since FakeEvents do not bubble. Provided for compatibility
|
||||
* with native Events.
|
||||
*/
|
||||
shaka.util.FakeEvent.prototype.stopPropagation = function() {};
|
||||
|
||||
@@ -19,6 +19,7 @@ goog.provide('shaka.util.FakeEventTarget');
|
||||
|
||||
goog.require('shaka.asserts');
|
||||
goog.require('shaka.log');
|
||||
goog.require('shaka.util.FakeEvent');
|
||||
goog.require('shaka.util.MultiMap');
|
||||
|
||||
|
||||
@@ -26,23 +27,17 @@ goog.require('shaka.util.MultiMap');
|
||||
/**
|
||||
* A work-alike for EventTarget. Only DOM elements may be true EventTargets,
|
||||
* but this can be used as a base class to provide event dispatch to non-DOM
|
||||
* classes.
|
||||
* classes. Only FakeEvents should be dispatched.
|
||||
*
|
||||
* @param {shaka.util.FakeEventTarget} parent The parent for the purposes of
|
||||
* event bubbling. Note that events on a FakeEventTarget can only bubble
|
||||
* to other FakeEventTargets.
|
||||
* @struct
|
||||
* @constructor
|
||||
* @implements {EventTarget}
|
||||
*/
|
||||
shaka.util.FakeEventTarget = function(parent) {
|
||||
shaka.util.FakeEventTarget = function() {
|
||||
/**
|
||||
* @private {!shaka.util.MultiMap.<shaka.util.FakeEventTarget.ListenerType>}
|
||||
*/
|
||||
this.listeners_ = new shaka.util.MultiMap();
|
||||
|
||||
/** @protected {shaka.util.FakeEventTarget} */
|
||||
this.parent = parent;
|
||||
};
|
||||
|
||||
|
||||
@@ -59,18 +54,13 @@ shaka.util.FakeEventTarget.ListenerType;
|
||||
* @param {string} type The event type to listen for.
|
||||
* @param {shaka.util.FakeEventTarget.ListenerType} listener The callback or
|
||||
* listener object to invoke.
|
||||
* @param {boolean=} opt_capturing True to listen during the capturing phase,
|
||||
* false to listen during the bubbling phase. Note that FakeEventTarget
|
||||
* does not support the capturing phase from the standard event model.
|
||||
* @param {boolean=} opt_capturing Ignored. FakeEventTargets do not have
|
||||
* parents, so events neither capture nor bubble.
|
||||
* @override
|
||||
*/
|
||||
shaka.util.FakeEventTarget.prototype.addEventListener =
|
||||
function(type, listener, opt_capturing) {
|
||||
// We don't support the capturing phase.
|
||||
shaka.asserts.assert(!opt_capturing, 'Capturing phase unsupported');
|
||||
if (!opt_capturing) {
|
||||
this.listeners_.push(type, listener);
|
||||
}
|
||||
this.listeners_.push(type, listener);
|
||||
};
|
||||
|
||||
|
||||
@@ -80,19 +70,13 @@ shaka.util.FakeEventTarget.prototype.addEventListener =
|
||||
* @param {string} type The event type for which you wish to remove a listener.
|
||||
* @param {shaka.util.FakeEventTarget.ListenerType} listener The callback or
|
||||
* listener object to remove.
|
||||
* @param {boolean=} opt_capturing True to remove a listener for the capturing
|
||||
* phase, false to remove a listener for the bubbling phase. Note that
|
||||
* FakeEventTarget does not support the capturing phase from the standard
|
||||
* event model.
|
||||
* @param {boolean=} opt_capturing Ignored. FakeEventTargets do not have
|
||||
* parents, so events neither capture nor bubble.
|
||||
* @override
|
||||
*/
|
||||
shaka.util.FakeEventTarget.prototype.removeEventListener =
|
||||
function(type, listener, opt_capturing) {
|
||||
// We don't support the capturing phase.
|
||||
shaka.asserts.assert(!opt_capturing, 'Capturing phase unsupported');
|
||||
if (!opt_capturing) {
|
||||
this.listeners_.remove(type, listener);
|
||||
}
|
||||
this.listeners_.remove(type, listener);
|
||||
};
|
||||
|
||||
|
||||
@@ -104,61 +88,18 @@ shaka.util.FakeEventTarget.prototype.removeEventListener =
|
||||
* @override
|
||||
*/
|
||||
shaka.util.FakeEventTarget.prototype.dispatchEvent = function(event) {
|
||||
// Overwrite the Event's properties if not already done so (events can be
|
||||
// re-dispatched, so we may be have already done this, so in this case we
|
||||
// can just update the values). Assignment doesn't work in most browsers.
|
||||
// Object.defineProperty seems to work, although some browsers
|
||||
// need the original properties deleted first.
|
||||
|
||||
if (!event.hasOwnProperty('srcElement')) {
|
||||
delete event.srcElement;
|
||||
|
||||
Object.defineProperty(event, 'srcElement', {
|
||||
get: function() { return null; }
|
||||
});
|
||||
}
|
||||
|
||||
if (event.hasOwnProperty('target')) {
|
||||
event.target = this;
|
||||
} else {
|
||||
delete event.target;
|
||||
|
||||
var target = this;
|
||||
Object.defineProperty(event, 'target', {
|
||||
get: function() { return target; },
|
||||
set: function(value) { target = value; }
|
||||
});
|
||||
}
|
||||
|
||||
if (event.hasOwnProperty('currentTarget')) {
|
||||
event.currentTarget = null;
|
||||
} else {
|
||||
delete event.currentTarget;
|
||||
|
||||
var currentTarget = null;
|
||||
Object.defineProperty(event, 'currentTarget', {
|
||||
get: function() { return currentTarget; },
|
||||
set: function(value) { currentTarget = value; }
|
||||
});
|
||||
}
|
||||
|
||||
return this.recursiveDispatch_(event);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches an event recursively without changing its original target.
|
||||
*
|
||||
* @param {!Event} event
|
||||
* @return {boolean} True if the default action was prevented.
|
||||
* @private
|
||||
*/
|
||||
shaka.util.FakeEventTarget.prototype.recursiveDispatch_ = function(event) {
|
||||
event.currentTarget = this;
|
||||
// In many browsers, it is complex to overwrite properties of actual Events.
|
||||
// Here we expect only to dispatch FakeEvents, which are simpler.
|
||||
shaka.asserts.assert(event instanceof shaka.util.FakeEvent,
|
||||
'FakeEventTarget can only dispatch FakeEvents!');
|
||||
|
||||
var list = this.listeners_.get(event.type) || [];
|
||||
|
||||
for (var i = 0; i < list.length; ++i) {
|
||||
// Do this every time, since events can be re-dispatched from handlers.
|
||||
event.target = this;
|
||||
event.currentTarget = this;
|
||||
|
||||
var listener = list[i];
|
||||
try {
|
||||
if (listener.handleEvent) {
|
||||
@@ -166,20 +107,17 @@ shaka.util.FakeEventTarget.prototype.recursiveDispatch_ = function(event) {
|
||||
} else {
|
||||
listener.call(this, event);
|
||||
}
|
||||
// NOTE: If needed, stopImmediatePropagation() would be checked here.
|
||||
} catch (exception) {
|
||||
// Exceptions during event handlers should not affect the caller,
|
||||
// but should appear on the console as uncaught, according to MDN:
|
||||
// http://goo.gl/N6Ff27
|
||||
shaka.log.error('Uncaught exception in event handler', exception);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: If needed, stopPropagation() would be checked here.
|
||||
if (this.parent && event.bubbles) {
|
||||
this.parent.recursiveDispatch_(event);
|
||||
if (event.stopped) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return event.defaultPrevented;
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ goog.require('shaka.media.VttTextParser');
|
||||
goog.require('shaka.net.DataUriPlugin');
|
||||
goog.require('shaka.net.HttpPlugin');
|
||||
|
||||
goog.require('shaka.polyfill.CustomEvent');
|
||||
goog.require('shaka.polyfill.Fullscreen');
|
||||
goog.require('shaka.polyfill.MediaKeys');
|
||||
goog.require('shaka.polyfill.Promise');
|
||||
|
||||
@@ -26,8 +26,12 @@ describe('EventManager', function() {
|
||||
eventManager = new shaka.util.EventManager();
|
||||
target1 = document.createElement('div');
|
||||
target2 = document.createElement('div');
|
||||
event1 = new CustomEvent('eventtype1');
|
||||
event2 = new CustomEvent('eventtype2');
|
||||
|
||||
// new Event() is current, but document.createEvent() works back to IE11.
|
||||
event1 = document.createEvent('Event');
|
||||
event1.initEvent('eventtype1', false, false);
|
||||
event2 = document.createEvent('Event');
|
||||
event2.initEvent('eventtype2', false, false);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
describe('FakeEventTarget', function() {
|
||||
var target;
|
||||
var logErrorSpy;
|
||||
var originalLogError;
|
||||
|
||||
beforeAll(function() {
|
||||
originalLogError = shaka.log.error;
|
||||
logErrorSpy = jasmine.createSpy('shaka.log.error');
|
||||
shaka.log.error = logErrorSpy;
|
||||
});
|
||||
|
||||
afterAll(function() {
|
||||
shaka.log.error = originalLogError;
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
target = new shaka.util.FakeEventTarget();
|
||||
logErrorSpy.calls.reset();
|
||||
logErrorSpy.and.callFake(fail);
|
||||
});
|
||||
|
||||
it('sets target on dispatched events', function(done) {
|
||||
target.addEventListener('event', function(event) {
|
||||
expect(event.target).toBe(target);
|
||||
expect(event.currentTarget).toBe(target);
|
||||
done();
|
||||
});
|
||||
|
||||
target.dispatchEvent(new shaka.util.FakeEvent('event'));
|
||||
});
|
||||
|
||||
it('calls all event listeners', function(done) {
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
target.addEventListener('event', listener1);
|
||||
target.addEventListener('event', listener2);
|
||||
|
||||
target.dispatchEvent(new shaka.util.FakeEvent('event'));
|
||||
|
||||
shaka.test.Util.delay(0.1).then(function() {
|
||||
expect(listener1).toHaveBeenCalled();
|
||||
expect(listener2).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('stops processing on stopImmediatePropagation', function(done) {
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
target.addEventListener('event', listener1);
|
||||
target.addEventListener('event', listener2);
|
||||
|
||||
listener1.and.callFake(function(event) {
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
target.dispatchEvent(new shaka.util.FakeEvent('event'));
|
||||
|
||||
shaka.test.Util.delay(0.1).then(function() {
|
||||
expect(listener1).toHaveBeenCalled();
|
||||
expect(listener2).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('catches exceptions thrown from listeners', function(done) {
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
target.addEventListener('event', listener1);
|
||||
target.addEventListener('event', listener2);
|
||||
|
||||
listener1.and.throwError('whoops');
|
||||
logErrorSpy.and.stub();
|
||||
|
||||
target.dispatchEvent(new shaka.util.FakeEvent('event'));
|
||||
|
||||
shaka.test.Util.delay(0.1).then(function() {
|
||||
expect(listener1).toHaveBeenCalled();
|
||||
expect(logErrorSpy).toHaveBeenCalled();
|
||||
expect(listener2).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('allows events to be re-dispatched', function(done) {
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
target.addEventListener('event', listener1);
|
||||
target.addEventListener('event', listener2);
|
||||
|
||||
var target2 = new shaka.util.FakeEventTarget();
|
||||
var target2Listener = jasmine.createSpy('target2Listener');
|
||||
|
||||
target2.addEventListener('event', target2Listener);
|
||||
|
||||
listener1.and.callFake(function(event) {
|
||||
expect(event.target).toBe(target);
|
||||
target2.dispatchEvent(event);
|
||||
});
|
||||
|
||||
target2Listener.and.callFake(function(event) {
|
||||
expect(event.target).toBe(target2);
|
||||
});
|
||||
|
||||
listener2.and.callFake(function(event) {
|
||||
expect(event.target).toBe(target);
|
||||
});
|
||||
|
||||
target.dispatchEvent(new shaka.util.FakeEvent('event'));
|
||||
|
||||
shaka.test.Util.delay(0.1).then(function() {
|
||||
expect(listener1).toHaveBeenCalled();
|
||||
expect(listener2).toHaveBeenCalled();
|
||||
expect(target2Listener).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
describe('FakeEventTarget', function() {
|
||||
it('sets target on dispatched events', function(done) {
|
||||
var target = new shaka.util.FakeEventTarget(null);
|
||||
|
||||
target.addEventListener('event', function(event) {
|
||||
expect(event.target).toBe(target);
|
||||
done();
|
||||
});
|
||||
|
||||
target.dispatchEvent(shaka.util.FakeEvent.create({
|
||||
'type': 'event',
|
||||
'bubbles': false
|
||||
}));
|
||||
});
|
||||
|
||||
it('sets currentTarget on dispatched events', function(done) {
|
||||
var targetHigh = new shaka.util.FakeEventTarget(null);
|
||||
var targetLow = new shaka.util.FakeEventTarget(targetHigh);
|
||||
|
||||
targetHigh.addEventListener('event', function(event) {
|
||||
expect(event.target).toBe(targetLow);
|
||||
expect(event.currentTarget).toBe(targetHigh);
|
||||
done();
|
||||
});
|
||||
|
||||
targetLow.dispatchEvent(shaka.util.FakeEvent.create({
|
||||
'type': 'event',
|
||||
'bubbles': true
|
||||
}));
|
||||
});
|
||||
|
||||
it('allows events to be re-dispatched', function(done) {
|
||||
var targetHigh = new shaka.util.FakeEventTarget(null);
|
||||
var targetLow = new shaka.util.FakeEventTarget(targetHigh);
|
||||
|
||||
targetLow.addEventListener('event', function(event) {
|
||||
expect(event.target).toBe(targetLow);
|
||||
targetHigh.dispatchEvent(event);
|
||||
});
|
||||
|
||||
targetHigh.addEventListener('event', function(event) {
|
||||
expect(event.target).toBe(targetHigh);
|
||||
done();
|
||||
});
|
||||
|
||||
targetLow.dispatchEvent(shaka.util.FakeEvent.create({
|
||||
'type': 'event',
|
||||
'bubbles': false
|
||||
}));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user