@eclipse-scout/core 22.0.1 → 22.0.11

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 (156) hide show
  1. package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js +2 -0
  2. package/dist/eclipse-scout-core-e5e8740e3649f5b9f279.min.js.map +1 -0
  3. package/dist/eclipse-scout-core-theme-74b63e0d57bed407a729.min.css +1 -0
  4. package/dist/eclipse-scout-core-theme-dark-b82aea152f416e38ce7f.min.css +1 -0
  5. package/dist/eclipse-scout-core-theme-dark.css +517 -361
  6. package/dist/eclipse-scout-core-theme-dark.css.map +1 -1
  7. package/dist/eclipse-scout-core-theme.css +300 -144
  8. package/dist/eclipse-scout-core-theme.css.map +1 -1
  9. package/dist/eclipse-scout-core.js +1150 -766
  10. package/dist/eclipse-scout-core.js.map +1 -1
  11. package/dist/file-list +7 -0
  12. package/dist/locales.json +47126 -0
  13. package/dist/texts.json +1153 -0
  14. package/package.json +2 -2
  15. package/src/ErrorHandler.js +66 -28
  16. package/src/{table/TableHeaderMenuButtonKeyStroke.js → action/ActionExecKeyStroke.js} +4 -5
  17. package/src/action/Button.less +1 -0
  18. package/src/box/Box.less +10 -6
  19. package/src/breadcrumbbar/BreadcrumbItem.less +3 -6
  20. package/src/calendar/Calendar.js +40 -58
  21. package/src/calendar/Calendar.less +10 -10
  22. package/src/calendar/CalendarLayout.js +3 -1
  23. package/src/checkbox/CheckBox.less +3 -1
  24. package/src/datepicker/DatePicker.less +1 -0
  25. package/src/datepicker/DatePickerTouchPopup.js +8 -0
  26. package/src/desktop/DisableBrowserF5ReloadKeyStroke.js +1 -0
  27. package/src/desktop/bench/DesktopTabSelectKeyStroke.js +2 -1
  28. package/src/desktop/desktoptab/DesktopTab.less +5 -2
  29. package/src/desktop/desktoptab/DesktopTabArea.less +7 -3
  30. package/src/desktop/desktoptab/DisableBrowserTabSwitchingKeyStroke.js +1 -0
  31. package/src/desktop/navigation/DesktopNavigation.less +4 -0
  32. package/src/desktop/navigation/EnlargeNavigationKeyStroke.js +1 -0
  33. package/src/desktop/navigation/ShrinkNavigationKeyStroke.js +1 -0
  34. package/src/desktop/notification/DesktopNotification.js +11 -4
  35. package/src/desktop/notification/DesktopNotification.less +5 -3
  36. package/src/desktop/outline/Outline.less +4 -4
  37. package/src/desktop/viewbutton/ViewButton.less +13 -9
  38. package/src/desktop/viewbutton/ViewMenuPopupEnterKeyStroke.js +2 -1
  39. package/src/desktop/viewbutton/ViewMenuTab.less +3 -2
  40. package/src/filechooser/FileChooser.js +1 -1
  41. package/src/filechooser/FileChooser.less +16 -11
  42. package/src/focus/FocusContext.js +11 -8
  43. package/src/focus/FocusManager.js +24 -5
  44. package/src/form/Form.less +1 -0
  45. package/src/form/fields/LookupBox.js +5 -2
  46. package/src/form/fields/LookupBox.less +28 -2
  47. package/src/form/fields/TextFieldIcon.less +2 -2
  48. package/src/form/fields/ValueField.js +11 -2
  49. package/src/form/fields/breadcrumbbarfield/BreadcrumbBarField.less +20 -0
  50. package/src/form/fields/button/ButtonKeyStroke.js +0 -3
  51. package/src/form/fields/datefield/DateField.js +31 -47
  52. package/src/form/fields/filechooserfield/FileChooserFieldBrowseKeyStroke.js +1 -3
  53. package/src/form/fields/filechooserfield/FileChooserFieldDeleteKeyStroke.js +1 -3
  54. package/src/form/fields/groupbox/GroupBox.js +14 -9
  55. package/src/form/fields/groupbox/GroupBox.less +1 -0
  56. package/src/form/fields/htmlfield/HtmlField.less +0 -1
  57. package/src/form/fields/listbox/ListBox.js +13 -7
  58. package/src/form/fields/lookupfield/lookupField.js +6 -5
  59. package/src/form/fields/smartfield/ProposalField.js +2 -1
  60. package/src/form/fields/smartfield/ProposalTreeNode.js +4 -8
  61. package/src/form/fields/smartfield/SmartField.js +4 -20
  62. package/src/form/fields/smartfield/SmartField.less +24 -11
  63. package/src/form/fields/splitbox/SplitBoxCollapseKeyStroke.js +1 -0
  64. package/src/form/fields/splitbox/SplitBoxFirstCollapseKeyStroke.js +1 -0
  65. package/src/form/fields/splitbox/SplitBoxSecondCollapseKeyStroke.js +1 -0
  66. package/src/form/fields/tabbox/TabAreaLayout.js +63 -66
  67. package/src/form/fields/tabbox/TabAreaLeftKeyStroke.js +2 -0
  68. package/src/form/fields/tabbox/TabAreaRightKeyStroke.js +2 -0
  69. package/src/form/fields/tabbox/TabBox.js +8 -7
  70. package/src/form/fields/tabbox/TabBox.less +2 -1
  71. package/src/form/fields/tabbox/TabBoxHeader.js +4 -0
  72. package/src/form/fields/tabbox/TabBoxHeaderLayout.js +5 -5
  73. package/src/form/fields/tabbox/TabItem.js +4 -0
  74. package/src/form/fields/treebox/TreeBox.js +6 -5
  75. package/src/glasspane/GlassPane.js +3 -3
  76. package/src/group/Group.less +1 -1
  77. package/src/index.js +1 -1
  78. package/src/index.less +1 -0
  79. package/src/jquery/jquery-scout.js +17 -4
  80. package/src/keystroke/CloseKeyStroke.js +1 -0
  81. package/src/keystroke/ContextMenuKeyStroke.js +1 -0
  82. package/src/keystroke/FocusFilterFieldKeyStroke.js +1 -0
  83. package/src/keystroke/KeyStroke.js +11 -3
  84. package/src/keystroke/TabItemKeyStroke.js +8 -5
  85. package/src/logging/logging.js +16 -8
  86. package/src/login/LoginBox.js +3 -2
  87. package/src/login/LoginBox.less +18 -1
  88. package/src/menu/ContextMenuPopup.less +9 -2
  89. package/src/menu/Menu.less +1 -0
  90. package/src/menu/MenuExecKeyStroke.js +3 -17
  91. package/src/menu/MenuNavigationKeyStroke.js +1 -0
  92. package/src/menu/menubar/MenuBarLeftKeyStroke.js +2 -0
  93. package/src/menu/menubar/MenuBarRightKeyStroke.js +2 -0
  94. package/src/messagebox/MessageBox.less +17 -17
  95. package/src/modeselector/Mode.less +15 -37
  96. package/src/modeselector/ModeSelector.js +1 -1
  97. package/src/modeselector/ModeSelector.less +2 -1
  98. package/src/planner/Planner.js +2 -0
  99. package/src/planner/PlannerHeader.less +2 -1
  100. package/src/popup/Popup.js +24 -8
  101. package/src/popup/PopupLayout.js +2 -8
  102. package/src/scrollbar/Scrollbar.less +8 -1
  103. package/src/scrollbar/scrollbars.js +26 -4
  104. package/src/session/Session.js +8 -5
  105. package/src/style/colors-dark.less +17 -10
  106. package/src/style/colors.less +11 -3
  107. package/src/style/fonts.less +10 -1
  108. package/src/style/mixins.less +16 -12
  109. package/src/style/sizes-dark.less +4 -1
  110. package/src/style/sizes.less +17 -9
  111. package/src/table/Table.js +62 -48
  112. package/src/table/Table.less +50 -20
  113. package/src/table/TableAdapter.js +9 -12
  114. package/src/table/TableHeader.js +10 -8
  115. package/src/table/TableHeader.less +1 -0
  116. package/src/table/TableHeaderMenu.js +3 -1
  117. package/src/table/TableHeaderMenu.less +7 -2
  118. package/src/table/TableHeaderMenuButton.js +2 -2
  119. package/src/table/TableLayout.js +6 -0
  120. package/src/table/columns/BooleanColumn.js +2 -2
  121. package/src/table/columns/Column.js +10 -7
  122. package/src/table/editor/CellEditorPopup.js +29 -15
  123. package/src/table/keystrokes/AbstractTableNavigationKeyStroke.js +1 -0
  124. package/src/table/keystrokes/TableCopyKeyStroke.js +1 -0
  125. package/src/table/keystrokes/TableNavigationCollapseKeyStroke.js +2 -2
  126. package/src/table/keystrokes/TableNavigationEndKeyStroke.js +2 -2
  127. package/src/table/keystrokes/TableNavigationExpandKeyStroke.js +2 -2
  128. package/src/table/keystrokes/TableNavigationHomeKeyStroke.js +2 -2
  129. package/src/table/keystrokes/TableNavigationPageDownKeyStroke.js +2 -2
  130. package/src/table/keystrokes/TableNavigationPageUpKeyStroke.js +2 -2
  131. package/src/table/keystrokes/TableNavigationUpKeyStroke.js +2 -2
  132. package/src/table/keystrokes/TableRefreshKeyStroke.js +2 -2
  133. package/src/table/keystrokes/TableSelectAllKeyStroke.js +3 -2
  134. package/src/table/keystrokes/TableStartCellEditKeyStroke.js +2 -2
  135. package/src/testing/index.js +1 -0
  136. package/src/testing/lookup/AbortableMicrotaskStaticLookupCall.js +50 -0
  137. package/src/tile/TileGrid.js +10 -12
  138. package/src/tile/TileGridLayout.js +2 -2
  139. package/src/tile/accordion/TileAccordion.js +16 -1
  140. package/src/tile/fields/FormFieldTile.less +18 -11
  141. package/src/tile/fields/tablefield/TileTableField.less +19 -2
  142. package/src/tile/keystrokes/TileGridSelectKeyStroke.js +3 -2
  143. package/src/timepicker/TimePickerTouchPopup.js +8 -0
  144. package/src/tree/CompactTree.less +1 -1
  145. package/src/tree/Tree.js +4 -4
  146. package/src/tree/Tree.less +13 -5
  147. package/src/tree/keystrokes/AbstractTreeNavigationKeyStroke.js +1 -0
  148. package/src/tree/keystrokes/TreeCollapseAllKeyStroke.js +2 -2
  149. package/src/tree/keystrokes/TreeExpandOrDrillDownKeyStroke.js +2 -2
  150. package/src/tree/keystrokes/TreeNavigationDownKeyStroke.js +2 -2
  151. package/src/tree/keystrokes/TreeNavigationEndKeyStroke.js +2 -2
  152. package/src/tree/keystrokes/TreeNavigationUpKeyStroke.js +2 -2
  153. package/src/util/Device.js +4 -4
  154. package/src/util/arrays.js +44 -2
  155. package/src/util/objects.js +4 -1
  156. package/src/widget/Widget.js +17 -7
@@ -42,6 +42,7 @@ export default class GroupBox extends CompositeField {
42
42
  this.processButtons = [];
43
43
  this.processMenus = [];
44
44
  this.staticMenus = [];
45
+ this.selectionKeystroke = null;
45
46
  this.responsive = null;
46
47
 
47
48
  this.$header = null;
@@ -162,12 +163,12 @@ export default class GroupBox extends CompositeField {
162
163
  render: () => true,
163
164
  offset: 0,
164
165
  hAlign: HAlign.RIGHT,
165
- $drawingArea: function($drawingArea, event) {
166
- if (this.labelVisible) {
166
+ $drawingArea: ($drawingArea, event) => {
167
+ if (this.$header && this.$header.isVisible()) {
167
168
  return this.$header;
168
169
  }
169
170
  return this.$body;
170
- }.bind(this)
171
+ }
171
172
  };
172
173
 
173
174
  keyStrokes
@@ -360,14 +361,11 @@ export default class GroupBox extends CompositeField {
360
361
  this.$container.toggleClass('has-scroll-shadow-bottom', hasScrollShadowBottom);
361
362
  if ((headerVisible || hasMenubarTop) && oldHasScrollShadowTop !== hasScrollShadowTop
362
363
  || hasMenubarBottom && oldHasScrollShadowBottom !== hasScrollShadowBottom) {
363
- this.invalidateLayout();
364
+ this.invalidateLayoutTree(false);
364
365
  }
365
366
 
366
367
  // Enlarge header line if there is a shadow, but don't do it if there is a menubar on top
367
368
  fields.adjustStatusPositionForScrollShadow(this, () => hasScrollShadowTop && headerVisible && !hasMenubarTop);
368
-
369
- // Prevent flickering of status icon
370
- this.validateLayout();
371
369
  }
372
370
 
373
371
  setMainBox(mainBox) {
@@ -782,9 +780,16 @@ export default class GroupBox extends CompositeField {
782
780
  }
783
781
 
784
782
  _onControlClick(event) {
785
- if (this.expandable) {
786
- this.setExpanded(!this.expanded);
783
+ if (!this.expandable) {
784
+ return;
787
785
  }
786
+ const target = scout.widget(event.target);
787
+ if (this.menuBarPosition === GroupBox.MenuBarPosition.TITLE && this.menuBar.has(target)) {
788
+ // If the position of the menubar is set to title and a menu has been clicked, then the event must not be handled
789
+ return;
790
+ }
791
+
792
+ this.setExpanded(!this.expanded);
788
793
  $.suppressEvent(event); // otherwise, the event would be triggered twice sometimes (by group-box-control and group-box-title)
789
794
  }
790
795
 
@@ -120,6 +120,7 @@
120
120
  vertical-align: middle;
121
121
  padding: @group-box-title-padding-top 0 @group-box-title-padding-bottom 0;
122
122
  max-width: 100%;
123
+ margin-top: @text-margin-top;
123
124
 
124
125
  .group-box.has-sub-label > & {
125
126
  padding-bottom: @group-box-title-with-sub-label-padding-bottom;
@@ -19,7 +19,6 @@
19
19
 
20
20
  & > .field {
21
21
  margin-left: @mandatory-indicator-width;
22
- overflow: hidden;
23
22
 
24
23
  &:focus {
25
24
  outline: none;
@@ -1,14 +1,14 @@
1
1
  /*
2
- * Copyright (c) 2014-2017 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
10
10
  */
11
- import {arrays, ListBoxLayout, LookupBox, scout, Table, ValueField} from '../../../index';
11
+ import {arrays, ListBoxLayout, LookupBox, scout, Table} from '../../../index';
12
12
 
13
13
  export default class ListBox extends LookupBox {
14
14
 
@@ -17,7 +17,6 @@ export default class ListBox extends LookupBox {
17
17
 
18
18
  this.table = null;
19
19
  this.lookupStatus = null;
20
- this.clearable = ValueField.Clearable.NEVER;
21
20
 
22
21
  this._addWidgetProperties(['table', 'filterBox']);
23
22
  }
@@ -32,6 +31,12 @@ export default class ListBox extends LookupBox {
32
31
  if (!this.table) {
33
32
  this.table = this._createDefaultListBoxTable();
34
33
  }
34
+
35
+ // align checkableColumn in table with checkboxes of tree fields
36
+ if (this.table.checkableColumn) { // may be null if a non-default list-box-table with checkable=false is used
37
+ this.table.checkableColumn.minWidth = 28;
38
+ this.table.checkableColumn.width = this.table.checkableColumn.minWidth; // do not use setWidth here
39
+ }
35
40
  }
36
41
 
37
42
  _render() {
@@ -174,12 +179,13 @@ export default class ListBox extends LookupBox {
174
179
  if (lookupRow.enabled === false) {
175
180
  row.enabled = false;
176
181
  }
177
- if (lookupRow.active === false) {
178
- row.active = false;
179
- }
180
182
  if (lookupRow.cssClass) {
181
183
  row.cssClass = lookupRow.cssClass;
182
184
  }
185
+ if (lookupRow.active === false) {
186
+ row.active = false;
187
+ row.cssClass = (row.cssClass ? (row.cssClass + ' ') : '') + 'inactive';
188
+ }
183
189
 
184
190
  return row;
185
191
  }
@@ -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
@@ -25,12 +25,13 @@ export function createTableRow(lookupRow, multipleColumns) {
25
25
  if (lookupRow.enabled === false) {
26
26
  row.enabled = false;
27
27
  }
28
- if (lookupRow.active === false) {
29
- row.active = false;
30
- }
31
28
  if (lookupRow.cssClass) {
32
29
  row.cssClass = lookupRow.cssClass;
33
30
  }
31
+ if (lookupRow.active === false) {
32
+ row.active = false;
33
+ row.cssClass = (row.cssClass ? (row.cssClass + ' ') : '') + 'inactive';
34
+ }
34
35
 
35
36
  if (!multipleColumns) {
36
37
  cells.push(createTableCell(lookupRow, null, null));
@@ -189,11 +189,12 @@ export default class ProposalField extends SmartField {
189
189
  // this causes a lookup which may fail and open a new proposal chooser (property
190
190
  // change for 'result').
191
191
  if (searchTextChanged) {
192
+ this.clearErrorStatus();
192
193
  this._acceptByText(sync, searchText);
193
194
  } else if (!this._hasUiError()) {
194
195
  this._inputAccepted(false);
195
196
  } else {
196
- // even though there's nothing todo, someone could wait for our promise to be resolved
197
+ // even though there's nothing to do, someone could wait for our promise to be resolved
197
198
  this._acceptInputDeferred.resolve();
198
199
  }
199
200
 
@@ -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
@@ -22,14 +22,10 @@ export default class ProposalTreeNode extends TreeNode {
22
22
  }
23
23
 
24
24
  _renderText() {
25
- let text = this.text;
26
- if (this.lookupRow.active === false) {
27
- text += ' (' + this.session.text('InactiveState') + ')';
28
- }
29
25
  if (this.htmlEnabled) {
30
- this.$text.html(text);
26
+ this.$text.html(this.text);
31
27
  } else {
32
- this.$text.textOrNbsp(text);
28
+ this.$text.textOrNbsp(this.text);
33
29
  }
34
30
  }
35
31
 
@@ -1,31 +1,14 @@
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
10
10
  */
11
- import {
12
- arrays,
13
- Device,
14
- fields,
15
- FormField,
16
- InputFieldKeyStrokeContext,
17
- keys,
18
- LookupCall,
19
- objects,
20
- QueryBy,
21
- scout,
22
- SimpleLoadingSupport,
23
- SmartFieldCancelKeyStroke,
24
- SmartFieldLayout,
25
- Status,
26
- strings,
27
- ValueField
28
- } from '../../../index';
11
+ import {arrays, Device, fields, FormField, InputFieldKeyStrokeContext, keys, LookupCall, objects, QueryBy, scout, SimpleLoadingSupport, SmartFieldCancelKeyStroke, SmartFieldLayout, Status, strings, ValueField} from '../../../index';
29
12
  import $ from 'jquery';
30
13
 
31
14
  export default class SmartField extends ValueField {
@@ -932,6 +915,7 @@ export default class SmartField extends ValueField {
932
915
  });
933
916
 
934
917
  this.popup.open();
918
+ this.popup.$container.css('--inactive-lookup-row-suffix-text', `'${this.session.text('InactiveState')}'`);
935
919
 
936
920
  /* This variable is required to route events to the right field:
937
921
  * - in normal mode popup events should be processed by the normal smart-field
@@ -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
@@ -266,13 +266,23 @@
266
266
  & > .table-data {
267
267
  padding: @proposal-chooser-padding-y @proposal-chooser-padding-x;
268
268
 
269
- & > .table-row.first {
270
- border-top: 1px solid @table-row-border-color;
269
+ & > .table-row {
270
+ &.first {
271
+ border-top: 1px solid @table-row-border-color;
271
272
 
272
- &.selected::after {
273
- // If header is invisible, selection of first row starts at 0
274
- // Since we now have a top border we can move it to -1px again to cover the border
275
- top: -1px;
273
+ &.selected::after {
274
+ // If header is invisible, selection of first row starts at 0
275
+ // Since we now have a top border we can move it to -1px again to cover the border
276
+ top: -1px;
277
+ }
278
+ }
279
+
280
+ &.inactive {
281
+ font-style: italic;
282
+
283
+ & > .table-cell.last > .text::after {
284
+ content: ' (' var(--inactive-lookup-row-suffix-text) ')';
285
+ }
276
286
  }
277
287
  }
278
288
 
@@ -286,9 +296,12 @@
286
296
  & > .tree-data {
287
297
  padding: @proposal-chooser-padding-y @proposal-chooser-padding-x;
288
298
 
289
- & > .tree-node {
290
- &.inactive {
291
- font-style: italic;
299
+ & > .tree-node.inactive,
300
+ & > .animation-wrapper > .tree-node.inactive {
301
+ font-style: italic;
302
+
303
+ & > .text::after {
304
+ content: ' (' var(--inactive-lookup-row-suffix-text) ')';
292
305
  }
293
306
  }
294
307
  }
@@ -16,6 +16,7 @@ export default class SplitBoxCollapseKeyStroke extends KeyStroke {
16
16
  super();
17
17
  this.field = splitBox;
18
18
  this.parseAndSetKeyStroke(keyStroke);
19
+ this.inheritAccessibility = false;
19
20
  }
20
21
 
21
22
  handle(event) {
@@ -16,6 +16,7 @@ export default class SplitBoxFirstCollapseKeyStroke extends KeyStroke {
16
16
  super();
17
17
  this.field = splitBox;
18
18
  this.parseAndSetKeyStroke(keyStroke);
19
+ this.inheritAccessibility = false;
19
20
  }
20
21
 
21
22
  handle(event) {
@@ -16,6 +16,7 @@ export default class SplitBoxSecondCollapseKeyStroke extends KeyStroke {
16
16
  super();
17
17
  this.field = splitBox;
18
18
  this.parseAndSetKeyStroke(keyStroke);
19
+ this.inheritAccessibility = false;
19
20
  }
20
21
 
21
22
  handle(event) {
@@ -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
@@ -30,32 +30,37 @@ export default class TabAreaLayout extends AbstractLayout {
30
30
  }
31
31
 
32
32
  layout($container) {
33
- let ellipsis = this.tabArea.ellipsis,
34
- htmlContainer = HtmlComponent.get($container),
33
+ let htmlContainer = HtmlComponent.get($container),
35
34
  containerSize = htmlContainer.availableSize().subtract(htmlContainer.insets());
36
35
 
37
36
  // compute visible and overflown tabs
38
37
  this.preferredLayoutSize($container, {
39
38
  widthHint: containerSize.width
40
39
  });
40
+ this._layoutSelectionMarker();
41
+ }
41
42
 
42
- if (this.overflowTabs.length > 0) {
43
- ellipsis.setHidden(false);
44
- }
45
-
46
- this.visibleTabs.forEach(tabItem => {
47
- tabItem.setOverflown(false);
48
- });
49
-
50
- this.overflowTabs.forEach(tabItem => {
51
- tabItem.setOverflown(true);
52
- });
43
+ _layoutSelectionMarker() {
44
+ let $selectionMarker = this.tabArea.$selectionMarker,
45
+ selectedTab = this.tabArea.selectedTab,
46
+ selectedItemBounds;
53
47
 
54
- if (this.overflowTabs.length === 0) {
55
- ellipsis.setHidden(true);
48
+ if (selectedTab) {
49
+ $selectionMarker.setVisible(true);
50
+ selectedItemBounds = graphics.bounds(selectedTab.$container);
51
+ $selectionMarker.cssLeft(selectedItemBounds.x);
52
+ $selectionMarker.cssWidth(selectedItemBounds.width);
53
+ } else {
54
+ $selectionMarker.setVisible(false);
56
55
  }
56
+ }
57
57
 
58
+ _updateEllipsis() {
59
+ let ellipsis = this.tabArea.ellipsis;
60
+ ellipsis.setHidden(this.overflowTabs.length < 1);
58
61
  ellipsis.setText(this.overflowTabs.length + '');
62
+ this.visibleTabs.forEach(tabItem => tabItem.setOverflown(false));
63
+ this.overflowTabs.forEach(tabItem => tabItem.setOverflown(true));
59
64
 
60
65
  ellipsis.setChildActions(this.overflowTabs.map(tab => {
61
66
  let menu = scout.create('Menu', {
@@ -73,73 +78,54 @@ export default class TabAreaLayout extends AbstractLayout {
73
78
  });
74
79
  return menu;
75
80
  }, this));
76
-
77
- this._layoutSelectionMarker();
78
- }
79
-
80
- _layoutSelectionMarker() {
81
- let $selectionMarker = this.tabArea.$selectionMarker,
82
- selectedTab = this.tabArea.selectedTab,
83
- selectedItemBounds;
84
-
85
- if (selectedTab) {
86
- $selectionMarker.setVisible(true);
87
- selectedItemBounds = graphics.bounds(selectedTab.$container);
88
- $selectionMarker.cssLeft(selectedItemBounds.x);
89
- $selectionMarker.cssWidth(selectedItemBounds.width);
90
- } else {
91
- $selectionMarker.setVisible(false);
92
- }
93
81
  }
94
82
 
95
83
  preferredLayoutSize($container, options) {
96
84
  let htmlComp = HtmlComponent.get($container),
97
85
  prefSize = new Dimension(0, 0),
98
- prefWidth = Number.MAX_VALUE,
99
- visibleTabItems = this.tabArea.visibleTabs(),
100
- overflowableIndexes = visibleTabItems.map((tabItem, index) => {
101
- if (tabItem.selected) {
102
- return -1;
103
- }
104
- return index;
105
- }).filter(index => index >= 0);
86
+ prefWidth = Number.MAX_VALUE;
87
+ this.visibleTabs = this.tabArea.visibleTabs();
88
+ let overflowableIndexes = this.visibleTabs.map((tabItem, index) => {
89
+ if (tabItem.selected) {
90
+ return -1;
91
+ }
92
+ return index;
93
+ }).filter(index => index >= 0);
106
94
 
107
95
  this.overflowTabs = [];
108
96
 
109
- // consider avoid falsy 0 in tabboxes a 0 withHint will be used to calculate the minimum width
97
+ // consider avoid falsy 0 in tab-boxes a 0 withHint will be used to calculate the minimum width
110
98
  if (options.widthHint === 0 || options.widthHint) {
111
99
  prefWidth = options.widthHint - htmlComp.insets().horizontal();
112
100
  }
113
101
 
114
102
  // shortcut for minimum size.
115
103
  if (prefWidth <= 0) {
116
- return this._minSize(visibleTabItems).add(htmlComp.insets());
104
+ return this._minSize(this.visibleTabs).add(htmlComp.insets());
117
105
  }
118
106
 
119
- let overflowIndex = -1;
120
- this._setFirstLastMarker(visibleTabItems);
121
- prefSize = this._prefSize(visibleTabItems);
107
+ this._setFirstLastMarker(this.visibleTabs);
108
+ this._updateEllipsis();
109
+ prefSize = this._prefSize(this.visibleTabs);
110
+
122
111
  while (prefSize.width > prefWidth && overflowableIndexes.length > 0) {
123
- overflowIndex = overflowableIndexes.splice(-1)[0];
124
- this.overflowTabs.splice(0, 0, visibleTabItems[overflowIndex]);
125
- visibleTabItems.splice(overflowIndex, 1);
126
- this._setFirstLastMarker(visibleTabItems);
127
- prefSize = this._prefSize(visibleTabItems);
112
+ let overflowIndex = overflowableIndexes.splice(-1)[0];
113
+ this.overflowTabs.splice(0, 0, this.visibleTabs[overflowIndex]);
114
+ this.visibleTabs.splice(overflowIndex, 1);
115
+ this._setFirstLastMarker(this.visibleTabs);
116
+ this._updateEllipsis(); // update ellipsis here already so that the prefSize on the next line is correct
117
+ prefSize = this._prefSize(this.visibleTabs);
128
118
  }
129
119
 
130
- this.visibleTabs = visibleTabItems;
131
-
132
120
  // Use the total available space if spreading tabs evenly.
133
121
  if (this.tabArea.displayStyle === TabArea.DisplayStyle.SPREAD_EVEN) {
134
122
  return graphics.prefSize($container, options);
135
123
  }
136
-
137
124
  return graphics.exactPrefSize(prefSize.add(htmlComp.insets()), options);
138
125
  }
139
126
 
140
127
  _minSize(tabItems) {
141
- let visibleTabItems = [],
142
- prefSize;
128
+ let visibleTabItems = [];
143
129
  this.overflowTabs = tabItems.filter(tabItem => {
144
130
  if (tabItem.selected) {
145
131
  visibleTabItems.push(tabItem);
@@ -150,23 +136,21 @@ export default class TabAreaLayout extends AbstractLayout {
150
136
 
151
137
  this.visibleTabs = visibleTabItems;
152
138
  this._setFirstLastMarker(visibleTabItems);
153
- prefSize = this._prefSize(visibleTabItems);
154
-
155
- return prefSize;
139
+ return this._prefSize(visibleTabItems);
156
140
  }
157
141
 
158
142
  _prefSize(tabItems, considerEllipsis) {
159
- let prefSize = tabItems.map(tabItem => this._tabItemSize(tabItem.htmlComp)
160
- ).reduce((prefSize, itemSize) => {
143
+ let prefSize = tabItems
144
+ .map(tabItem => this._tabItemSize(tabItem))
145
+ .reduce((prefSize, itemSize) => {
161
146
  prefSize.height = Math.max(prefSize.height, itemSize.height);
162
147
  prefSize.width += itemSize.width;
163
148
  return prefSize;
164
- }, new Dimension(0, 0)),
165
- ellipsisSize = new Dimension(0, 0);
149
+ }, new Dimension(0, 0));
166
150
 
167
151
  considerEllipsis = scout.nvl(considerEllipsis, this.overflowTabs.length > 0);
168
152
  if (considerEllipsis) {
169
- ellipsisSize = this._tabItemSize(this.tabArea.ellipsis.htmlComp);
153
+ let ellipsisSize = this._tabItemSize(this.tabArea.ellipsis);
170
154
  prefSize.height = Math.max(prefSize.height, ellipsisSize.height);
171
155
  prefSize.width += ellipsisSize.width;
172
156
  }
@@ -193,8 +177,8 @@ export default class TabAreaLayout extends AbstractLayout {
193
177
  }
194
178
  }
195
179
 
196
- _tabItemSize(htmlComp) {
197
- let prefSize,
180
+ _tabItemSize(item) {
181
+ let htmlComp = item.htmlComp, prefSize,
198
182
  classList = htmlComp.$comp.attr('class');
199
183
 
200
184
  // temporarily revert display style to default. otherwise the pref size of the tab item will be the size of the container.
@@ -208,6 +192,19 @@ export default class TabAreaLayout extends AbstractLayout {
208
192
  prefSize = htmlComp.prefSize({
209
193
  exact: true
210
194
  }).add(graphics.margins(htmlComp.$comp));
195
+ if (item.fieldStatus && item.fieldStatus.htmlComp) {
196
+ let statusOverflownAndHidden = item.overflown && !item.fieldStatus.visible;
197
+ if (statusOverflownAndHidden) {
198
+ // overflown tabs have no fieldStatus: explicitly set to visible so that the real consumed space can be computed
199
+ item.fieldStatus.setVisible(true);
200
+ }
201
+ let statusWidth = item.fieldStatus.htmlComp.prefSize({includeMargin: true}).width;
202
+ if (statusOverflownAndHidden) {
203
+ // restore
204
+ item.fieldStatus.setVisible(false);
205
+ }
206
+ prefSize.width += statusWidth;
207
+ }
211
208
 
212
209
  htmlComp.$comp.attrOrRemove('class', classList);
213
210
 
@@ -12,6 +12,7 @@ import {keys, KeyStroke} from '../../../index';
12
12
 
13
13
  export default class TabAreaLeftKeyStroke extends KeyStroke {
14
14
 
15
+ // noinspection DuplicatedCode
15
16
  constructor(tabArea) {
16
17
  super();
17
18
  this.field = tabArea;
@@ -19,6 +20,7 @@ export default class TabAreaLeftKeyStroke extends KeyStroke {
19
20
  this.renderingHints.render = false;
20
21
  this.stopPropagation = true;
21
22
  this.keyStrokeMode = KeyStroke.Mode.DOWN;
23
+ this.inheritAccessibility = false;
22
24
  }
23
25
 
24
26
  handle(event) {
@@ -12,6 +12,7 @@ import {keys, KeyStroke} from '../../../index';
12
12
 
13
13
  export default class TabAreaRightKeyStroke extends KeyStroke {
14
14
 
15
+ // noinspection DuplicatedCode
15
16
  constructor(tabArea) {
16
17
  super();
17
18
  this.field = tabArea;
@@ -19,6 +20,7 @@ export default class TabAreaRightKeyStroke extends KeyStroke {
19
20
  this.renderingHints.render = false;
20
21
  this.stopPropagation = true;
21
22
  this.keyStrokeMode = KeyStroke.Mode.DOWN;
23
+ this.inheritAccessibility = false;
22
24
  }
23
25
 
24
26
  handle(event) {
@@ -32,7 +32,6 @@ export default class TabBox extends CompositeField {
32
32
  this._addPreserveOnPropertyChangeProperties(['selectedTab']);
33
33
 
34
34
  this._tabBoxHeaderPropertyChangeHander = this._onTabBoxHeaderPropertyChange.bind(this);
35
- this._selectedTabScrollTopChangeHandler = this._updateScrollShadow.bind(this);
36
35
  }
37
36
 
38
37
  /**
@@ -173,16 +172,17 @@ export default class TabBox extends CompositeField {
173
172
  _renderSelectedTab() {
174
173
  if (this.selectedTab) {
175
174
  this.selectedTab.render(this._$tabContent);
176
- this.selectedTab.on('propertyChange:scrollTop', this._selectedTabScrollTopChangeHandler);
175
+ this.selectedTab.get$Scrollable().data('scroll-shadow-customizer', this._updateScrollShadow.bind(this));
177
176
  }
178
177
  if (this.rendered) {
178
+ this._updateScrollShadow();
179
179
  HtmlComponent.get(this._$tabContent).invalidateLayoutTree();
180
180
  }
181
181
  }
182
182
 
183
183
  _removeSelectedTab() {
184
184
  if (this.selectedTab) {
185
- this.selectedTab.off('propertyChange:scrollTop', this._selectedTabScrollTopChangeHandler);
185
+ this.selectedTab.get$Scrollable().removeData('scroll-shadow-customizer');
186
186
  this.selectedTab.remove();
187
187
  }
188
188
  }
@@ -195,14 +195,11 @@ export default class TabBox extends CompositeField {
195
195
  let oldHasScrollShadowTop = this.$container.hasClass('has-scroll-shadow-top');
196
196
  this.$container.toggleClass('has-scroll-shadow-top', hasScrollShadowTop);
197
197
  if (oldHasScrollShadowTop !== hasScrollShadowTop) {
198
- this.invalidateLayout();
198
+ this.invalidateLayoutTree(false);
199
199
  }
200
200
 
201
201
  // Enlarge header line if there is a shadow, but only if there is a header (controlled by labelVisible)
202
202
  fields.adjustStatusPositionForScrollShadow(this, () => hasScrollShadowTop && this.labelVisible);
203
-
204
- // Prevent flickering of status icon
205
- this.validateLayout();
206
203
  }
207
204
 
208
205
  setTabAreaStyle(tabAreaStyle) {
@@ -293,6 +290,10 @@ export default class TabBox extends CompositeField {
293
290
  this.header.focusTabItem(tabItem);
294
291
  }
295
292
 
293
+ getTabForItem(tabItem) {
294
+ return this.header.getTabForItem(tabItem);
295
+ }
296
+
296
297
  _onTabBoxHeaderPropertyChange(event) {
297
298
  if (event.propertyName === 'selectedTabItem') {
298
299
  this.setSelectedTab(event.newValue);
@@ -74,7 +74,7 @@
74
74
  & > .menubar {
75
75
  position: absolute;
76
76
  #scout.menubar-background-color-inherit();
77
- border-bottom-color: transparent;
77
+ border-bottom: none;
78
78
  }
79
79
 
80
80
  & > .status {
@@ -163,6 +163,7 @@
163
163
  display: inline-block;
164
164
  vertical-align: middle;
165
165
  padding: @tab-item-title-padding-top 0 @tab-item-title-padding-bottom;
166
+ margin-top: @text-margin-top;
166
167
 
167
168
  .tab-area.has-sub-label > & {
168
169
  padding-bottom: @group-box-title-with-sub-label-padding-bottom;
@@ -89,6 +89,10 @@ export default class TabBoxHeader extends Widget {
89
89
  this.tabArea.focusTabItem(tabItem);
90
90
  }
91
91
 
92
+ getTabForItem(tabItem) {
93
+ return this.tabArea.getTabForItem(tabItem);
94
+ }
95
+
92
96
  _onTabBoxPropertyChange(event) {
93
97
  if (event.propertyName === 'menus') {
94
98
  this.menuBar.setMenuItems(this.tabBox.menus);