Introduce widget class
Change-Id: I949cd46c48b9176c0b013c1c65f1fba949413c8e
diff --git a/dev/js/src/plugin/client.js b/dev/js/src/plugin/client.js
index f14a7f7..6918da4 100644
--- a/dev/js/src/plugin/client.js
+++ b/dev/js/src/plugin/client.js
@@ -8,6 +8,19 @@
* @author Nils Diewald
*/
+/*
+* TODO:
+* Some methods require bidirectional
+* calling, like
+* - getKoralQuery()
+* this probably should be done using a callback,
+* like fetch({data}, function () {}, '*'), that will
+* add a unique ID to the message and will call on the cb
+* once the answer to that message arrives.
+*/
+
+var cs = document.currentScript;
+
(function () {
"use strict";
@@ -24,16 +37,18 @@
* Initialize plugin
*/
_init : function () {
- console.log('Init');
+ this.widgetID = window.name;
+ this.server = cs.getAttribute('data-server') || '*';
this.resize();
return this;
},
// Send a message
_sendMsg : function (data) {
+ data["originID"] = this.widgetID;
// TODO: This should send a correct origin
- window.parent.postMessage(data, '*');
+ window.parent.postMessage(data, this.server);
},
/**
@@ -54,8 +69,6 @@
resize : function () {
var body = document.body;
- console.log('Resize');
-
// recognize margin of first element
// (don't know why in FF)
var cs = getComputedStyle(body.children[0]);
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index 01dddac..db59422 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -8,9 +8,20 @@
* @author Nils Diewald
*/
-define(["util"], function () {
+define(["plugin/widget", "util"], function (widgetClass) {
"use strict";
+ // TODO:
+ // This is a counter to limit acceptable incoming messages
+ // to hundred. For every message, this will be decreased
+ // (down to 0), for every second this will be increased
+ // (up to 100).
+ var c = 100;
+
+ // Contains all widgets to address with
+ // messages to them
+ var widgets = {};
+
return {
/**
@@ -35,17 +46,22 @@
/**
* Open a new widget on a certain element
- * TODO: and register
*/
addWidget : function (element, src) {
- // Spawn new iframe
- var iframe = element.addE('iframe');
- iframe.setAttribute('allowTransparency',"true");
- iframe.setAttribute('frameborder',0);
- iframe.setAttribute('sandbox','allow-scripts');
- iframe.classList.add('widget');
- iframe.setAttribute('src', src);
+ // Create a unique random ID per widget
+ var id = 'id-' + this._randomID();
+
+ // Create a new widget
+ var widget = widgetClass.create(src, id);
+
+ // Store the widget based on the identifier
+ widgets[id] = widget;
+
+ // Open widget in frontend
+ element.appendChild(
+ widget.element()
+ );
},
// Receive a call from an embedded iframe
@@ -53,30 +69,37 @@
// Get event data
var d = e.data;
- // TODO: Check for e.origin!
+ // e.origin is probably set and okay
- // TODO: Deal with mad iframes
-
+ // TODO:
+ // Deal with mad iframes
+
+ // Get the widget
+ var widget = widgets[d["originID"]];
+
+ // If the addressed widget does not exist - fail
+ if (!widget)
+ return;
+
+
// Resize the iframe
if (d.action === 'resize') {
- // TODO: Check which iframe it was
- // var iframe = document.getElementById('?');
-
- // this.resize(iframe, d);
- console.log('Resizing not yet implemented');
+ widget.resize(d);
}
// Log message from iframe
else if (d.action === 'log') {
KorAP.log(d.code, d.msg);
- }
+ };
+
+ // TODO:
+ // Close
},
-
- // Resize the calling iframe
- resize : function (iframe, d) {
- iframe.style.height = d.height + 'px';
+ // Get a random identifier
+ _randomID : function () {
+ return randomID(20);
}
}
});
diff --git a/dev/js/src/plugin/widget.js b/dev/js/src/plugin/widget.js
new file mode 100644
index 0000000..4c2f09c
--- /dev/null
+++ b/dev/js/src/plugin/widget.js
@@ -0,0 +1,54 @@
+/**
+ * The plugin system is based
+ * on registered widgets (iframes) from
+ * foreign services.
+ * The widget component represents a single iframe.
+ *
+ * @author Nils Diewald
+ */
+
+define(["util"], function () {
+ "use strict";
+
+ return {
+
+ /**
+ * Create new widget
+ */
+ create : function (src, id) {
+ return Object.create(this)._init(src, id);
+ },
+
+ _init : function (src, id) {
+ this.src = src;
+ this.id = id;
+ return this;
+ },
+
+ /**
+ * The element of the widget
+ */
+ element : function () {
+
+ if (this._element)
+ return this._element;
+
+ // Spawn new iframe
+ var i = document.createElement('iframe');
+ i.setAttribute('allowTransparency',"true");
+ i.setAttribute('frameborder', 0);
+ i.setAttribute('sandbox','allow-scripts');
+ i.classList.add('widget');
+ i.setAttribute('name', this.id);
+ i.setAttribute('src', this.src);
+ this._element = i;
+
+ return i;
+ },
+
+ // Resize iframe
+ resize : function (data) {
+ this._element.style.height = data.height + 'px';
+ }
+ }
+});
diff --git a/dev/js/src/util.js b/dev/js/src/util.js
index 5b6c8f8..80f6364 100644
--- a/dev/js/src/util.js
+++ b/dev/js/src/util.js
@@ -59,6 +59,24 @@
return e.keyCode;
};
+function _dec2hex (dec) {
+ return ('0' + dec.toString(16)).substr(-2)
+};
+
+
+/**
+ * Create random identifiers
+ */
+/*
+ * code based on
+ * https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript#8084248
+ */
+function randomID (len) {
+ var arr = new Uint8Array((len || 40) / 2)
+ window.crypto.getRandomValues(arr)
+ return Array.from(arr, _dec2hex).join('')
+};
+
define(function () {
// Todo: That's double now!