"use strict";
var Widgets = require("./widgets");
var pluginTypes_1 = require("../pluginApi/pluginTypes");
var WidgetPluginInstance = (function () {
function WidgetPluginInstance(id, store) {
var _this = this;
this.id = id;
this.store = store;
this.frameInitialized = false;
this.disposed = false;
this.oldWidgetState = null;
this.oldDatasourceData = {};
if (typeof window !== 'undefined') {
this.messageListener = function (e) {
if (_this.disposed) {
// TODO: better unit test than runtime checking
console.error("Message listener called but WidgetPluginInstance is already disposed");
return;
}
if (!_this._iFrame && e.origin === "null") {
console.log("Discarding message because iFrame not set yet", e.data);
}
if (_this._iFrame !== undefined && e.origin === "null" && e.source === _this._iFrame.contentWindow) {
_this.handleMessage(e.data);
}
};
window.addEventListener('message', this.messageListener);
}
this.unsubscribeStore = store.subscribe(function () {
if (_this.disposed) {
// TODO: better unit test than runtime checking
console.error("Store change observed but WidgetPluginInstance is already disposed");
return;
}
if (!_this.frameInitialized) {
// We get invalid caches when we send state to the iFrame before it is ready
return;
}
var state = store.getState();
var widgetState = state.widgets[id];
if (widgetState === undefined) {
// This happens for example during import. Where the state is cleared but this class not yet disposed.
// So we just silently return.
return;
}
if (widgetState !== _this.oldWidgetState) {
_this.oldWidgetState = widgetState;
_this.sendPluginState();
}
_this.updateDatasourceDataInFrame();
});
}
Object.defineProperty(WidgetPluginInstance.prototype, "iFrame", {
set: function (element) {
this._iFrame = element;
this.sendMessage({ type: pluginTypes_1.MESSAGE_INIT });
},
enumerable: true,
configurable: true
});
WidgetPluginInstance.prototype.updateDatasourceDataInFrame = function () {
var _this = this;
var state = this.store.getState();
var widgetState = state.widgets[this.id];
var widgetPluginState = state.widgetPlugins[widgetState.type];
widgetPluginState.typeInfo.settings.filter(function (s) {
return s.type === "datasource";
}).map(function (s) {
return widgetState.settings[s.id];
}).forEach(function (dsId) {
if (state.datasources[dsId] === undefined) {
return;
}
var data = state.datasourceData[dsId];
if (data !== _this.oldDatasourceData[dsId]) {
_this.oldDatasourceData[dsId] = data;
_this.sendDatasourceData(dsId);
}
});
};
WidgetPluginInstance.prototype.handleMessage = function (msg) {
switch (msg.type) {
case 'init': {
this.frameInitialized = true;
this.sendPluginState();
this.updateDatasourceDataInFrame();
break;
}
case 'updateSetting': {
this.updateSetting(msg.payload.id, msg.payload.value);
break;
}
default:
break;
}
};
WidgetPluginInstance.prototype.sendMessage = function (msg) {
if (!this._iFrame.contentWindow) {
// This happens during import. We ignore it silently and rely on later disposal to free memory.
// TODO: Find a way to dispose this instance before this happens.
return;
}
this._iFrame.contentWindow.postMessage(msg, '*');
};
WidgetPluginInstance.prototype.sendPluginState = function () {
var state = this.store.getState();
var widgetState = state.widgets[this.id];
this.sendMessage({
type: pluginTypes_1.MESSAGE_STATE,
payload: widgetState
});
};
WidgetPluginInstance.prototype.sendDatasourceData = function (dsId) {
var state = this.store.getState();
this.sendMessage({
type: pluginTypes_1.MESSAGE_DATA,
payload: {
id: dsId,
data: state.datasourceData[dsId]
}
});
};
WidgetPluginInstance.prototype.updateSetting = function (settingId, value) {
this.store.dispatch(Widgets.updatedSingleSetting(this.id, settingId, value));
};
WidgetPluginInstance.prototype.dispose = function () {
if (!this.disposed && _.isFunction(this.unsubscribeStore)) {
this.unsubscribeStore();
}
if (!this.disposed && _.isFunction(this.messageListener)) {
window.removeEventListener("message", this.messageListener);
}
this.disposed = true;
};
return WidgetPluginInstance;
}());
exports.WidgetPluginInstance = WidgetPluginInstance;
|