Adding ability to deregister event listeners
This commit is contained in:
20
README.md
20
README.md
@@ -177,6 +177,16 @@ window.API.on("LMSSetValue.cmi.*", function(CMIElement, value) {
|
||||
});
|
||||
```
|
||||
|
||||
You also have to ability to remove specific callback listeners:
|
||||
```javascript
|
||||
window.API.off("LMSInitialize", callback);
|
||||
```
|
||||
|
||||
Or, you can clear all callbacks for a particular event:
|
||||
```javascript
|
||||
window.API.clear("LMSInitialize");
|
||||
```
|
||||
|
||||
### SCORM 2004 Listeners
|
||||
|
||||
For convenience, hooks are available for all the SCORM API Signature functions:
|
||||
@@ -220,6 +230,16 @@ window.API_1484_11.on("SetValue.cmi.* ", function(CMIElement, value) {
|
||||
});
|
||||
```
|
||||
|
||||
You also have to ability to remove specific callback listeners:
|
||||
```javascript
|
||||
window.API_1484_11.off("Initialize", callback);
|
||||
```
|
||||
|
||||
Or, you can clear all callbacks for a particular event:
|
||||
```javascript
|
||||
window.API_1484_11.clear("Initialize");
|
||||
```
|
||||
|
||||
### Total Time Calculation
|
||||
The APIs provide a convenience method `getCurrentTotalTime()` that can be used for calculating the current `total_time` value, based on the current `session_time` and the `total_time` supplied when the module was launched. This works for both ISO 8601 duration time formats in SCORM 2004 as well as the HH:MM:SS format in SCORM 1.2 and AICC, and outputs the correct format based on the version used.
|
||||
|
||||
|
||||
99
dist/scorm-again.js
vendored
99
dist/scorm-again.js
vendored
File diff suppressed because one or more lines are too long
2
dist/scorm-again.js.map
vendored
2
dist/scorm-again.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/scorm-again.min.js
vendored
2
dist/scorm-again.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "scorm-again",
|
||||
"version": "1.4.5",
|
||||
"version": "1.5.0",
|
||||
"description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
|
||||
"main": "dist/scorm-again.min.js",
|
||||
"directories": {
|
||||
|
||||
@@ -772,6 +772,66 @@ export default class BaseAPI {
|
||||
CMIElement: CMIElement,
|
||||
callback: callback,
|
||||
});
|
||||
|
||||
this.apiLog('on', functionName, `Added event listener: ${this.listenerArray.length}`, global_constants.LOG_LEVEL_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a mechanism for detaching a specific SCORM event listener
|
||||
*
|
||||
* @param {string} listenerName
|
||||
* @param {function} callback
|
||||
*/
|
||||
off(listenerName: String, callback: function) {
|
||||
if (!callback) return;
|
||||
|
||||
const listenerFunctions = listenerName.split(' ');
|
||||
for (let i = 0; i < listenerFunctions.length; i++) {
|
||||
const listenerSplit = listenerFunctions[i].split('.');
|
||||
if (listenerSplit.length === 0) return;
|
||||
|
||||
const functionName = listenerSplit[0];
|
||||
|
||||
let CMIElement = null;
|
||||
if (listenerSplit.length > 1) {
|
||||
CMIElement = listenerName.replace(functionName + '.', '');
|
||||
}
|
||||
|
||||
const removeIndex = this.listenerArray.findIndex((obj) =>
|
||||
obj.functionName === functionName &&
|
||||
obj.CMIElement === CMIElement &&
|
||||
obj.callback === callback
|
||||
);
|
||||
if (removeIndex !== -1) {
|
||||
this.listenerArray.splice(removeIndex, 1);
|
||||
this.apiLog('off', functionName, `Removed event listener: ${this.listenerArray.length}`, global_constants.LOG_LEVEL_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a mechanism for clearing all listeners from a specific SCORM event
|
||||
*
|
||||
* @param {string} listenerName
|
||||
*/
|
||||
clear(listenerName: String) {
|
||||
const listenerFunctions = listenerName.split(' ');
|
||||
for (let i = 0; i < listenerFunctions.length; i++) {
|
||||
const listenerSplit = listenerFunctions[i].split('.');
|
||||
if (listenerSplit.length === 0) return;
|
||||
|
||||
const functionName = listenerSplit[0];
|
||||
|
||||
let CMIElement = null;
|
||||
if (listenerSplit.length > 1) {
|
||||
CMIElement = listenerName.replace(functionName + '.', '');
|
||||
}
|
||||
|
||||
this.listenerArray = this.listenerArray.filter((obj) =>
|
||||
obj.functionName !== functionName &&
|
||||
obj.CMIElement !== CMIElement,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1023,13 +1083,6 @@ export default class BaseAPI {
|
||||
} else {
|
||||
result = JSON.parse(httpReq.responseText);
|
||||
}
|
||||
|
||||
if (result.result === true ||
|
||||
result.result === global_constants.SCORM_TRUE) {
|
||||
api.processListeners('CommitSuccess');
|
||||
} else {
|
||||
api.processListeners('CommitError');
|
||||
}
|
||||
};
|
||||
}
|
||||
try {
|
||||
@@ -1053,10 +1106,12 @@ export default class BaseAPI {
|
||||
result = {};
|
||||
result.result = global_constants.SCORM_TRUE;
|
||||
result.errorCode = 0;
|
||||
api.processListeners('CommitSuccess');
|
||||
return result;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
api.processListeners('CommitError');
|
||||
return genericError;
|
||||
}
|
||||
} else {
|
||||
@@ -1081,11 +1136,13 @@ export default class BaseAPI {
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
api.processListeners('CommitError');
|
||||
return genericError;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof result === 'undefined') {
|
||||
api.processListeners('CommitError');
|
||||
return genericError;
|
||||
}
|
||||
|
||||
|
||||
@@ -448,6 +448,62 @@ describe('SCORM 1.2 API Tests', () => {
|
||||
clock.tick(2000);
|
||||
expect(callback.called).to.be.true;
|
||||
});
|
||||
it('Should clear all event listeners for CommitSuccess',
|
||||
() => {
|
||||
const scorm12API = api({
|
||||
lmsCommitUrl: '/scorm12',
|
||||
autocommit: true,
|
||||
autocommitSeconds: 1,
|
||||
});
|
||||
scorm12API.lmsInitialize();
|
||||
|
||||
const callback = sinon.spy();
|
||||
const callback2 = sinon.spy();
|
||||
scorm12API.on('CommitSuccess', callback);
|
||||
scorm12API.on('CommitSuccess', callback2);
|
||||
|
||||
scorm12API.lmsSetValue('cmi.core.session_time', '00:01:00');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledOnce).to.be.true;
|
||||
expect(callback2.calledOnce).to.be.true;
|
||||
|
||||
scorm12API.clear('CommitSuccess');
|
||||
|
||||
scorm12API.lmsSetValue('cmi.core.session_time', '00:01:00');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledTwice).to.be.false;
|
||||
expect(callback2.calledTwice).to.be.false;
|
||||
});
|
||||
it('Should clear only the specific event listener for CommitSuccess',
|
||||
() => {
|
||||
const scorm12API = api({
|
||||
lmsCommitUrl: '/scorm12',
|
||||
autocommit: true,
|
||||
autocommitSeconds: 1,
|
||||
});
|
||||
scorm12API.lmsInitialize();
|
||||
|
||||
const callback = sinon.spy(() => 1);
|
||||
const callback2 = sinon.spy(() => 2);
|
||||
const callback3 = sinon.spy(() => 3);
|
||||
scorm12API.on('CommitSuccess', callback);
|
||||
scorm12API.on('CommitSuccess', callback2);
|
||||
scorm12API.on('LMSSetValue', callback3);
|
||||
|
||||
scorm12API.lmsSetValue('cmi.core.session_time', '00:01:00');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledOnce).to.be.true;
|
||||
expect(callback2.calledOnce).to.be.true;
|
||||
expect(callback3.calledOnce).to.be.true;
|
||||
|
||||
scorm12API.off('CommitSuccess', callback);
|
||||
|
||||
scorm12API.lmsSetValue('cmi.core.session_time', '00:01:00');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledTwice).to.be.false; // removed callback should not be called a second time
|
||||
expect(callback2.calledTwice).to.be.true;
|
||||
expect(callback3.calledTwice).to.be.true;
|
||||
});
|
||||
it('Should handle CommitError event',
|
||||
() => {
|
||||
const scorm12API = api({
|
||||
|
||||
@@ -38,6 +38,10 @@ describe('SCORM 2004 API Tests', () => {
|
||||
server.post('/scorm2004/error', () => {
|
||||
return [500, {'Content-Type': 'application/json'}, '{}'];
|
||||
}, false);
|
||||
|
||||
server.unhandledRequest = function(verb, path, request) {
|
||||
// do nothing
|
||||
};
|
||||
});
|
||||
|
||||
after(() => {
|
||||
@@ -645,6 +649,62 @@ describe('SCORM 2004 API Tests', () => {
|
||||
clock.tick(2000);
|
||||
expect(callback.called).to.be.true;
|
||||
});
|
||||
it('Should clear all event listeners for CommitSuccess',
|
||||
() => {
|
||||
const scorm2004API = api({
|
||||
lmsCommitUrl: '/scorm2004',
|
||||
autocommit: true,
|
||||
autocommitSeconds: 1,
|
||||
});
|
||||
scorm2004API.lmsInitialize();
|
||||
|
||||
const callback = sinon.spy();
|
||||
const callback2 = sinon.spy();
|
||||
scorm2004API.on('CommitSuccess', callback);
|
||||
scorm2004API.on('CommitSuccess', callback2);
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledOnce).to.be.true;
|
||||
expect(callback2.calledOnce).to.be.true;
|
||||
|
||||
scorm2004API.clear('CommitSuccess');
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledTwice).to.be.false;
|
||||
expect(callback2.calledTwice).to.be.false;
|
||||
});
|
||||
it('Should clear only the specific event listener for CommitSuccess',
|
||||
() => {
|
||||
const scorm2004API = api({
|
||||
lmsCommitUrl: '/scorm2004',
|
||||
autocommit: true,
|
||||
autocommitSeconds: 1,
|
||||
});
|
||||
scorm2004API.lmsInitialize();
|
||||
|
||||
const callback = sinon.spy(() => 1);
|
||||
const callback2 = sinon.spy(() => 2);
|
||||
const callback3 = sinon.spy(() => 3);
|
||||
scorm2004API.on('CommitSuccess', callback);
|
||||
scorm2004API.on('CommitSuccess', callback2);
|
||||
scorm2004API.on('SetValue', callback3);
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledOnce).to.be.true;
|
||||
expect(callback2.calledOnce).to.be.true;
|
||||
expect(callback3.calledOnce).to.be.true;
|
||||
|
||||
scorm2004API.off('CommitSuccess', callback);
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.calledTwice).to.be.false; // removed callback should not be called a second time
|
||||
expect(callback2.calledTwice).to.be.true;
|
||||
expect(callback3.calledTwice).to.be.true;
|
||||
});
|
||||
it('Should handle CommitError event',
|
||||
() => {
|
||||
const scorm2004API = api({
|
||||
@@ -657,6 +717,22 @@ describe('SCORM 2004 API Tests', () => {
|
||||
const callback = sinon.spy();
|
||||
scorm2004API.on('CommitError', callback);
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.called).to.be.true;
|
||||
});
|
||||
it('Should handle CommitError event when offline',
|
||||
() => {
|
||||
const scorm2004API = api({
|
||||
lmsCommitUrl: '/scorm2004/does_not_exist',
|
||||
autocommit: true,
|
||||
autocommitSeconds: 1,
|
||||
});
|
||||
scorm2004API.lmsInitialize();
|
||||
|
||||
const callback = sinon.spy();
|
||||
scorm2004API.on('CommitError', callback);
|
||||
|
||||
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||
clock.tick(2000);
|
||||
expect(callback.called).to.be.true;
|
||||
|
||||
Reference in New Issue
Block a user