Support toggle+widget buttons in plugin-framework
Change-Id: Ibf2b80efc1eeda2f51dedf4a7f3cd5ac67325ef9
diff --git a/dev/js/src/buttongroup.js b/dev/js/src/buttongroup.js
index 40eb61f..922ca1c 100644
--- a/dev/js/src/buttongroup.js
+++ b/dev/js/src/buttongroup.js
@@ -83,6 +83,7 @@
const b = this._insert('span');
let desc = title;
+ let that = this;
if (data !== undefined) {
if (data['cls'] !== undefined) {
b.classList.add.apply(b.classList, data['cls']);
@@ -98,14 +99,21 @@
if (data['active'] !== undefined) {
let active = data['active'];
+ b['active'] = active;
- let check = _addCheck(b,active);
- check.addEventListener('click', function (e) {
- // Do not bubble
- e.halt();
+ let check = _addCheck(b,active);
+ check.addEventListener('click', function (e) {
+ // Do not bubble
+ e.halt();
// Toggle state
- active.roll();
- });
+ active.roll();
+
+ let obj = that._bind || this;
+ obj.button = b;
+ b._activeClick = true;
+ cb.apply(obj, e);
+ b._activeClick = false;
+ });
};
@@ -119,10 +127,9 @@
innerSpan.addT(title);
b["changeTitle"] = function (title) {
- innerSpan.textContent = title;
+ innerSpan.textContent = title;
};
- let that = this;
b.addEventListener('click', function (e) {
// Do not bubble
diff --git a/dev/js/src/pipe.js b/dev/js/src/pipe.js
index f10853e..241b126 100644
--- a/dev/js/src/pipe.js
+++ b/dev/js/src/pipe.js
@@ -37,7 +37,7 @@
*/
append : function (service) {
service = _notNull(service);
- if (service) {
+ if (service && this._pipe.indexOf(service) === -1) {
this._pipe.push(service);
this._update();
};
@@ -49,7 +49,7 @@
*/
prepend : function (service) {
service = _notNull(service);
- if (service) {
+ if (service && this._pipe.indexOf(service) === -1) {
this._pipe.unshift(service);
this._update();
};
diff --git a/dev/js/src/plugin/server.js b/dev/js/src/plugin/server.js
index f8c9855..ab84ed3 100644
--- a/dev/js/src/plugin/server.js
+++ b/dev/js/src/plugin/server.js
@@ -161,6 +161,55 @@
// "this".button is the button
// "that" is the server object
+ // Active-check click: load iframe as a background service,
+ // not as a visible widget.
+ if (this.button._activeClick && 'active' in this.button) {
+
+ // Service already running - just return
+ // (active.roll() was already called in buttongroup)
+ if (this.button['widgetID'] &&
+ services[this.button['widgetID']]) {
+ return;
+ };
+
+ // For addWidget mode (no state), just toggle - no service
+ if (!('state' in this.button)) {
+ return;
+ };
+
+ // Create a background service (iframe in services container)
+ let id = that.addService({
+ "name": name,
+ "src": onClick["template"],
+ "permissions": onClick["permissions"]
+ });
+ plugin["widgets"].push(id);
+
+ this.button['widgetID'] = id;
+
+ // Store panel reference so 'get Active' works
+ services[id].panel = this;
+
+ let activeState = this.button.active;
+ let iframe = services[id].load();
+
+ iframe.onload = function () {
+ activeState.associate({
+ setState : function (value) {
+ if (services[id]) {
+ services[id].sendMsg({
+ action: 'state',
+ key : 'active',
+ value : value
+ });
+ };
+ }
+ });
+ };
+
+ return;
+ };
+
// The button has a state and the state is associated to the
// a intermediate object to toggle the view
if ('state' in this.button && this.button.state.associates() > 0) {
@@ -182,15 +231,26 @@
}
};
+ // If a background service exists (from active-check),
+ // close it before creating the widget
+ if ('active' in this.button &&
+ this.button['widgetID'] &&
+ services[this.button['widgetID']] &&
+ !services[this.button['widgetID']].isWidget) {
+ that._closeService(this.button['widgetID']);
+ this.button['widgetID'] = undefined;
+ };
+
// Add the widget to the panel
let id = that.addWidget(this, {
"name": name,
"src": onClick["template"], // that._interpolateURI(onClick["template"], this.match);
"permissions": onClick["permissions"],
- "desc":desc
+ "desc":desc,
+ "panel":panel
});
plugin["widgets"].push(id);
-
+
// If a state exists, associate with a mediator object
if ('state' in this.button) {
this.button['widgetID'] = id;
@@ -205,7 +265,29 @@
};
}
});
- }
+ };
+
+ // If an active state exists, associate it with the widget
+ // so active-state changes can be reflected in the iframe.
+ if ('active' in this.button) {
+ this.button['widgetID'] = id;
+ let first = true;
+ this.button.active.associate({
+ setState : function (value) {
+ if (first) {
+ first = false;
+ return;
+ };
+ if (services[id]) {
+ services[id].sendMsg({
+ action: 'state',
+ key : 'active',
+ value : value
+ });
+ };
+ }
+ });
+ };
};
@@ -215,6 +297,11 @@
if (embed['desc'] != undefined)
obj['desc'] = embed['desc'];
+ if (onClick['active'] !== undefined) {
+ obj['active'] = stateClass.create([true, false]);
+ obj['active'].setIfNotYet(onClick['active'] ? true : false);
+ };
+
if (onClick["action"] && onClick["action"] == "setWidget") {
// Create a boolean state value,
@@ -559,6 +646,14 @@
v["page"] = pi.page();
v["total"] = pi.total();
v["count"] = pi.count();
+ }
+
+ // Get active toggle state of the widget button
+ else if (d.key == 'Active') {
+ let button = services[d["originID"]].panel.button;
+ if (button && button.active) {
+ d["value"] = button.active.get();
+ };
};
// data needs to be mirrored
@@ -596,6 +691,24 @@
// if (v["cq"] != undefined) {};
}
+ else if (d.key == "Title") {
+ // TODO: Only support "Add title"!
+ let v = d["value"];
+ services[d["originID"]].panel.button.changeTitle(v);
+ }
+
+ else if (d.key == "Active") {
+ let v = d["value"];
+ let button = services[d["originID"]].panel.button;
+ if (button && button.active) {
+ if (v !== undefined) {
+ button.active.set(v);
+ } else {
+ button.active.roll();
+ };
+ };
+ };
+
break;
// Redirect to a different page relative to the current
diff --git a/dev/js/src/plugin/service.js b/dev/js/src/plugin/service.js
index ef6836c..7b4e998 100644
--- a/dev/js/src/plugin/service.js
+++ b/dev/js/src/plugin/service.js
@@ -107,10 +107,12 @@
*/
sendMsg : function (d) {
let iframe = this.load();
- iframe.contentWindow.postMessage(
- d,
- '*'
- ); // TODO: Fix origin
+ if (iframe && iframe.contentWindow) {
+ iframe.contentWindow.postMessage(
+ d,
+ '*'
+ ); // TODO: Fix origin
+ };
},
// onClose : function () {},