@eclipse-scout/core 22.0.11 → 22.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/eclipse-scout-core-d110a434bcc809661ce5.min.js +2 -0
  2. package/dist/eclipse-scout-core-d110a434bcc809661ce5.min.js.map +1 -0
  3. package/dist/eclipse-scout-core-theme-dark-fd0e080c10f65e67b68b.min.css +1 -0
  4. package/dist/eclipse-scout-core-theme-dark.css +20 -5
  5. package/dist/eclipse-scout-core-theme-dark.css.map +1 -1
  6. package/dist/eclipse-scout-core-theme-f3a61fbc12acf8e27fcc.min.css +1 -0
  7. package/dist/eclipse-scout-core-theme.css +20 -5
  8. package/dist/eclipse-scout-core-theme.css.map +1 -1
  9. package/dist/eclipse-scout-core.js +184 -105
  10. package/dist/eclipse-scout-core.js.map +1 -1
  11. package/dist/file-list +4 -4
  12. package/package.json +2 -2
  13. package/src/App.js +1 -0
  14. package/src/desktop/DesktopDense.less +24 -6
  15. package/src/desktop/OpenUriHandler.js +5 -5
  16. package/src/form/fields/FormField.js +1 -1
  17. package/src/form/fields/datefield/DateField.js +2 -0
  18. package/src/form/fields/sequencebox/SequenceBox.js +20 -3
  19. package/src/form/fields/stringfield/StringField.js +9 -1
  20. package/src/session/Session.js +21 -18
  21. package/src/table/Table.js +2 -3
  22. package/src/table/columns/ColumnOptimalWidthMeasurer.js +1 -1
  23. package/src/testing/JasmineScoutUtil.js +127 -0
  24. package/src/testing/index.js +7 -3
  25. package/src/tile/TileGrid.js +5 -15
  26. package/src/tile/TileGridLayout.js +21 -11
  27. package/src/tile/accordion/TileAccordion.js +4 -23
  28. package/src/tile/accordion/TileAccordionLayout.js +39 -2
  29. package/src/tree/Tree.js +4 -0
  30. package/src/util/arrays.js +4 -0
  31. package/src/util/objects.js +4 -1
  32. package/src/widget/FilterSupport.js +19 -8
  33. package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js +0 -2
  34. package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js.map +0 -1
  35. package/dist/eclipse-scout-core-theme-74b63e0d57bed407a729.min.css +0 -1
  36. package/dist/eclipse-scout-core-theme-dark-b82aea152f416e38ce7f.min.css +0 -1
package/dist/file-list CHANGED
@@ -1,9 +1,9 @@
1
- eclipse-scout-core-e5e8740e3649f5b9f279.min.js
2
- eclipse-scout-core-e5e8740e3649f5b9f279.min.js.map
3
- eclipse-scout-core-theme-74b63e0d57bed407a729.min.css
4
- eclipse-scout-core-theme-dark-b82aea152f416e38ce7f.min.css
1
+ eclipse-scout-core-d110a434bcc809661ce5.min.js
2
+ eclipse-scout-core-d110a434bcc809661ce5.min.js.map
3
+ eclipse-scout-core-theme-dark-fd0e080c10f65e67b68b.min.css
5
4
  eclipse-scout-core-theme-dark.css
6
5
  eclipse-scout-core-theme-dark.css.map
6
+ eclipse-scout-core-theme-f3a61fbc12acf8e27fcc.min.css
7
7
  eclipse-scout-core-theme.css
8
8
  eclipse-scout-core-theme.css.map
9
9
  eclipse-scout-core.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclipse-scout/core",
3
- "version": "22.0.11",
3
+ "version": "22.0.19",
4
4
  "description": "Eclipse Scout runtime",
5
5
  "author": "BSI Business Systems Integration AG",
6
6
  "homepage": "https://www.eclipse.org/scout",
@@ -26,7 +26,7 @@
26
26
  "src"
27
27
  ],
28
28
  "devDependencies": {
29
- "@eclipse-scout/cli": "22.0.11",
29
+ "@eclipse-scout/cli": "22.0.19",
30
30
  "@eclipse-scout/releng": "^22.0.0",
31
31
  "jasmine-core": "3.10.1",
32
32
  "jasmine-ajax": "4.0.0",
package/src/App.js CHANGED
@@ -62,6 +62,7 @@ export default class App {
62
62
  * @param {string|string[]} [options.bootstrap.textsUrl] URL or multiple URLs pointing to a json resource containing texts that will be available through texts.js.
63
63
  * @param {string} [options.bootstrap.localesUrl] URL pointing to a json resource containing locale information processed by locales.js
64
64
  * @param {string} [options.bootstrap.codesUrl] URL pointing to a json resources containing codes that will be available through codes.js
65
+ * @param {object} [options.session] Object to configure the session, see {@link Session.init} for the available options.
65
66
  */
66
67
  init(options) {
67
68
  options = options || {};
@@ -1,9 +1,9 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -50,7 +50,8 @@
50
50
 
51
51
  .menubar:not(.main-menubar) {
52
52
  & > .menubar-box {
53
- & > .menu-item {
53
+ & > .menu-item,
54
+ & > .combo-menu > .menu-item {
54
55
  padding-top: 3px; /* @menubar-item-padding-y; */
55
56
  padding-bottom: 3px; /* @menubar-item-padding-y; */
56
57
 
@@ -58,10 +59,22 @@
58
59
  min-height: @logical-grid-row-height-dense; /* @logical-grid-row-height; */
59
60
  }
60
61
 
61
- & > .menu-button {
62
+ & > .menu-button,
63
+ & > .combo-menu > .menu-button {
62
64
  padding-top: 2px;
63
65
  padding-bottom: 2px;
64
66
  }
67
+
68
+ & > .combo-menu {
69
+ padding: 0;
70
+ }
71
+
72
+ & > .form-field-menu {
73
+ padding-top: 0;
74
+ padding-bottom: 0;
75
+ margin-top: 0;
76
+ margin-bottom: 0;
77
+ }
65
78
  }
66
79
  }
67
80
 
@@ -155,14 +168,18 @@
155
168
  }
156
169
  }
157
170
 
158
-
159
171
  /* ContextMenuPopup.less */
160
172
 
161
173
  .context-menu {
162
- & > .menu-item {
174
+ & > .menu-item,
175
+ & > .combo-menu > .menu-item {
163
176
  padding-top: 6px; /* padding: 11px 15px; */
164
177
  padding-bottom: 6px;
165
178
  }
179
+
180
+ & > .combo-menu {
181
+ padding: 0;
182
+ }
166
183
  }
167
184
 
168
185
  /* CheckBoxField.less */
@@ -279,6 +296,7 @@
279
296
  }
280
297
 
281
298
  /* BreadcrumbItem.less */
299
+
282
300
  .breadcrumb-item {
283
301
  font-size: @font-size-normal;
284
302
  }
@@ -1,9 +1,9 @@
1
1
  /*
2
- * Copyright (c) 2014-2018 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -50,7 +50,7 @@ export default class OpenUriHandler {
50
50
  } else {
51
51
  this.openUriAsNewWindow(uri);
52
52
  }
53
- } else if (Device.get().browser === Device.Browser.CHROME) {
53
+ } else if (Device.get().browser === Device.Browser.CHROME && this.isUriWithExternallyHandledProtocol(uri)) {
54
54
  // "Hidden iframe"-solution is not working in Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=663325)
55
55
  this.openUriInSameWindow(uri);
56
56
  } else {
@@ -59,7 +59,7 @@ export default class OpenUriHandler {
59
59
  }
60
60
 
61
61
  isUriWithExternallyHandledProtocol(uri) {
62
- return /^(callto|facetime|fax|geo|mailto|maps|notes|sip|skype|tel|google.navigation):/.test(uri);
62
+ return /^(callto|facetime|fax|geo|mailto|maps|notes|sip|skype|tel|google.navigation|sms|msteams):/.test(uri);
63
63
  }
64
64
 
65
65
  handleUriActionOpen(uri) {
@@ -69,7 +69,7 @@ export default class OpenUriHandler {
69
69
  // Additionally, some url types require to be opened in the same window like tel or mailto, at least on mobile devices
70
70
  this.openUriInSameWindow(uri);
71
71
  } else if (this.isUriWithExternallyHandledProtocol(uri)) {
72
- if (Device.get().browser === Device.Browser.CHROME) {
72
+ if (Device.get().browser === Device.Browser.CHROME || Device.get().isAndroid()) {
73
73
  // "Hidden iframe"-solution is not working in Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=663325)
74
74
  this.openUriInSameWindow(uri);
75
75
  } else {
@@ -1134,7 +1134,7 @@ export default class FormField extends Widget {
1134
1134
  if (!this.fieldStatus) {
1135
1135
  return;
1136
1136
  }
1137
- this.fieldStatus.remove();
1137
+ this.fieldStatus.destroy();
1138
1138
  this.$status = null;
1139
1139
  this.fieldStatus = null;
1140
1140
  }
@@ -205,6 +205,7 @@ export default class DateField extends ValueField {
205
205
  this.htmlDateTimeComposite.invalidateLayoutTree();
206
206
  }
207
207
  this._renderDateClearable();
208
+ this.$container.toggleClass('has-date', this.hasDate);
208
209
  }
209
210
 
210
211
  setHasTime(hasTime) {
@@ -257,6 +258,7 @@ export default class DateField extends ValueField {
257
258
  this.htmlDateTimeComposite.invalidateLayoutTree();
258
259
  }
259
260
  this._renderTimeClearable();
261
+ this.$container.toggleClass('has-time', this.hasTime);
260
262
  }
261
263
 
262
264
  setTimePickerResolution(timePickerResolution) {
@@ -1,9 +1,9 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -19,6 +19,8 @@ export default class SequenceBox extends CompositeField {
19
19
  this.logicalGrid = scout.create('scout.HorizontalGrid');
20
20
  this.layoutConfig = null;
21
21
  this.fields = [];
22
+ this._fieldPropertyChangeHandler = this._onFieldPropertyChange.bind(this);
23
+ this._lastVisibleFieldSuppressStatusHandler = this._onLastVisibleFieldSuppressStatusChange.bind(this);
22
24
  }
23
25
 
24
26
  _init(model) {
@@ -65,7 +67,7 @@ export default class SequenceBox extends CompositeField {
65
67
  for (i = 0; i < this.fields.length; i++) {
66
68
  field = this.fields[i];
67
69
  field.labelUseUiWidth = true;
68
- field.on('propertyChange', this._onFieldPropertyChange.bind(this));
70
+ field.on('propertyChange', this._fieldPropertyChangeHandler);
69
71
  field.render(this.$field);
70
72
  this._modifyLabel(field);
71
73
 
@@ -83,6 +85,14 @@ export default class SequenceBox extends CompositeField {
83
85
  return new SequenceBoxLayout(this, this.layoutConfig);
84
86
  }
85
87
 
88
+ _remove() {
89
+ this.fields.forEach(f => f.off('propertyChange', this._fieldPropertyChangeHandler));
90
+ if (this._lastVisibleField) {
91
+ this._lastVisibleField.off('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
92
+ }
93
+ super._remove();
94
+ }
95
+
86
96
  /**
87
97
  * @override
88
98
  */
@@ -137,6 +147,7 @@ export default class SequenceBox extends CompositeField {
137
147
  _handleStatus(visibilityChanged) {
138
148
  if (visibilityChanged && this._lastVisibleField) {
139
149
  // if there is a new last visible field, make sure the status is shown on the previously last one
150
+ this._lastVisibleField.off('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
140
151
  this._lastVisibleField.setSuppressStatus(null);
141
152
  if (this._lastVisibleField.rendered) {
142
153
  this._lastVisibleField._renderErrorStatus();
@@ -184,6 +195,7 @@ export default class SequenceBox extends CompositeField {
184
195
 
185
196
  // Make sure the last field won't display a status (but shows status CSS class)
186
197
  this._lastVisibleField.setSuppressStatus(FormField.SuppressStatus.ICON);
198
+ this._lastVisibleField.on('propertyChange:suppressStatus', this._lastVisibleFieldSuppressStatusHandler);
187
199
  if (visibilityChanged) {
188
200
  // If the last field got invisible, make sure the new last field does not display a status anymore (now done by the seq box)
189
201
  if (this._lastVisibleField.rendered) {
@@ -194,6 +206,11 @@ export default class SequenceBox extends CompositeField {
194
206
  }
195
207
  }
196
208
 
209
+ _onLastVisibleFieldSuppressStatusChange(e) {
210
+ // do not change suppressStatus
211
+ e.preventDefault();
212
+ }
213
+
197
214
  setErrorStatus(errorStatus) {
198
215
  if (this._isOverwritingStatusFromField && !this._isErrorStatusOverwritten) {
199
216
  // was not overwritten, will be overwritten now -> backup old value
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2014-2018 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
@@ -255,6 +255,14 @@ export default class StringField extends BasicField {
255
255
  this.revalidateLayout();
256
256
  }
257
257
 
258
+ /**
259
+ * @override
260
+ */
261
+ _renderEnabled() {
262
+ super._renderEnabled();
263
+ this.revalidateLayout();
264
+ }
265
+
258
266
  setFormatUpper(formatUpper) {
259
267
  if (formatUpper) {
260
268
  this.setFormat(StringField.Format.UPPER);
@@ -100,36 +100,39 @@ export default class Session {
100
100
  static EMPTY_UPLOAD_FILENAME = '*empty*';
101
101
 
102
102
  /**
103
- * $entryPoint is required to create a new session.
104
- *
105
- * @param model The 'model' argument holds all optional values that may be used during
106
- * initialization (it is the same object passed to the scout.init() function).
107
- * @param [model.portletPartId]
108
- * Optional, default is 0. Necessary when multiple UI sessions are managed
109
- * by the same window (portlet support). Each session's partId must be unique.
110
- * @param model.clientSessionId
103
+ * @param {$} model.$entryPoint
104
+ * The HTML element that is used by the {@link Desktop} to render its content.
105
+ * @param {string} [model.portletPartId]
106
+ * Necessary when multiple UI sessions are managed by the same window (portlet support).
107
+ * Each session's partId must be unique. Default is 0.
108
+ * @param {string} [model.clientSessionId]
111
109
  * Identifies the 'client instance' on the UI server. If the property is not set
112
110
  * (which is the default case), the clientSessionId is taken from the browser's
113
111
  * session storage (per browser window, survives F5 refresh of page). If no
114
112
  * clientSessionId can be found, a new one is generated on the server.
115
- * @param [model.userAgent]
116
- * Default: DESKTOP
117
- * @param [model.backgroundJobPollingEnabled]
113
+ * @param {boolean} [model.forceNewClientSession]
114
+ * If set to true, the stored or passed clientSessionId will be ignored
115
+ * and a new one generated by the server.
116
+ * @param {UserAgent} [model.userAgent]
117
+ * By default the user agent for the running platform is used. Use this option if you want to set a custom one.
118
+ * @param {Locale|object} [model.locale]
119
+ * If not specified, {@link Locale.DEFAULT} is used.
120
+ * @param {boolean} [model.backgroundJobPollingEnabled]
118
121
  * Unless websockets is used, this property turns on (default) or off background
119
122
  * polling using an async ajax call together with setTimeout()
120
- * @param [model.suppressErrors]
123
+ * @param {boolean} [model.suppressErrors]
121
124
  * Basically added because of Jasmine-tests. When working with async tests that
122
125
  * use setTimeout(), sometimes the Jasmine-Maven plug-in fails and aborts the
123
126
  * build because there were console errors. These errors always happen in this
124
127
  * class. That's why we can skip suppress error handling with this flag.
125
- * @param [model.focusManagerActive]
128
+ * @param {boolean} [model.focusManagerActive]
126
129
  * Forces the focus manager to be active or not. If undefined, the value is
127
130
  * auto detected by Device.js.
128
- * @param [model.reconnectorOptions]
129
- * Optional, properties of this object are copied to the Session's reconnector
130
- * instance (see Reconnector.js).
131
- * @param [model.ajaxCallOptions]
132
- * Optional, properties of this object are copied to all instances of AjaxCall.js.
131
+ * @param {object} [model.reconnectorOptions]
132
+ * Properties of this object are copied to the Session's reconnector
133
+ * instance (see {@link Reconnector}).
134
+ * @param {object} [model.ajaxCallOptions]
135
+ * Properties of this object are copied to all instances of {@link AjaxCall}.
133
136
  */
134
137
  init(model) {
135
138
  let options = model || {};
@@ -5271,15 +5271,14 @@ export default class Table extends Widget {
5271
5271
 
5272
5272
  for (i = 0; i < columns.length; i++) {
5273
5273
  column = columns[i];
5274
- currentPosition = this.columns.indexOf(column);
5274
+ currentPosition = arrays.findIndex(this.columns, element => element.id === column.id);
5275
5275
  if (currentPosition < 0) {
5276
5276
  throw new Error('Column with id ' + column.id + 'not found.');
5277
5277
  }
5278
5278
 
5279
5279
  if (currentPosition !== i) {
5280
5280
  // Update model
5281
- arrays.remove(this.columns, column);
5282
- arrays.insert(this.columns, column, i);
5281
+ arrays.move(this.columns, currentPosition, i);
5283
5282
  }
5284
5283
  }
5285
5284
 
@@ -147,7 +147,7 @@ export default class ColumnOptimalWidthMeasurer {
147
147
  _build$CellForAggregateRow(row) {
148
148
  let columns = this.table.visibleColumns();
149
149
  let colIndex = columns.indexOf(this.column);
150
- let $row = this.table._buildAggregateRowDiv(row);
150
+ let $row = this.table._build$AggregateRow(row);
151
151
 
152
152
  $row.appendTo(this.table.$data);
153
153
  columns
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
+ * All rights reserved. This program and the accompanying materials
4
+ * are made available under the terms of the Eclipse Public License v1.0
5
+ * which accompanies this distribution, and is available at
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
+ *
8
+ * Contributors:
9
+ * BSI Business Systems Integration AG - initial API and implementation
10
+ */
11
+ import {arrays, scout, strings} from '../index';
12
+ import $ from 'jquery';
13
+
14
+ let _jsonResourceCache = {};
15
+
16
+ /**
17
+ * Utility functions for jasmine tests.
18
+ */
19
+ export const JasmineScoutUtil = {
20
+
21
+ /**
22
+ * @param {string} jsonResourceUrl
23
+ * @param {object} [options]
24
+ * @param {boolean} [options.useCache=true]
25
+ * @return {Promise<object>} - the loaded JSON data structure
26
+ */
27
+ loadJsonResource(jsonResourceUrl, options = {}) {
28
+ scout.assertParameter('jsonResourceUrl', jsonResourceUrl);
29
+
30
+ if (scout.nvl(options.useCache, true)) {
31
+ let json = _jsonResourceCache[jsonResourceUrl];
32
+ if (json) {
33
+ return $.resolvedPromise(json);
34
+ }
35
+ }
36
+
37
+ return $.ajax({
38
+ async: false,
39
+ type: 'GET',
40
+ dataType: 'json',
41
+ contentType: 'application/json; charset=UTF-8',
42
+ cache: false,
43
+ url: jsonResourceUrl
44
+ })
45
+ .done(json => {
46
+ if (scout.nvl(options.useCache, true)) {
47
+ _jsonResourceCache[jsonResourceUrl] = json;
48
+ }
49
+ return $.resolvedPromise(json);
50
+ })
51
+ .fail((jqXHR, textStatus, errorThrown) => {
52
+ throw new Error('Could not load resource from url: ' + jsonResourceUrl);
53
+ });
54
+ },
55
+
56
+ /**
57
+ * @param {string} resourceUrlToMock
58
+ * @param {string} jsonResourceUrl
59
+ * @param {object} [options]
60
+ * @param {boolean} [options.useCache=true]
61
+ * @param {*} [options.restriction]
62
+ * @param {string} [options.method]
63
+ */
64
+ loadJsonResourceAndMockRestCall(resourceUrlToMock, jsonResourceUrl, options = {}) {
65
+ scout.assertParameter('resourceUrlToMock', resourceUrlToMock);
66
+
67
+ this.loadJsonResource(jsonResourceUrl, options)
68
+ .then(json => this.mockRestCall(resourceUrlToMock, json, options));
69
+ },
70
+
71
+ /**
72
+ * @param {string} resourceUrlToMock
73
+ * @param {array} lookupRows
74
+ * @param {*} [parentRestriction]
75
+ */
76
+ mockRestLookupCall(resourceUrlToMock, lookupRows, parentRestriction) {
77
+ scout.assertParameter('resourceUrlToMock', resourceUrlToMock);
78
+
79
+ // Normalize lookup rows
80
+ lookupRows = arrays.ensure(lookupRows).map(lookupRow => $.extend({
81
+ active: true,
82
+ enabled: true,
83
+ parentId: null
84
+ }, lookupRow));
85
+
86
+ // getAll()
87
+ this.mockRestCall(resourceUrlToMock, {
88
+ rows: lookupRows
89
+ }, {
90
+ restriction: parentRestriction
91
+ });
92
+
93
+ // getKey()
94
+ lookupRows.forEach(lookupRow => {
95
+ this.mockRestCall(resourceUrlToMock, {
96
+ rows: [lookupRow]
97
+ }, {
98
+ restriction: lookupRow.id
99
+ });
100
+ });
101
+ },
102
+
103
+ /**
104
+ * @param {string} resourceUrlToMock
105
+ * @param {*} responseData
106
+ * @param {object} [options]
107
+ * @param {*} [options.restriction]
108
+ * @param {string} [options.method]
109
+ */
110
+ mockRestCall(resourceUrlToMock, responseData, options = {}) {
111
+ let url = new RegExp('.*' + strings.quote(resourceUrlToMock) + '.*');
112
+ let data = options.restriction ? new RegExp('.*' + strings.quote(options.restriction) + '.*') : undefined;
113
+ jasmine.Ajax.stubRequest(url, data, options.method).andReturn({
114
+ status: 200,
115
+ responseText: JSON.stringify(responseData)
116
+ });
117
+ },
118
+
119
+ /**
120
+ * If a ajax call is not mocked, this fallback will be triggered to show information about which url is not mocked.
121
+ */
122
+ captureNotMockedCalls() {
123
+ jasmine.Ajax.stubRequest(/.*/).andCallFunction((stub, mockAjax) => {
124
+ fail('Ajax call not mocked for url: ' + mockAjax.url + ', method: ' + mockAjax.method);
125
+ });
126
+ }
127
+ };
@@ -8,8 +8,14 @@
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
10
10
  */
11
+
12
+ // /////////////////////////////////////////////////////////////////
13
+ // TEST SUPPORT - DO NOT USE IN PRODUCTION CODE
14
+ // /////////////////////////////////////////////////////////////////
15
+
11
16
  export {default as TestingApp} from './TestingApp';
12
17
  export {default as JasmineScout} from './JasmineScout';
18
+ export {JasmineScoutUtil} from './JasmineScoutUtil';
13
19
  export {default as LocaleSpecHelper} from './text/LocaleSpecHelper';
14
20
  export {default as MenuSpecHelper} from './menu/MenuSpecHelper';
15
21
  export {default as TreeSpecHelper} from './tree/TreeSpecHelper';
@@ -31,6 +37,4 @@ export {default as GroupBoxSpecHelper} from './form/fields/groupbox/GroupBoxSpec
31
37
  import * as self from './index.js';
32
38
 
33
39
  export default self;
34
- if (window) {
35
- window.scout = Object.assign(window.scout || {}, self);
36
- }
40
+ window.scout = Object.assign(window.scout || {}, self);
@@ -1,9 +1,9 @@
1
1
  /*
2
- * Copyright (c) 2010-2021 BSI Business Systems Integration AG.
2
+ * Copyright (c) 2010-2022 BSI Business Systems Integration AG.
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -42,8 +42,6 @@ export default class TileGrid extends Widget {
42
42
  this.selectedTiles = [];
43
43
  this.selectionHandler = new TileGridSelectionHandler(this);
44
44
  this.scrollable = true;
45
- this.scrolling = false;
46
- this.scrollTopDirty = false;
47
45
  this.startupAnimationDone = false;
48
46
  this.startupAnimationEnabled = false;
49
47
  this.tiles = [];
@@ -594,18 +592,14 @@ export default class TileGrid extends Widget {
594
592
  let scrollTop = this.$container[0].scrollTop;
595
593
  let scrollLeft = this.$container[0].scrollLeft;
596
594
  if (this.scrollTop !== scrollTop && this.virtual) {
597
- this.scrolling = true;
598
- this.revalidateLayout();
599
- this.scrolling = false;
595
+ this.htmlComp.layout.updateViewPort();
600
596
  }
601
597
  this.scrollTop = scrollTop;
602
598
  this.scrollLeft = scrollLeft;
603
599
  }
604
600
 
605
601
  _onScrollParentScroll(event) {
606
- this.scrolling = true;
607
- this.revalidateLayoutTree(false);
608
- this.scrolling = false;
602
+ this.htmlComp.layout.updateViewPort();
609
603
  }
610
604
 
611
605
  setWithPlaceholders(withPlaceholders) {
@@ -961,12 +955,8 @@ export default class TileGrid extends Widget {
961
955
  this.ensureTileRendered(tile);
962
956
  // If tile was not rendered it is not yet positioned correctly -> make sure layout is valid before trying to scroll
963
957
  // Layout must not render the viewport because scroll position is not correct yet -> just make sure tiles are at the correct position
964
- this.scrolling = true;
965
- this.scrollTopDirty = true;
966
- this.validateLayoutTree();
967
- this.scrolling = false;
958
+ this.htmlComp.layout.updateViewPort(true);
968
959
  tile.reveal(options);
969
- this.scrollTopDirty = false;
970
960
  }
971
961
 
972
962
  revealSelection() {
@@ -3,7 +3,7 @@
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -44,19 +44,29 @@ export default class TileGridLayout extends LogicalGridLayout {
44
44
  this.maxWidth = -1;
45
45
  }
46
46
 
47
- layout($container) {
48
- let htmlComp = this.widget.htmlComp;
49
- if (this.widget.scrolling) {
50
- // Try to layout only as much as needed while scrolling in virtual mode
51
- // Scroll top may be dirty when layout is validated before scrolling to a specific tile (see tileGrid.scrollTo)
52
- if (!this.widget.scrollTopDirty) {
53
- this.widget._renderViewPort();
54
- }
55
- this._layout($container);
56
- this.widget.trigger('layoutAnimationDone');
47
+ /**
48
+ *
49
+ * @param {boolean} [scrollTopDirty] If the scroll top position should be considered dirty while updating the view port.
50
+ * If true, the view port is not rendered, as the scroll positions are not reliable anyway. Then only the layout of the TileGrid is updated.
51
+ */
52
+ updateViewPort(scrollTopDirty) {
53
+ let tileGrid = this.widget;
54
+ if (!tileGrid.rendered) {
57
55
  return;
58
56
  }
59
57
 
58
+ // Try to layout only as much as needed while scrolling in virtual mode
59
+ // Scroll top may be dirty when layout is validated before scrolling to a specific tile (see tileGrid.scrollTo)
60
+ if (!scout.nvl(scrollTopDirty, false)) {
61
+ tileGrid._renderViewPort();
62
+ }
63
+ this._layout(tileGrid.$container);
64
+ tileGrid.trigger('layoutAnimationDone');
65
+ }
66
+
67
+ layout($container) {
68
+ let htmlComp = this.widget.htmlComp;
69
+
60
70
  // Animate only once on startup (if enabled) but animate every time on resize
61
71
  let animated = htmlComp.layouted || (this.widget.startupAnimationEnabled && !this.widget.startupAnimationDone) || this.widget.renderAnimationEnabled;
62
72
  this.tiles = this.widget.renderedTiles();
@@ -3,7 +3,7 @@
3
3
  * All rights reserved. This program and the accompanying materials
4
4
  * are made available under the terms of the Eclipse Public License v1.0
5
5
  * which accompanies this distribution, and is available at
6
- * http://www.eclipse.org/legal/epl-v10.html
6
+ * https://www.eclipse.org/legal/epl-v10.html
7
7
  *
8
8
  * Contributors:
9
9
  * BSI Business Systems Integration AG - initial API and implementation
@@ -350,24 +350,7 @@ export default class TileAccordion extends Accordion {
350
350
  }
351
351
 
352
352
  _filter() {
353
- this.groups.forEach(group => {
354
- group.body.filter();
355
-
356
- // If the layout has not been invalidated as part of the filtering above, it even though must be validated here.
357
- // This is because groups above might have fewer visible Tiles now which makes room for this group.
358
- // The revalidateLayout() with scrolling=true here ensures TileGrid._renderViewPort() is called to ensure these Tiles become visible as there is space available now.
359
- // It is executed as postValidateFunction because the groups above must have completed their layouting so that
360
- // TileGrid._renderViewPort() knows that there is more space available now.
361
- if (group.body.htmlComp && group.body.htmlComp.valid && !group.body._accordionLayoutHandler /* skip if already registered */) {
362
- group.body._accordionLayoutHandler = () => {
363
- group.body.scrolling = true;
364
- group.body.revalidateLayout();
365
- group.body.scrolling = false;
366
- group.body._accordionLayoutHandler = null;
367
- };
368
- this.session.layoutValidator.schedulePostValidateFunction(group.body._accordionLayoutHandler);
369
- }
370
- });
353
+ this.groups.forEach(group => group.body.filter());
371
354
  }
372
355
 
373
356
  /**
@@ -700,10 +683,8 @@ export default class TileAccordion extends Accordion {
700
683
  // Btw: another group may be doing it as well at the same time (e.g. because of exclusiveExpand)
701
684
  return;
702
685
  }
703
- if (group.body.virtual) {
704
- group.body.scrolling = true;
705
- group.body.revalidateLayout();
706
- group.body.scrolling = false;
686
+ if (group.body.virtual && group.body.htmlComp) {
687
+ group.body.htmlComp.layout.updateViewPort();
707
688
  }
708
689
  });
709
690
  }