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
|
### SCORM 2004 Listeners
|
||||||
|
|
||||||
For convenience, hooks are available for all the SCORM API Signature functions:
|
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
|
### 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.
|
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",
|
"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",
|
"description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
|
||||||
"main": "dist/scorm-again.min.js",
|
"main": "dist/scorm-again.min.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
|||||||
@@ -772,6 +772,66 @@ export default class BaseAPI {
|
|||||||
CMIElement: CMIElement,
|
CMIElement: CMIElement,
|
||||||
callback: callback,
|
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 {
|
} else {
|
||||||
result = JSON.parse(httpReq.responseText);
|
result = JSON.parse(httpReq.responseText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.result === true ||
|
|
||||||
result.result === global_constants.SCORM_TRUE) {
|
|
||||||
api.processListeners('CommitSuccess');
|
|
||||||
} else {
|
|
||||||
api.processListeners('CommitError');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -1053,10 +1106,12 @@ export default class BaseAPI {
|
|||||||
result = {};
|
result = {};
|
||||||
result.result = global_constants.SCORM_TRUE;
|
result.result = global_constants.SCORM_TRUE;
|
||||||
result.errorCode = 0;
|
result.errorCode = 0;
|
||||||
|
api.processListeners('CommitSuccess');
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
api.processListeners('CommitError');
|
||||||
return genericError;
|
return genericError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1081,11 +1136,13 @@ export default class BaseAPI {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
api.processListeners('CommitError');
|
||||||
return genericError;
|
return genericError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof result === 'undefined') {
|
if (typeof result === 'undefined') {
|
||||||
|
api.processListeners('CommitError');
|
||||||
return genericError;
|
return genericError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -448,6 +448,62 @@ describe('SCORM 1.2 API Tests', () => {
|
|||||||
clock.tick(2000);
|
clock.tick(2000);
|
||||||
expect(callback.called).to.be.true;
|
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',
|
it('Should handle CommitError event',
|
||||||
() => {
|
() => {
|
||||||
const scorm12API = api({
|
const scorm12API = api({
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ describe('SCORM 2004 API Tests', () => {
|
|||||||
server.post('/scorm2004/error', () => {
|
server.post('/scorm2004/error', () => {
|
||||||
return [500, {'Content-Type': 'application/json'}, '{}'];
|
return [500, {'Content-Type': 'application/json'}, '{}'];
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
server.unhandledRequest = function(verb, path, request) {
|
||||||
|
// do nothing
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
@@ -645,6 +649,62 @@ describe('SCORM 2004 API Tests', () => {
|
|||||||
clock.tick(2000);
|
clock.tick(2000);
|
||||||
expect(callback.called).to.be.true;
|
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',
|
it('Should handle CommitError event',
|
||||||
() => {
|
() => {
|
||||||
const scorm2004API = api({
|
const scorm2004API = api({
|
||||||
@@ -657,6 +717,22 @@ describe('SCORM 2004 API Tests', () => {
|
|||||||
const callback = sinon.spy();
|
const callback = sinon.spy();
|
||||||
scorm2004API.on('CommitError', callback);
|
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');
|
scorm2004API.lmsSetValue('cmi.session_time', 'PT1M0S');
|
||||||
clock.tick(2000);
|
clock.tick(2000);
|
||||||
expect(callback.called).to.be.true;
|
expect(callback.called).to.be.true;
|
||||||
|
|||||||
Reference in New Issue
Block a user