Desktop: prevent incorrect filtering of 'formActive' event
Problem:
When the UI server hides the current form and instead shows another
form, the handling of the "hide form" event causes a 'formActive=null'
event to be sent to the server (queued). When later the "show form"
event is processed, an event filter prevents that a second 'formActive'
event (with the new form as value) is sent to the server. As a
consequence, the UI server will no longer have the same state as the
browser.
Solution:
Before adding the event filter, DesktopAdapter needs to check if the
current request queue contains a 'formActivate' event. If yes, the event
filter must not be added.
253018
Change-Id: I9c1f1d663f6d9cfb7804b7f1e4390f2cc6f79f00
Reviewed-on: https://git.eclipse.org/r/147847
Tested-by: CI Bot
Reviewed-by: Claudio Guglielmo <claudio.guglielmo@bsiag.com>
diff --git a/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/desktop/DesktopAdapterSpec.js b/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/desktop/DesktopAdapterSpec.js
index e3c3117..b83e033 100644
--- a/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/desktop/DesktopAdapterSpec.js
+++ b/org.eclipse.scout.rt.ui.html.test/src/test/js/scout/desktop/DesktopAdapterSpec.js
@@ -72,6 +72,89 @@
});
expect(mostRecentJsonRequest()).toContainEvents(event);
});
+
+ it('can close and open new form in the same response', function() {
+ var formModel = createAndRegisterFormModel();
+ var form = session.getOrCreateWidget(formModel.id, desktop);
+ desktop.dialogs = [form];
+ session._renderDesktop();
+
+ desktop.activateForm(form);
+ expect(desktop.activeForm).toBe(form);
+
+ expect(jasmine.Ajax.requests.count()).toBe(0);
+
+ sendQueuedAjaxCalls();
+ expect(jasmine.Ajax.requests.count()).toBe(1);
+
+ // ------------------------
+
+ // Close form and open new form --> new form must be activated
+
+ var response = {
+ adapterData: {
+ '400': {
+ displayHint: 'view',
+ global: true,
+ id: '400',
+ objectType: 'Form',
+ owner: '1',
+ rootGroupBox: '401'
+ },
+ '401': {
+ fields: [],
+ id: '401',
+ objectType: 'GroupBox',
+ owner: '400'
+ }
+ },
+ events: [
+ {
+ target: desktopAdapter.id,
+ type: 'formHide',
+ displayParent: desktopAdapter.id,
+ form: formModel.id
+ },
+ {
+ target: desktopAdapter.id,
+ type: 'formShow',
+ displayParent: desktopAdapter.id,
+ form: '400'
+ }
+ ]
+ };
+ session._processSuccessResponse(response);
+ sendQueuedAjaxCalls();
+
+ var expectedEvents = [
+ new scout.RemoteEvent(desktopAdapter.id, 'formActivate', {
+ formId: null
+ }),
+ new scout.RemoteEvent(desktopAdapter.id, 'formActivate', {
+ formId: '400'
+ })
+ ];
+ expect(mostRecentJsonRequest()).toContainEventsExactly(expectedEvents);
+ expect(jasmine.Ajax.requests.count()).toBe(2);
+
+ // ------------------------
+
+ // Only hide form --> no formActivate event is sent
+
+ response = {
+ events: [
+ {
+ target: desktopAdapter.id,
+ type: 'formHide',
+ displayParent: desktopAdapter.id,
+ form: '400'
+ }
+ ]
+ };
+ session._processSuccessResponse(response);
+ sendQueuedAjaxCalls();
+ expect(jasmine.Ajax.requests.count()).toBe(2);
+ });
});
describe('onFormShow', function() {
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/desktop/DesktopAdapter.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/desktop/DesktopAdapter.js
index 9632a36..d643452 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout/desktop/DesktopAdapter.js
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/desktop/DesktopAdapter.js
@@ -66,11 +66,17 @@
if (displayParent) {
form = this.session.getOrCreateWidget(event.form, displayParent.widget);
- this.addFilterForWidgetEvent(function(widgetEvent) {
- return (widgetEvent.type === 'formActivate' &&
- widgetEvent.form === form);
- });
form.setDisplayParent(displayParent.widget);
+
+ var hasPendingFormActivateEvent = this.session.asyncEvents.some(function(event) {
+ return event.type === 'formActivate' && event.target === this.id;
+ }, this);
+ if (!hasPendingFormActivateEvent) {
+ this.addFilterForWidgetEvent(function(widgetEvent) {
+ return (widgetEvent.type === 'formActivate' && widgetEvent.form === form);
+ }.bind(this));
+ }
+
this.widget.showForm(form, event.position);
}
};