Bubbling for event system
parent
efbe56001d
commit
5c3620c637
|
@ -1606,7 +1606,7 @@ class H5PCore {
|
||||||
|
|
||||||
public static $coreApi = array(
|
public static $coreApi = array(
|
||||||
'majorVersion' => 1,
|
'majorVersion' => 1,
|
||||||
'minorVersion' => 4
|
'minorVersion' => 5
|
||||||
);
|
);
|
||||||
public static $styles = array(
|
public static $styles = array(
|
||||||
'styles/h5p.css',
|
'styles/h5p.css',
|
||||||
|
@ -2749,13 +2749,13 @@ class H5PContentValidator {
|
||||||
'type' => 'group',
|
'type' => 'group',
|
||||||
'fields' => $library['semantics'],
|
'fields' => $library['semantics'],
|
||||||
), FALSE);
|
), FALSE);
|
||||||
$validkeys = array('library', 'params', 'uuid');
|
$validkeys = array('library', 'params', 'subContentId');
|
||||||
if (isset($semantics->extraAttributes)) {
|
if (isset($semantics->extraAttributes)) {
|
||||||
$validkeys = array_merge($validkeys, $semantics->extraAttributes);
|
$validkeys = array_merge($validkeys, $semantics->extraAttributes);
|
||||||
}
|
}
|
||||||
$this->filterParams($value, $validkeys);
|
$this->filterParams($value, $validkeys);
|
||||||
if (isset($value->uuid) && ! preg_match('/^\{?[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\}?$/', $value->uuid)) {
|
if (isset($value->subContentId) && ! preg_match('/^\{?[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\}?$/', $value->subContentId)) {
|
||||||
unset($value->uuid);
|
unset($value->subContentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all dependencies for this library
|
// Find all dependencies for this library
|
||||||
|
|
|
@ -9,18 +9,55 @@ H5P.Event = function(type, data, extras) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
var bubbles = false;
|
var bubbles = false;
|
||||||
|
|
||||||
|
// Is this an external event?
|
||||||
|
var external = false;
|
||||||
|
|
||||||
|
// Is this event scheduled to be sent externally?
|
||||||
|
var scheduledForExternal = false;
|
||||||
|
|
||||||
if (extras === undefined) {
|
if (extras === undefined) {
|
||||||
extras = {};
|
extras = {};
|
||||||
}
|
}
|
||||||
if (extras.bubbles === true) {
|
if (extras.bubbles === true) {
|
||||||
bubbles = true;
|
bubbles = true;
|
||||||
}
|
}
|
||||||
|
if (extras.external === true) {
|
||||||
|
external = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent this event from bubbling up to parent
|
||||||
|
*
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
this.preventBubbling = function() {
|
this.preventBubbling = function() {
|
||||||
bubbles = false;
|
bubbles = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bubbling status
|
||||||
|
*
|
||||||
|
* @returns {Boolean} - true if bubbling false otherwise
|
||||||
|
*/
|
||||||
this.getBubbles = function() {
|
this.getBubbles = function() {
|
||||||
return bubbles;
|
return bubbles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to schedule an event for externalDispatcher
|
||||||
|
*
|
||||||
|
* @returns {Boolean}
|
||||||
|
* - true if external and not already scheduled
|
||||||
|
* - false otherwise
|
||||||
|
*/
|
||||||
|
this.scheduleForExternal = function() {
|
||||||
|
if (external && !scheduledForExternal) {
|
||||||
|
scheduledForExternal = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
H5P.EventDispatcher = (function () {
|
H5P.EventDispatcher = (function () {
|
||||||
|
@ -144,27 +181,42 @@ H5P.EventDispatcher = (function () {
|
||||||
* Custom event data(used when event type as string is used as first
|
* Custom event data(used when event type as string is used as first
|
||||||
* argument
|
* argument
|
||||||
*/
|
*/
|
||||||
this.trigger = function (event, eventData) {
|
this.trigger = function (event, eventData, extras) {
|
||||||
if (event === undefined) {
|
if (event === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof event === 'string') {
|
if (typeof event === 'string') {
|
||||||
event = new H5P.Event(event, eventData);
|
event = new H5P.Event(event, eventData, extras);
|
||||||
}
|
}
|
||||||
else if (eventData !== undefined) {
|
else if (eventData !== undefined) {
|
||||||
event.data = eventData;
|
event.data = eventData;
|
||||||
}
|
}
|
||||||
if (triggers[event.type] === undefined) {
|
|
||||||
return;
|
// Check to see if this event should go externally after all triggering and bubbling is done
|
||||||
}
|
var scheduledForExternal = event.scheduleForExternal();
|
||||||
|
|
||||||
|
if (triggers[event.type] !== undefined) {
|
||||||
// Call all listeners
|
// Call all listeners
|
||||||
for (var i = 0; i < triggers[event.type].length; i++) {
|
for (var i = 0; i < triggers[event.type].length; i++) {
|
||||||
triggers[event.type][i].listener.call(triggers[event.type][i].thisArg, event);
|
triggers[event.type][i].listener.call(triggers[event.type][i].thisArg, event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggers['*'] !== undefined) {
|
||||||
|
// Call all * listeners
|
||||||
|
for (var i = 0; i < triggers['*'].length; i++) {
|
||||||
|
triggers['*'][i].listener.call(triggers['*'][i].thisArg, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bubble
|
// Bubble
|
||||||
if (event.getBubbles() && self.parent instanceof H5P.EventDispatcher && typeof self.parent.trigger === 'function') {
|
if (event.getBubbles() && self.parent instanceof H5P.EventDispatcher && typeof self.parent.trigger === 'function') {
|
||||||
self.parent.trigger(event);
|
self.parent.trigger(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scheduledForExternal) {
|
||||||
|
H5P.externalDispatcher.trigger(event);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ var H5P = H5P || {};
|
||||||
* @class
|
* @class
|
||||||
*/
|
*/
|
||||||
H5P.XAPIEvent = function() {
|
H5P.XAPIEvent = function() {
|
||||||
H5P.Event.call(this, 'xAPI', {'statement': {}}, {bubbles: true});
|
H5P.Event.call(this, 'xAPI', {'statement': {}}, {bubbles: true, external: true});
|
||||||
};
|
};
|
||||||
|
|
||||||
H5P.XAPIEvent.prototype = Object.create(H5P.Event.prototype);
|
H5P.XAPIEvent.prototype = Object.create(H5P.Event.prototype);
|
||||||
|
@ -87,8 +87,8 @@ H5P.XAPIEvent.prototype.setObject = function(instance) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (instance.uuid) {
|
if (instance.subContentId) {
|
||||||
this.data.statement.object.definition.extensions['http://h5p.org/x-api/h5p-uuid'] = instance.uuid;
|
this.data.statement.object.definition.extensions['http://h5p.org/x-api/h5p-subContentId'] = instance.subContentId;
|
||||||
// Don't set titles on main content, title should come from publishing platform
|
// Don't set titles on main content, title should come from publishing platform
|
||||||
if (typeof instance.getH5PTitle === 'function') {
|
if (typeof instance.getH5PTitle === 'function') {
|
||||||
this.data.statement.object.definition.name = {
|
this.data.statement.object.definition.name = {
|
||||||
|
@ -112,8 +112,8 @@ H5P.XAPIEvent.prototype.setObject = function(instance) {
|
||||||
* @param {object} instance - the H5P instance
|
* @param {object} instance - the H5P instance
|
||||||
*/
|
*/
|
||||||
H5P.XAPIEvent.prototype.setContext = function(instance) {
|
H5P.XAPIEvent.prototype.setContext = function(instance) {
|
||||||
if (instance.parent && (instance.parent.contentId || instance.parent.uuid)) {
|
if (instance.parent && (instance.parent.contentId || instance.parent.subContentId)) {
|
||||||
var parentId = instance.parent.uuid === undefined ? instance.parent.contentId : instance.parent.uuid;
|
var parentId = instance.parent.subContentId === undefined ? instance.parent.contentId : instance.parent.subContentId;
|
||||||
this.data.statement.context = {
|
this.data.statement.context = {
|
||||||
"contextActivities": {
|
"contextActivities": {
|
||||||
"parent": [
|
"parent": [
|
||||||
|
@ -179,8 +179,8 @@ H5P.XAPIEvent.prototype.getContentXAPIId = function (instance) {
|
||||||
var xAPIId;
|
var xAPIId;
|
||||||
if (instance.contentId && H5PIntegration && H5PIntegration.contents) {
|
if (instance.contentId && H5PIntegration && H5PIntegration.contents) {
|
||||||
xAPIId = H5PIntegration.contents['cid-' + instance.contentId].url;
|
xAPIId = H5PIntegration.contents['cid-' + instance.contentId].url;
|
||||||
if (instance.uuid) {
|
if (instance.subContentId) {
|
||||||
xAPIId += '?uuid=' + instance.uuid;
|
xAPIId += '?subContentId=' + instance.subContentId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return xAPIId;
|
return xAPIId;
|
||||||
|
|
|
@ -4,7 +4,7 @@ var H5P = H5P || {};
|
||||||
H5P.externalDispatcher = new H5P.EventDispatcher();
|
H5P.externalDispatcher = new H5P.EventDispatcher();
|
||||||
|
|
||||||
if (H5P.isFramed && H5P.externalEmbed !== true) {
|
if (H5P.isFramed && H5P.externalEmbed !== true) {
|
||||||
H5P.externalDispatcher.on('xAPI', window.top.H5P.externalDispatcher.trigger);
|
H5P.externalDispatcher.on('*', window.top.H5P.externalDispatcher.trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventDispatcher extensions
|
// EventDispatcher extensions
|
||||||
|
|
Loading…
Reference in New Issue