@componyx/ui 0.0.0-stage → 1.0.3
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.
- package/AppSkin/AppSkin.css +1268 -0
- package/AppSkin/AppSkin.js +2748 -0
- package/AppSkin/Themes/Default.css +241 -0
- package/Base/Base.js +3407 -0
- package/Base/ComponentIcons.css +66 -0
- package/Base/Font/ComponentIcons.woff +0 -0
- package/Base/Font/UI.woff +0 -0
- package/Base/Library.js +8432 -0
- package/Base/NavigationManager.js +462 -0
- package/Base/ResponsiveTemplates.js +371 -0
- package/Base/Sanitizer.js +288 -0
- package/Base/Themes/Default.css +255 -0
- package/Base/UI.css +618 -0
- package/Base/UIResourcePath.js +6 -0
- package/Bindary/Bindary.js +2011 -0
- package/Bindary/Modules/Connection.js +216 -0
- package/Bindary/Modules/Core.js +854 -0
- package/Bindary/Modules/DataUpdater.js +351 -0
- package/Bindary/Modules/ExpressionEngine.js +347 -0
- package/Bindary/Modules/ProxyManager.js +482 -0
- package/Bindary/Modules/Renderer.js +605 -0
- package/Bindary/Modules/Router.js +291 -0
- package/Bindary/Modules/Scroller.js +89 -0
- package/Bindary/Modules/Template.js +1273 -0
- package/BookmarkSpy/BookmarkSpy.js +430 -0
- package/Box/Box.css +36 -0
- package/Box/Box.js +1685 -0
- package/Button/Button.css +470 -0
- package/Button/Button.js +1398 -0
- package/Button/Themes/Default.css +200 -0
- package/Carousel/Carousel.css +273 -0
- package/Carousel/Carousel.js +607 -0
- package/ColorButton/ColorButton.css +39 -0
- package/ColorButton/ColorButton.js +336 -0
- package/ColorPicker/ColorPicker.css +359 -0
- package/ColorPicker/ColorPicker.js +972 -0
- package/ComboBox/ComboBox.css +357 -0
- package/ComboBox/ComboBox.js +2342 -0
- package/ComboBox/Themes/Default.css +23 -0
- package/DataPager/DataPager.css +72 -0
- package/DataPager/DataPager.js +674 -0
- package/DatePicker/DatePicker.css +227 -0
- package/DatePicker/DatePicker.js +1531 -0
- package/DatePicker/Themes/Default.css +26 -0
- package/Dialog/Dialog.css +106 -0
- package/Dialog/Dialog.js +572 -0
- package/Dialog/Themes/Default.css +10 -0
- package/Editor/Data/Emoji.json +8285 -0
- package/Editor/Data/Special.json +1042 -0
- package/Editor/Editor.css +1562 -0
- package/Editor/Editor.js +4058 -0
- package/Editor/Font/Editor.woff +0 -0
- package/Editor/Modules/ComponentFactory.js +565 -0
- package/Editor/Modules/ContentManager.js +748 -0
- package/Editor/Modules/DialogManager.js +1234 -0
- package/Editor/Modules/EventManager.js +458 -0
- package/Editor/Modules/Format.js +950 -0
- package/Editor/Modules/History.js +191 -0
- package/Editor/Modules/LayoutState.js +379 -0
- package/Editor/Modules/ListManager.js +296 -0
- package/Editor/Modules/MenuManager.js +388 -0
- package/Editor/Modules/NodeManager.js +681 -0
- package/Editor/Modules/ParagraphButtons.js +122 -0
- package/Editor/Modules/Resizer.js +176 -0
- package/Editor/Modules/SelectionRange.js +564 -0
- package/Editor/Modules/SourceViewBuilder.js +212 -0
- package/Editor/Modules/SymbolPicker.js +208 -0
- package/Editor/Modules/Table.js +2327 -0
- package/Editor/Modules/TableDialog.js +757 -0
- package/Editor/Modules/Toolbar.js +375 -0
- package/Editor/Modules/TooltipMenu.js +125 -0
- package/Editor/Modules/Utility.js +131 -0
- package/Editor/Themes/Default.css +204 -0
- package/FileUpload/FileUpload.css +156 -0
- package/FileUpload/FileUpload.js +898 -0
- package/FileUpload/Themes/Default.css +17 -0
- package/Form/Form.css +1934 -0
- package/Form/Form.js +4943 -0
- package/Form/Modules/ActionManager.js +368 -0
- package/Form/Modules/BuildPanelManager.js +319 -0
- package/Form/Modules/ComponentFactory.js +468 -0
- package/Form/Modules/ComponentPanel.js +265 -0
- package/Form/Modules/ConfigPanelManager.js +685 -0
- package/Form/Modules/DataObserver.js +717 -0
- package/Form/Modules/Databinder.js +602 -0
- package/Form/Modules/Draggable.js +756 -0
- package/Form/Modules/OptionsPanel.js +342 -0
- package/Form/Modules/Renderer.js +1889 -0
- package/Form/Modules/RuleEngine.js +585 -0
- package/Form/Modules/RulesPanel.js +1158 -0
- package/Form/Modules/Types.js +1709 -0
- package/Form/Modules/ValidationManager.js +194 -0
- package/Form/Themes/Default.css +216 -0
- package/FormField/FormField.css +468 -0
- package/FormField/FormField.js +576 -0
- package/FormField/Themes/Default.css +99 -0
- package/Grid/Grid.css +544 -0
- package/Grid/Grid.js +3761 -0
- package/Grid/Themes/Default.css +43 -0
- package/LICENSE +126 -0
- package/MaskedTextBox/MaskedTextBox.css +28 -0
- package/MaskedTextBox/MaskedTextBox.js +642 -0
- package/MaskedTextBox/Themes/Default.css +6 -0
- package/Menu/Menu.css +328 -0
- package/Menu/Menu.js +2386 -0
- package/Menu/Themes/Default.css +24 -0
- package/NumericBox/NumericBox.css +120 -0
- package/NumericBox/NumericBox.js +984 -0
- package/PanelBar/PanelBar.css +123 -0
- package/PanelBar/PanelBar.js +505 -0
- package/PanelBar/Themes/Default.css +51 -0
- package/PieChart/PieChart.css +95 -0
- package/PieChart/PieChart.js +820 -0
- package/PieChart/Themes/Default.css +9 -0
- package/README.md +178 -3
- package/Slider/Slider.css +348 -0
- package/Slider/Slider.js +1306 -0
- package/Slider/Themes/Default.css +44 -0
- package/TabStrip/TabStrip.css +52 -0
- package/TabStrip/TabStrip.js +362 -0
- package/TabStrip/Themes/Default.css +35 -0
- package/TimePicker/Themes/Default.css +30 -0
- package/TimePicker/TimePicker.css +253 -0
- package/TimePicker/TimePicker.js +1485 -0
- package/TooltipManager/Themes/Default.css +21 -0
- package/TooltipManager/TooltipManager.css +227 -0
- package/TooltipManager/TooltipManager.js +791 -0
- package/Validator/Validator.css +54 -0
- package/Validator/Validator.js +2508 -0
- package/componyx.html-data.json +619 -0
- package/index.js +27 -0
- package/package.json +43 -4
- package/types/AppSkin.d.ts +842 -0
- package/types/Base.d.ts +1034 -0
- package/types/Bindary.d.ts +1196 -0
- package/types/BookmarkSpy.d.ts +112 -0
- package/types/Box.d.ts +374 -0
- package/types/Button.d.ts +455 -0
- package/types/Carousel.d.ts +136 -0
- package/types/ColorButton.d.ts +120 -0
- package/types/ColorPicker.d.ts +225 -0
- package/types/ComboBox.d.ts +507 -0
- package/types/DataPager.d.ts +152 -0
- package/types/DatePicker.d.ts +354 -0
- package/types/Dialog.d.ts +160 -0
- package/types/Editor.d.ts +1289 -0
- package/types/FileUpload.d.ts +206 -0
- package/types/Form.d.ts +3078 -0
- package/types/FormField.d.ts +204 -0
- package/types/Grid.d.ts +911 -0
- package/types/Library.d.ts +1899 -0
- package/types/MaskedTextBox.d.ts +91 -0
- package/types/Menu.d.ts +577 -0
- package/types/NumericBox.d.ts +310 -0
- package/types/PanelBar.d.ts +223 -0
- package/types/PieChart.d.ts +224 -0
- package/types/ResponsiveTemplates.d.ts +108 -0
- package/types/Slider.d.ts +227 -0
- package/types/TabStrip.d.ts +185 -0
- package/types/TimePicker.d.ts +265 -0
- package/types/TooltipManager.d.ts +178 -0
- package/types/UI.d.ts +29 -0
- package/types/Validator.d.ts +653 -0
- package/types/index.d.ts +59 -0
- package/ui.css +11783 -0
- package/ui.js +79477 -0
- package/ui.min.css +138 -0
- package/ui.min.js +264 -0
- package/ui.min.js.map +1 -0
package/Box/Box.js
ADDED
|
@@ -0,0 +1,1685 @@
|
|
|
1
|
+
/*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
|
|
2
|
+
import '../Base/Base.js';
|
|
3
|
+
import '../Base/Library.js';
|
|
4
|
+
|
|
5
|
+
(function (window)
|
|
6
|
+
{
|
|
7
|
+
/**
|
|
8
|
+
* Box class.
|
|
9
|
+
* @class
|
|
10
|
+
* @memberof componyx.UI
|
|
11
|
+
* @augments componyx.UI.base.Component
|
|
12
|
+
* @mixes componyx.UI.base.methods
|
|
13
|
+
* @param {String} id The id of the component.
|
|
14
|
+
* @param {Object|HTMLElement} properties The properties used to initialize the component or the container element.
|
|
15
|
+
* @property {componyx.UI.base.AjaxMethod} ajax.load - AJAX method used to load box content data on demand.
|
|
16
|
+
* @returns {Object} An instance of the component.
|
|
17
|
+
*/
|
|
18
|
+
componyx.UI.Box = function Box(id, properties)
|
|
19
|
+
{
|
|
20
|
+
var _instance = this,
|
|
21
|
+
_contentElement,
|
|
22
|
+
_draggable,
|
|
23
|
+
_focusable = [],
|
|
24
|
+
_timerId = null,
|
|
25
|
+
_showTimerId, _hideTimerId,
|
|
26
|
+
_styleCache = {},
|
|
27
|
+
_animation = null,
|
|
28
|
+
_invertedX = false,
|
|
29
|
+
_invertedY = false,
|
|
30
|
+
_resizedX = false,
|
|
31
|
+
_resizedY = false,
|
|
32
|
+
_resizeObserver = null,
|
|
33
|
+
_invertMarginX = 0,
|
|
34
|
+
_invertMarginY = 0,
|
|
35
|
+
_rendered = false,
|
|
36
|
+
_allowHide = true,
|
|
37
|
+
_expander = null, _modal,
|
|
38
|
+
_pointerCoordinates,
|
|
39
|
+
_modalStyle = 'position:fixed; left:0px; top:0px; width:100%; height:100%;';
|
|
40
|
+
$base.static.ThemeOption;
|
|
41
|
+
var _autoPositionOption = componyx.UI.Box.AutoPositionOption,
|
|
42
|
+
_expandDirectionOption = componyx.UI.Box.ExpandDirectionOption,
|
|
43
|
+
_alignXOption = componyx.UI.Box.AlignXOption,
|
|
44
|
+
_alignYOption = componyx.UI.Box.AlignYOption,
|
|
45
|
+
_animationTypeOption = componyx.UI.Box.AnimationTypeOption,
|
|
46
|
+
_classOption =
|
|
47
|
+
{
|
|
48
|
+
CONTENT: 'content',
|
|
49
|
+
MODAL: 'modal',
|
|
50
|
+
EXPANDED: 'expanded',
|
|
51
|
+
HORIZONTALINVERTED: 'inverted',
|
|
52
|
+
VERTICALINVERTED: 'inverted',
|
|
53
|
+
SHOW: 'show',
|
|
54
|
+
SHOWANIMATION: 'show-animation',
|
|
55
|
+
HIDEANIMATION: 'hide-animation'
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// define public properties
|
|
59
|
+
/**
|
|
60
|
+
* Gets or sets the css class of the box content.
|
|
61
|
+
* @type {String}
|
|
62
|
+
*/
|
|
63
|
+
this.cssClassContent = '';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Gets or sets the css class of the box modal overlay.
|
|
67
|
+
* @type {String}
|
|
68
|
+
*/
|
|
69
|
+
this.cssClassModal = '';
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets or sets the css class of the box when AutoInvertFit is true and the box is inverted horizontally.
|
|
73
|
+
* @type {String}
|
|
74
|
+
*/
|
|
75
|
+
this.cssClassHorizontalInverted = '';
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Gets or sets the css class of the box when AutoInvertFit is true and the box is inverted vertically.
|
|
79
|
+
* @type {String}
|
|
80
|
+
*/
|
|
81
|
+
this.cssClassVerticalInverted = '';
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets or sets the top position of the box. Overwrites the property if already defined through Style.
|
|
85
|
+
* @type {String}
|
|
86
|
+
*/
|
|
87
|
+
this.top = '';
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets or sets the right position of the box. Overwrites the property if already defined through Style.
|
|
91
|
+
* @type {String}
|
|
92
|
+
*/
|
|
93
|
+
this.right = '';
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets or sets the bottom position of the box. Overwrites the property if already defined through Style.
|
|
97
|
+
* @type {String}
|
|
98
|
+
*/
|
|
99
|
+
this.bottom = '';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Gets or sets the left position of the box. Overwrites the property if already defined through Style.
|
|
103
|
+
* @type {String}
|
|
104
|
+
*/
|
|
105
|
+
this.left = '';
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Gets or sets the width of the box. Overwrites the property if already defined through Style.
|
|
109
|
+
* @type {String}
|
|
110
|
+
*/
|
|
111
|
+
this.width = '';
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Gets or sets the height of the box. Overwrites the property if already defined through Style.
|
|
115
|
+
* @type {String}
|
|
116
|
+
*/
|
|
117
|
+
this.height = '';
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Gets or sets a value indicating if the box element must stretch to the size of the expander element. The content width has priority over the expander width when stretchToContent is enabled and the content exceeds the expander width.
|
|
121
|
+
* @type {Boolean}
|
|
122
|
+
*/
|
|
123
|
+
this.stretchToExpander = false;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Gets or sets a value indicating if the box element must stretch to the size of the content element. This setting is useful when the box is positioned absolute/fixed and the content element is a flex-box (display:flex).
|
|
127
|
+
* @type {Boolean}
|
|
128
|
+
*/
|
|
129
|
+
this.stretchToContent = false;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Gets or sets a value indicating whether the box should handle focus events for focusable child elements. Only applies when modal is false.
|
|
133
|
+
* @type {Boolean}
|
|
134
|
+
*/
|
|
135
|
+
this.handleFocus = false;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Gets or sets a value indicating whether the first element of the focusable list should get focus when the box is shown.
|
|
139
|
+
* @type {Boolean}
|
|
140
|
+
*/
|
|
141
|
+
this.autoFocus = true;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Gets or sets a value indicating whether the focusable list is ordered by tabindex (requires all elements to have a tabindex set).
|
|
145
|
+
* @type {Boolean}
|
|
146
|
+
*/
|
|
147
|
+
this.tabIndexFocus = false;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Gets or sets the auto position of the box.
|
|
151
|
+
* @type {componyx.UI.Box.AutoPositionOption}
|
|
152
|
+
*/
|
|
153
|
+
this.autoPosition = _autoPositionOption.NONE;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Gets or sets a value indicating whether the box should try to fit when the window is too small.
|
|
157
|
+
* @type {Boolean}
|
|
158
|
+
*/
|
|
159
|
+
this.autoFit = true;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Gets or sets a value indicating whether the box should try to fit inverted when the window is too small.
|
|
163
|
+
* @type {Boolean}
|
|
164
|
+
*/
|
|
165
|
+
this.autoInvertFit = false;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Gets or sets a value indicating whether the box should be resized when the window is too small.
|
|
169
|
+
* @type {Boolean}
|
|
170
|
+
*/
|
|
171
|
+
this.autoResizeFit = false;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Gets or sets a value indicating whether the animation direction should be auto inverted when the box is inverted.
|
|
175
|
+
* @type {Boolean}
|
|
176
|
+
*/
|
|
177
|
+
this.autoInvertAnimation = true;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Gets or sets a value indicating whether the box is either resized to the window width or available (inverted) space when auto resized.
|
|
181
|
+
* @type {Boolean}
|
|
182
|
+
*/
|
|
183
|
+
this.resizeToMaxWidth = true;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Gets or sets a value indicating whether the box is either resized to the window height or available (inverted) space when auto resized.
|
|
187
|
+
* @type {Boolean}
|
|
188
|
+
*/
|
|
189
|
+
this.resizeToMaxHeight = true;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Gets or sets a value indicating whether the box is displayed as modal popup.
|
|
193
|
+
* @type {Boolean}
|
|
194
|
+
*/
|
|
195
|
+
this.modal = false;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Gets or sets a value indicating whether the box is draggable.
|
|
199
|
+
* @type {Boolean}
|
|
200
|
+
*/
|
|
201
|
+
this.draggable = false;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Gets or sets a value indicating whether the box is hidden when the user clicks outside the box.
|
|
205
|
+
* @type {Boolean}
|
|
206
|
+
*/
|
|
207
|
+
this.hideOnOutsideClick = false;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Gets or sets a value indicating whether the box position tracks the pointer when AutoPosition is set to Pointer.
|
|
211
|
+
* @type {Boolean}
|
|
212
|
+
*/
|
|
213
|
+
this.trackPointer = false;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Gets or sets a value indicating whether the box's horizontal position is aligned to the left, center or right of the expander element or pointer.
|
|
217
|
+
* @type {componyx.UI.Box.AlignXOption|null}
|
|
218
|
+
*/
|
|
219
|
+
this.alignX = null;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Gets or sets a value indicating whether the box's vertical position is aligned to the top, center or bottom of the expander element or pointer.
|
|
223
|
+
* @type {componyx.UI.Box.AlignYOption|null}
|
|
224
|
+
*/
|
|
225
|
+
this.alignY = null;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Gets the tag name of the content element.
|
|
229
|
+
* @type {String}
|
|
230
|
+
*/
|
|
231
|
+
this.contentTag = 'div';
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Gets or sets the expand direction.
|
|
235
|
+
* @type {componyx.UI.Box.ExpandDirectionOption}
|
|
236
|
+
*/
|
|
237
|
+
this.expandDirection = _expandDirectionOption.RIGHT;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Gets or sets the expander element or element-id.
|
|
241
|
+
* @type {HTMLElement|String|null}
|
|
242
|
+
*/
|
|
243
|
+
this.expander = null;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Gets or sets the submitter element or element-id on which to fire a click event when the enter-key is pressed within a field inside the box element.
|
|
247
|
+
* @type {HTMLElement|String|null}
|
|
248
|
+
*/
|
|
249
|
+
this.enterKeySubmitter = null;
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Gets the element which contains the box content.
|
|
253
|
+
* @type {HTMLElement}
|
|
254
|
+
*/
|
|
255
|
+
Object.defineProperty(this, 'contentElement',
|
|
256
|
+
{
|
|
257
|
+
get: function () { return _contentElement; }
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Box animation.
|
|
263
|
+
* @type animation
|
|
264
|
+
* @property {componyx.UI.Box.AnimationTypeOption} showType - Gets or sets the animation type used when showing the box.
|
|
265
|
+
* @property {String} showClass - Gets or sets the CSS class applied when showing the box.
|
|
266
|
+
* @property {String} showDirection - Gets or sets the animation direction (down, right, up, left) used when showing the box.
|
|
267
|
+
* @property {Boolean} showFade - Gets or sets a value indicating if fading is used when showing the box.
|
|
268
|
+
* @property {componyx.UI.Box.AnimationTypeOption} hideType - Gets or sets the animation type used when hiding the box.
|
|
269
|
+
* @property {String} hideClass - Gets or sets the CSS class applied when hiding the box.
|
|
270
|
+
* @property {String} hideDirection - Gets or sets the animation direction (top, right, bottom, left) used when hiding the box.
|
|
271
|
+
* @property {Boolean} hideFade - Gets or sets a value indicating if fading is used when hiding the box.
|
|
272
|
+
*/
|
|
273
|
+
this.animation =
|
|
274
|
+
{
|
|
275
|
+
showType: null,
|
|
276
|
+
showClass: null,
|
|
277
|
+
showDirection: null,
|
|
278
|
+
showFade: null,
|
|
279
|
+
hideType: null,
|
|
280
|
+
hideClass: null,
|
|
281
|
+
hideDirection: null,
|
|
282
|
+
hideFade: null
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @type {componyx.library.DraggableSettings}
|
|
287
|
+
* @see {@link componyx.library.DraggableSettings}
|
|
288
|
+
*/
|
|
289
|
+
this.dragSettings = {};
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @class
|
|
293
|
+
* @augments componyx.UI.base.Events
|
|
294
|
+
* @memberof componyx.UI.Box
|
|
295
|
+
* @property {componyx.UI.base.Event} onPrePosition - Event which fires before the box is positioned.
|
|
296
|
+
* @property {componyx.UI.base.Event} onPostPosition - Event which fires after the box is positioned.
|
|
297
|
+
* @property {componyx.UI.base.Event} onAutoFit - Event which fires when the window is too small and the box performs an auto fit. @see {@link componyx.UI.Box.AutoFitEventArgs}
|
|
298
|
+
* @property {componyx.UI.base.Event} onShowComplete - Event which fires when the show animation has completed, or immediately if animation type is 'none'.
|
|
299
|
+
* @property {componyx.UI.base.Event} onHideComplete - Event which fires when the hide animation has completed, or immediately if animation type is 'none'.
|
|
300
|
+
* @property {componyx.UI.base.Event} onHide - Event which fires when the box is hidden (overrides the base event arguments). Set cancel to true to keep the box visible. @see {@link componyx.UI.Box.HideEventArgs}
|
|
301
|
+
* @see {@link componyx.UI.base.Events}
|
|
302
|
+
*/
|
|
303
|
+
function BoxEvents(events)
|
|
304
|
+
{
|
|
305
|
+
Object.assign(this, events);
|
|
306
|
+
this.onPrePosition = $base.static.createEvent('onPrePosition');
|
|
307
|
+
this.onPostPosition = $base.static.createEvent('onPostPosition');
|
|
308
|
+
this.onAutoFit = $base.static.createEvent('onAutoFit');
|
|
309
|
+
this.onShowComplete = $base.static.createEvent('onShowComplete');
|
|
310
|
+
this.onHideComplete = $base.static.createEvent('onHideComplete');
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Box events
|
|
314
|
+
* @type {componyx.UI.Box.BoxEvents}
|
|
315
|
+
*/
|
|
316
|
+
this.events = new BoxEvents(this.events);
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Box hide event arguments.
|
|
320
|
+
* @typedef {Object} HideEventArgs
|
|
321
|
+
* @memberof componyx.UI.Box
|
|
322
|
+
* @property {Event} event - The original event object.
|
|
323
|
+
* @property {Boolean} cancel - Set to true to cancel hiding the box.
|
|
324
|
+
*/
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Box auto fit event arguments.
|
|
328
|
+
* @typedef {Object} AutoFitEventArgs
|
|
329
|
+
* @memberof componyx.UI.Box
|
|
330
|
+
* @property {Boolean} fitX - A value indicating if the box was fitted horizontally.
|
|
331
|
+
* @property {Boolean} fitY - A value indicating if the box was fitted vertically.
|
|
332
|
+
* @property {Boolean} invertedX - A value indicating if the box position was inverted horizontally.
|
|
333
|
+
* @property {Boolean} invertedY - A value indicating if the box position was inverted vertically.
|
|
334
|
+
* @property {Boolean} resizedX - A value indicating if the box was resized horizontally.
|
|
335
|
+
* @property {Boolean} resizedY - A value indicating if the box was resized vertically.
|
|
336
|
+
*/
|
|
337
|
+
|
|
338
|
+
// inherit base instance members
|
|
339
|
+
$base.Component.apply(this, [id, properties]);
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Adds the content template.
|
|
343
|
+
* @param {HTMLElement|HTMLElement[]|DocumentFragment|String} content The content template.
|
|
344
|
+
*/
|
|
345
|
+
this.setContentTemplate = function (content)
|
|
346
|
+
{
|
|
347
|
+
_instance.addTemplate('Content', content, false);
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Updates the box view to stretch and position with the updated content.
|
|
352
|
+
* @param {HTMLElement|HTMLElement[]|DocumentFragment|String} [content] A new content template.
|
|
353
|
+
* @param {Boolean} [show=true] A value indicating if the box should be displayed when hidden.
|
|
354
|
+
*/
|
|
355
|
+
this.update = function (content, show)
|
|
356
|
+
{
|
|
357
|
+
stopAnimation();
|
|
358
|
+
|
|
359
|
+
if (content)
|
|
360
|
+
{
|
|
361
|
+
_instance.addTemplate('Content', content, false);
|
|
362
|
+
_instance.applyTemplate(_instance.contentElement, 'Content');
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (_instance.modal || _instance.handleFocus)
|
|
366
|
+
createFocusableList();
|
|
367
|
+
|
|
368
|
+
if (_instance.autoPosition == _autoPositionOption.EXPAND)
|
|
369
|
+
getExpander();
|
|
370
|
+
|
|
371
|
+
if (_instance.showing || !show)
|
|
372
|
+
{
|
|
373
|
+
if (_instance.showing && _instance.autoPosition == _autoPositionOption.EXPAND && _instance.expander != _expander)
|
|
374
|
+
{
|
|
375
|
+
setExpanded(_expander, true);
|
|
376
|
+
setExpanded(_instance.expander);
|
|
377
|
+
_expander = _instance.expander;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
activate();
|
|
381
|
+
}
|
|
382
|
+
else
|
|
383
|
+
this.show();
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Stops the animation.
|
|
388
|
+
*/
|
|
389
|
+
this.stopAnimation = function ()
|
|
390
|
+
{
|
|
391
|
+
stopAnimation();
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Shows or hides the component.
|
|
396
|
+
*/
|
|
397
|
+
this.toggle = function ()
|
|
398
|
+
{
|
|
399
|
+
checkExpander();
|
|
400
|
+
$base.methods.toggle.call(_instance);
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Shows the component.
|
|
405
|
+
* @param {boolean} [instant] A value indicating if the box should be shown instantly without animation.
|
|
406
|
+
* @param {{clientX: number, clientY: number}} [pointerCoordinates] Optional pointer coordinates for POINTER auto-positioning. Pass these when the show is deferred (e.g. via setTimeout), as the original pointer event may no longer be available by then.
|
|
407
|
+
*/
|
|
408
|
+
this.show = function (instant, pointerCoordinates)
|
|
409
|
+
{
|
|
410
|
+
show(instant, pointerCoordinates);
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Hides the component.
|
|
415
|
+
* @param {Boolean} [instant] A value indicating if the box should be hidden instantly without animation.
|
|
416
|
+
*/
|
|
417
|
+
this.hide = function (instant)
|
|
418
|
+
{
|
|
419
|
+
hide(instant);
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Renders the component.
|
|
424
|
+
*/
|
|
425
|
+
this.render = function ()
|
|
426
|
+
{
|
|
427
|
+
if (_instance.renderState != $base.static.RenderState.RENDERING)
|
|
428
|
+
{
|
|
429
|
+
// call base render and return
|
|
430
|
+
$base.methods.render.call(_instance, preRender, 'box', false);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// render logic after loading resources
|
|
435
|
+
if (_instance.ajax.load && _instance.ajax.load.isDefined())
|
|
436
|
+
load();
|
|
437
|
+
else
|
|
438
|
+
draw();
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Destroys the component.
|
|
443
|
+
* @see {@link componyx.UI.base.methods#destroy}
|
|
444
|
+
*/
|
|
445
|
+
this.destroy = function (...args)
|
|
446
|
+
{
|
|
447
|
+
stopAnimation();
|
|
448
|
+
dispose();
|
|
449
|
+
$base.methods.destroy.call(this, ...args);
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
function show(instant, pointerCoordinates)
|
|
453
|
+
{
|
|
454
|
+
var a = _instance.animation; _instance.element;
|
|
455
|
+
var type = (a.showType != null) ? a.showType : _animationTypeOption.SLIDE;
|
|
456
|
+
|
|
457
|
+
checkExpander();
|
|
458
|
+
|
|
459
|
+
if (_instance.showing && _rendered)
|
|
460
|
+
{
|
|
461
|
+
_allowHide = true;
|
|
462
|
+
clearTimers();
|
|
463
|
+
|
|
464
|
+
if (instant)
|
|
465
|
+
stopAnimation();
|
|
466
|
+
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
_rendered = true;
|
|
471
|
+
_allowHide = false;
|
|
472
|
+
_expander = _instance.expander;
|
|
473
|
+
|
|
474
|
+
if (_instance.renderState != $base.static.RenderState.RENDERED)
|
|
475
|
+
{
|
|
476
|
+
_rendered = false;
|
|
477
|
+
|
|
478
|
+
if (_instance.renderState == $base.static.RenderState.NONE)
|
|
479
|
+
$base.methods.show.call(_instance);
|
|
480
|
+
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
clearTimers();
|
|
485
|
+
stopAnimation();
|
|
486
|
+
addDirectionClass();
|
|
487
|
+
removeOutsideClickHandler();
|
|
488
|
+
|
|
489
|
+
if (_instance.autoPosition == _autoPositionOption.POINTER)
|
|
490
|
+
{
|
|
491
|
+
_pointerCoordinates = pointerCoordinates ?? { clientX: ($lib.event) ? $lib.clientX($lib.event) : 0, clientY: ($lib.event) ? $lib.clientY($lib.event) : 0 };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (instant || !type)
|
|
495
|
+
execShow(instant);
|
|
496
|
+
else if (!_showTimerId)
|
|
497
|
+
_showTimerId = setTimeout(execShow.bind(_instance, instant), 0); // animate when device is ready
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function execShow(instant)
|
|
501
|
+
{
|
|
502
|
+
var a = _instance.animation, el = _instance.element,
|
|
503
|
+
type = (a.showType != null) ? a.showType : _animationTypeOption.SLIDE,
|
|
504
|
+
direction = getShowDirection(),
|
|
505
|
+
fade = (a.showFade != null) ? a.showFade : false;
|
|
506
|
+
|
|
507
|
+
$base.methods.show.call(_instance);
|
|
508
|
+
el.style.display = '';
|
|
509
|
+
activate();
|
|
510
|
+
setExpanded(_instance.expander);
|
|
511
|
+
bindOutsideClickHandler();
|
|
512
|
+
|
|
513
|
+
_instance.showing = true;
|
|
514
|
+
|
|
515
|
+
if (_instance.trackPointer)
|
|
516
|
+
{
|
|
517
|
+
$lib.on(document, 'pointermove', trackPointer, null, _instance);
|
|
518
|
+
$lib.on(document, 'pointerup', stopPointerTracking, _instance.hideOnOutsideClick);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
_modal.style.display = 'none';
|
|
522
|
+
|
|
523
|
+
if (_instance.autoInvertAnimation && _invertedX)
|
|
524
|
+
direction = (direction.indexOf('right') > -1) ? direction.replace('right', 'left') : direction.replace('left', 'right');
|
|
525
|
+
|
|
526
|
+
if (_instance.autoInvertAnimation && _invertedY)
|
|
527
|
+
direction = (direction.indexOf('down') > -1) ? direction.replace('down', 'up') : direction.replace('up', 'down');
|
|
528
|
+
|
|
529
|
+
if (!instant && type > 0)
|
|
530
|
+
{
|
|
531
|
+
if (type == _animationTypeOption.SLIDE)
|
|
532
|
+
_animation = $lib.slide(el, false, 'slide', direction, fade, showComplete);
|
|
533
|
+
else if (type == _animationTypeOption.REVEAL)
|
|
534
|
+
_animation = $lib.slide(el, false, 'reveal', direction, fade, showComplete);
|
|
535
|
+
else if (type == _animationTypeOption.CSS)
|
|
536
|
+
{
|
|
537
|
+
_animation = $lib.cssAnimation(el, a.showClass || _classOption.SHOWANIMATION, [], { onComplete: showComplete });
|
|
538
|
+
}
|
|
539
|
+
else
|
|
540
|
+
showComplete();
|
|
541
|
+
}
|
|
542
|
+
else
|
|
543
|
+
showComplete();
|
|
544
|
+
|
|
545
|
+
_allowHide = true;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function hide(instant)
|
|
549
|
+
{
|
|
550
|
+
if (!_instance.showing)
|
|
551
|
+
{
|
|
552
|
+
clearTimers();
|
|
553
|
+
|
|
554
|
+
if (instant)
|
|
555
|
+
stopAnimation();
|
|
556
|
+
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (_instance.renderState != $base.static.RenderState.RENDERED)
|
|
561
|
+
return;
|
|
562
|
+
|
|
563
|
+
var a = _instance.animation,
|
|
564
|
+
type = (a.hideType != null) ? a.hideType : _animationTypeOption.SLIDE;
|
|
565
|
+
|
|
566
|
+
clearTimers();
|
|
567
|
+
stopAnimation();
|
|
568
|
+
_allowHide = false;
|
|
569
|
+
|
|
570
|
+
if (instant || !type) // synchronous
|
|
571
|
+
execHide(instant);
|
|
572
|
+
else if (!_hideTimerId)
|
|
573
|
+
_hideTimerId = setTimeout(execHide.bind(_instance, instant), 0); // animate when device is ready
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
function execHide(instant)
|
|
577
|
+
{
|
|
578
|
+
var a = _instance.animation, el = _instance.element,
|
|
579
|
+
type = (a.hideType != null) ? a.hideType : _animationTypeOption.SLIDE,
|
|
580
|
+
direction = getHideDirection(),
|
|
581
|
+
fade = (a.hideFade != null) ? a.hideFade : false,
|
|
582
|
+
args = { event: $lib.event, cancel: false };
|
|
583
|
+
|
|
584
|
+
_instance.showing = false;
|
|
585
|
+
_instance.events.onHide.fire(_instance, args);
|
|
586
|
+
|
|
587
|
+
if (args.cancel)
|
|
588
|
+
{
|
|
589
|
+
_instance.showing = _allowHide = true;
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
removeOutsideClickHandler();
|
|
594
|
+
stopPointerTracking();
|
|
595
|
+
el.style.display = '';
|
|
596
|
+
_modal.style.display = 'none';
|
|
597
|
+
|
|
598
|
+
if (!instant && type > 0)
|
|
599
|
+
{
|
|
600
|
+
if (_instance.autoInvertAnimation && _invertedX)
|
|
601
|
+
direction = (direction.indexOf('right') > -1) ? direction.replace('right', 'left') : direction.replace('left', 'right');
|
|
602
|
+
|
|
603
|
+
if (_instance.autoInvertAnimation && _invertedY)
|
|
604
|
+
direction = (direction.indexOf('down') > -1) ? direction.replace('down', 'up') : direction.replace('up', 'down');
|
|
605
|
+
|
|
606
|
+
if (type == _animationTypeOption.SLIDE)
|
|
607
|
+
_animation = $lib.slide(el, true, 'slide', direction, fade, hideComplete);
|
|
608
|
+
else if (type == _animationTypeOption.REVEAL)
|
|
609
|
+
_animation = $lib.slide(el, true, 'reveal', direction, fade, hideComplete);
|
|
610
|
+
else if (type == _animationTypeOption.CSS)
|
|
611
|
+
{
|
|
612
|
+
_animation = $lib.cssAnimation(el, a.hideClass || _classOption.HIDEANIMATION, [], { onComplete: hideComplete });
|
|
613
|
+
}
|
|
614
|
+
else
|
|
615
|
+
hideComplete();
|
|
616
|
+
}
|
|
617
|
+
else
|
|
618
|
+
hideComplete();
|
|
619
|
+
|
|
620
|
+
_allowHide = true;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
function showComplete()
|
|
624
|
+
{
|
|
625
|
+
if (arguments[0] && arguments[0] instanceof Event && arguments[0].target !== _instance.element)
|
|
626
|
+
return;
|
|
627
|
+
|
|
628
|
+
var el = _instance.element;
|
|
629
|
+
|
|
630
|
+
_showTimerId = null;
|
|
631
|
+
|
|
632
|
+
$lib.addClass(el, _classOption.SHOW);
|
|
633
|
+
el.style.display = '';
|
|
634
|
+
|
|
635
|
+
if (_instance.modal)
|
|
636
|
+
_modal.style.display = '';
|
|
637
|
+
|
|
638
|
+
if (_instance.modal || _instance.handleFocus)
|
|
639
|
+
{
|
|
640
|
+
createFocusableList();
|
|
641
|
+
blurAll();
|
|
642
|
+
$lib.on(el, 'keydown', setFocus);
|
|
643
|
+
|
|
644
|
+
if (_instance.autoFocus && _focusable.length > 0)
|
|
645
|
+
setTimeout(function () { setFocus(); }, 1);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (_animation)
|
|
649
|
+
{
|
|
650
|
+
_animation = null;
|
|
651
|
+
position();
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
_instance.events.onShowComplete.fire(_instance);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function hideComplete()
|
|
658
|
+
{
|
|
659
|
+
if (arguments[0] && arguments[0] instanceof Event && arguments[0].target !== _instance.element)
|
|
660
|
+
return;
|
|
661
|
+
|
|
662
|
+
var el = _instance.element;
|
|
663
|
+
|
|
664
|
+
_hideTimerId = null;
|
|
665
|
+
|
|
666
|
+
if (_instance.modal || _instance.handleFocus)
|
|
667
|
+
$lib.off(el, 'keydown', setFocus);
|
|
668
|
+
|
|
669
|
+
$lib.removeClass(el, _classOption.SHOW);
|
|
670
|
+
setExpanded(_instance.expander, true);
|
|
671
|
+
_instance.showing = false;
|
|
672
|
+
_animation = null;
|
|
673
|
+
_pointerCoordinates = null;
|
|
674
|
+
$base.methods.hide.call(_instance, false);
|
|
675
|
+
_instance.events.onHideComplete.fire(_instance);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
function clearTimers()
|
|
679
|
+
{
|
|
680
|
+
clearTimeout(_showTimerId);
|
|
681
|
+
clearTimeout(_hideTimerId);
|
|
682
|
+
_showTimerId = _hideTimerId = null;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function trackPointer(e)
|
|
686
|
+
{
|
|
687
|
+
const pointerType = e.pointerType;
|
|
688
|
+
|
|
689
|
+
if (pointerType === "mouse" || pointerType === "pen")
|
|
690
|
+
{
|
|
691
|
+
position();
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
function stopPointerTracking(hide)
|
|
696
|
+
{
|
|
697
|
+
$lib.off(document, 'pointermove', trackPointer);
|
|
698
|
+
$lib.off(document, 'pointerup', stopPointerTracking);
|
|
699
|
+
|
|
700
|
+
if (hide)
|
|
701
|
+
{
|
|
702
|
+
_allowHide = true;
|
|
703
|
+
checkHide();
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function checkExpander()
|
|
708
|
+
{
|
|
709
|
+
getExpander();
|
|
710
|
+
|
|
711
|
+
if (_instance.expander != _expander && _instance.autoPosition == _autoPositionOption.EXPAND)
|
|
712
|
+
{
|
|
713
|
+
_instance.hide(true); // instant hide when previous expander element is different
|
|
714
|
+
setExpanded(_expander, true);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
function getExpander()
|
|
719
|
+
{
|
|
720
|
+
if (!$lib.isEmpty(_instance.expander) && (typeof _instance.expander === 'string') && $lib('#' + _instance.expander))
|
|
721
|
+
_instance.expander = $lib('#' + _instance.expander);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
function addDirectionClass()
|
|
725
|
+
{
|
|
726
|
+
var direction = _instance.animation.showDirection || 'right',
|
|
727
|
+
vertical = (_instance.expandDirection == _expandDirectionOption.DOWN || _instance.expandDirection == _expandDirectionOption.UP);
|
|
728
|
+
|
|
729
|
+
clearDirectionClasses();
|
|
730
|
+
|
|
731
|
+
if (_instance.expandDirection != null)
|
|
732
|
+
$lib.addClass(_instance.element, _expandDirectionOption.getName(_instance.expandDirection));
|
|
733
|
+
else
|
|
734
|
+
$lib.addClass(_instance.element, direction);
|
|
735
|
+
|
|
736
|
+
if (vertical && _instance.alignX > 0)
|
|
737
|
+
$lib.addClass(_instance.element, $lib.format('align-{0}', _alignXOption.getName(_instance.alignX)));
|
|
738
|
+
else if (!vertical && _instance.alignY > 0)
|
|
739
|
+
$lib.addClass(_instance.element, $lib.format('align-{0}', _alignYOption.getName(_instance.alignY)));
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
function clearDirectionClasses()
|
|
743
|
+
{
|
|
744
|
+
$lib.removeClass(_instance.element, 'down right up left align-left align-center align-right align-top align-bottom');
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
function setExpanded(expander, remove)
|
|
748
|
+
{
|
|
749
|
+
if ($lib.isEmpty(expander) || _instance.autoPosition != _autoPositionOption.EXPAND)
|
|
750
|
+
return;
|
|
751
|
+
|
|
752
|
+
if (remove)
|
|
753
|
+
$lib.removeClass(expander, _classOption.EXPANDED);
|
|
754
|
+
else
|
|
755
|
+
$lib.addClass(expander, _classOption.EXPANDED);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
function checkHide()
|
|
759
|
+
{
|
|
760
|
+
if (_allowHide)
|
|
761
|
+
_instance.hide();
|
|
762
|
+
|
|
763
|
+
_allowHide = true;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
function blurAll()
|
|
767
|
+
{
|
|
768
|
+
$lib(function (el)
|
|
769
|
+
{
|
|
770
|
+
if (el.blur)
|
|
771
|
+
el.blur();
|
|
772
|
+
|
|
773
|
+
}, document.body);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
function createFocusableList()
|
|
777
|
+
{
|
|
778
|
+
_focusable = [];
|
|
779
|
+
|
|
780
|
+
$lib(function (el)
|
|
781
|
+
{
|
|
782
|
+
if ($lib.focusable(el))
|
|
783
|
+
_focusable.push(el);
|
|
784
|
+
|
|
785
|
+
}, _instance.element);
|
|
786
|
+
|
|
787
|
+
if (_instance.tabIndexFocus)
|
|
788
|
+
{
|
|
789
|
+
_focusable = _focusable.sort(function (a, b)
|
|
790
|
+
{
|
|
791
|
+
return (a.tabIndex - b.tabIndex);
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
function setFocus(e)
|
|
797
|
+
{
|
|
798
|
+
let keyCode = (e) ? e.key : null,
|
|
799
|
+
shift = (e) ? e.shiftKey : false,
|
|
800
|
+
startIndex, element, index, focusable,
|
|
801
|
+
doc = _instance.element.ownerDocument || document;
|
|
802
|
+
|
|
803
|
+
if (!_focusable.length)
|
|
804
|
+
return;
|
|
805
|
+
|
|
806
|
+
if (!e || keyCode == 'Tab')
|
|
807
|
+
{
|
|
808
|
+
if (e)
|
|
809
|
+
{
|
|
810
|
+
element = $lib.eventSource(e);
|
|
811
|
+
startIndex = index = $lib.indexOf(_focusable, element);
|
|
812
|
+
|
|
813
|
+
if (index == -1)
|
|
814
|
+
return;
|
|
815
|
+
|
|
816
|
+
if (index == _focusable.length - 1)
|
|
817
|
+
index = (shift) ? index - 1 : 0;
|
|
818
|
+
else if (shift)
|
|
819
|
+
index--;
|
|
820
|
+
else
|
|
821
|
+
index++;
|
|
822
|
+
|
|
823
|
+
if (index < 0)
|
|
824
|
+
index = 0;
|
|
825
|
+
|
|
826
|
+
e.returnValue = false;
|
|
827
|
+
}
|
|
828
|
+
else
|
|
829
|
+
{
|
|
830
|
+
startIndex = _focusable.length;
|
|
831
|
+
index = 0;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// loop until next visible focusable element is found or when we are back on the current element
|
|
835
|
+
while (!focusable && (startIndex != index))
|
|
836
|
+
{
|
|
837
|
+
_focusable[index].focus();
|
|
838
|
+
focusable = (_focusable[index] === doc.activeElement);
|
|
839
|
+
|
|
840
|
+
if (!focusable)
|
|
841
|
+
{
|
|
842
|
+
if (shift)
|
|
843
|
+
index--;
|
|
844
|
+
else
|
|
845
|
+
index++;
|
|
846
|
+
|
|
847
|
+
if (index < 0)
|
|
848
|
+
index = _focusable.length - 1;
|
|
849
|
+
|
|
850
|
+
if (index != startIndex && index == _focusable.length)
|
|
851
|
+
index = 0;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
function getShowDirection()
|
|
860
|
+
{
|
|
861
|
+
var a = _instance.animation;
|
|
862
|
+
|
|
863
|
+
if (a.showDirection)
|
|
864
|
+
return a.showDirection;
|
|
865
|
+
|
|
866
|
+
if (_instance.expandDirection != null)
|
|
867
|
+
return _expandDirectionOption.getName(_instance.expandDirection);
|
|
868
|
+
else
|
|
869
|
+
return 'right';
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function getHideDirection()
|
|
873
|
+
{
|
|
874
|
+
var a = _instance.animation;
|
|
875
|
+
return (a.hideDirection != null) ? a.hideDirection : getShowDirection();
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
function stopAnimation()
|
|
879
|
+
{
|
|
880
|
+
if (_animation)
|
|
881
|
+
_animation.complete();
|
|
882
|
+
|
|
883
|
+
_animation = null;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
function preRender()
|
|
887
|
+
{
|
|
888
|
+
// initialize script and css
|
|
889
|
+
return ['Box'];
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
function load(parentItem, initialLoad)
|
|
893
|
+
{
|
|
894
|
+
_instance.ajaxCall('load', null, { onSuccess: dataLoaded });
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function dataLoaded(ajaxArgs)
|
|
898
|
+
{
|
|
899
|
+
draw(ajaxArgs.data);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
function draw(data)
|
|
903
|
+
{
|
|
904
|
+
var divBox = _instance.element,
|
|
905
|
+
content = document.createElement(_instance.contentTag || 'div');
|
|
906
|
+
|
|
907
|
+
_modal = document.createElement('div');
|
|
908
|
+
_modal.className = _instance.cssClassModal || _classOption.MODAL;
|
|
909
|
+
$lib.updateStyle(_modal.style, _modalStyle);
|
|
910
|
+
divBox.appendChild(_modal);
|
|
911
|
+
|
|
912
|
+
content.className = _instance.cssClassContent || _classOption.CONTENT;
|
|
913
|
+
divBox.appendChild(content);
|
|
914
|
+
|
|
915
|
+
if (data)
|
|
916
|
+
{
|
|
917
|
+
content.innerHTML = data;
|
|
918
|
+
}
|
|
919
|
+
else
|
|
920
|
+
{
|
|
921
|
+
_instance.applyTemplate(content, 'Content');
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
_contentElement = content;
|
|
925
|
+
_resizeObserver = new ResizeObserver(positionDelayed);
|
|
926
|
+
_resizeObserver.observe(_contentElement);
|
|
927
|
+
|
|
928
|
+
bindGlobalEvents();
|
|
929
|
+
|
|
930
|
+
if (_instance.draggable)
|
|
931
|
+
{
|
|
932
|
+
_draggable = $lib.draggable(_instance.element, $base.static.initDragSettings(_instance.dragSettings));
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
_instance.postRender();
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
function activate()
|
|
939
|
+
{
|
|
940
|
+
_styleCache = {};
|
|
941
|
+
$lib.setStyle(_instance.element, '');
|
|
942
|
+
|
|
943
|
+
getExpander();
|
|
944
|
+
stretch();
|
|
945
|
+
setStyle();
|
|
946
|
+
position();
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
function stretch()
|
|
950
|
+
{
|
|
951
|
+
if (!_instance.showing || _animation || (!_instance.stretchToExpander && !_instance.stretchToContent))
|
|
952
|
+
return;
|
|
953
|
+
|
|
954
|
+
var divBox = _instance.element, contentSize, expanderSize;
|
|
955
|
+
|
|
956
|
+
if (_instance.stretchToContent)
|
|
957
|
+
{
|
|
958
|
+
contentSize = $lib.size(_instance.contentElement);
|
|
959
|
+
divBox.style.minWidth = $lib.unit(contentSize.width);
|
|
960
|
+
divBox.style.minHeight = $lib.unit(contentSize.height);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
if (_instance.stretchToExpander && _instance.expander)
|
|
964
|
+
{
|
|
965
|
+
expanderSize = $lib.size(_instance.expander);
|
|
966
|
+
|
|
967
|
+
if (!contentSize)
|
|
968
|
+
contentSize = $lib.size(_instance.contentElement);
|
|
969
|
+
|
|
970
|
+
if (expanderSize.width > contentSize.width)
|
|
971
|
+
divBox.style.minWidth = $lib.unit(expanderSize.width);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
function setStyle()
|
|
976
|
+
{
|
|
977
|
+
var divBox = _instance.element,
|
|
978
|
+
content = _instance.contentElement,
|
|
979
|
+
style = [];
|
|
980
|
+
|
|
981
|
+
$lib.updateStyle(divBox.style, _instance.style);
|
|
982
|
+
content.style.width = content.style.height = '';
|
|
983
|
+
|
|
984
|
+
if (_instance.top)
|
|
985
|
+
style.push('top: ' + $lib.unit(_instance.top));
|
|
986
|
+
if (_instance.right)
|
|
987
|
+
style.push('right: ' + $lib.unit(_instance.right));
|
|
988
|
+
if (_instance.bottom)
|
|
989
|
+
style.push('bottom: ' + $lib.unit(_instance.bottom));
|
|
990
|
+
if (_instance.left)
|
|
991
|
+
style.push('left: ' + $lib.unit(_instance.left));
|
|
992
|
+
if (_instance.width)
|
|
993
|
+
style.push('width: ' + $lib.unit(_instance.width));
|
|
994
|
+
if (_instance.height)
|
|
995
|
+
style.push('height: ' + $lib.unit(_instance.height));
|
|
996
|
+
|
|
997
|
+
// add styles
|
|
998
|
+
if (style.length > 0)
|
|
999
|
+
$lib.updateStyle(divBox.style, style.join(';'));
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
function position()
|
|
1003
|
+
{
|
|
1004
|
+
clearTimeout(_timerId);
|
|
1005
|
+
_timerId = null;
|
|
1006
|
+
|
|
1007
|
+
if (!_instance.showing || _animation || (_instance.autoPosition == _autoPositionOption.NONE && !_instance.autoFit))
|
|
1008
|
+
return;
|
|
1009
|
+
|
|
1010
|
+
var divBox = _instance.element;
|
|
1011
|
+
|
|
1012
|
+
_invertMarginX = _invertMarginY = 0;
|
|
1013
|
+
_instance.events.onPrePosition.fire(_instance, null);
|
|
1014
|
+
|
|
1015
|
+
if (_instance.autoInvertFit)
|
|
1016
|
+
{
|
|
1017
|
+
$lib.removeClass(divBox, _instance.cssClassHorizontalInverted || _classOption.HORIZONTALINVERTED);
|
|
1018
|
+
$lib.removeClass(divBox, _instance.cssClassVerticalInverted || _classOption.VERTICALINVERTED);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (_instance.autoPosition != _autoPositionOption.NONE)
|
|
1022
|
+
{
|
|
1023
|
+
var stylePos = _styleCache.position || $lib.styleValue(divBox, 'position');
|
|
1024
|
+
|
|
1025
|
+
if (stylePos != 'absolute' && stylePos != 'fixed')
|
|
1026
|
+
{
|
|
1027
|
+
divBox.style.position = 'fixed';
|
|
1028
|
+
stylePos = 'fixed';
|
|
1029
|
+
_styleCache.position = stylePos;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
divBox.style.position = stylePos;
|
|
1033
|
+
|
|
1034
|
+
if (_instance.autoPosition == _autoPositionOption.EXPAND)
|
|
1035
|
+
positionExpand(stylePos);
|
|
1036
|
+
else if (_instance.autoPosition == _autoPositionOption.POINTER && _pointerCoordinates)
|
|
1037
|
+
positionAtPointer(stylePos, _pointerCoordinates.clientX, _pointerCoordinates.clientY);
|
|
1038
|
+
else
|
|
1039
|
+
positionAuto(stylePos);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
_instance.events.onPostPosition.fire(_instance, null);
|
|
1043
|
+
|
|
1044
|
+
if (_instance.autoFit)
|
|
1045
|
+
fit();
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
function clearPosition()
|
|
1049
|
+
{
|
|
1050
|
+
$lib.updateStyle(_instance.element.style, 'left: $; right: $; top: $; bottom: $; width: $; height: $;'.replace(/\$/g, 'auto'));
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
function positionExpand(stylePos)
|
|
1054
|
+
{
|
|
1055
|
+
clearPosition();
|
|
1056
|
+
|
|
1057
|
+
var coords = {},
|
|
1058
|
+
vertical = (_instance.expandDirection == _expandDirectionOption.DOWN || _instance.expandDirection == _expandDirectionOption.UP),
|
|
1059
|
+
divBox = _instance.element,
|
|
1060
|
+
expander = _instance.expander,
|
|
1061
|
+
position = $lib.getPos(expander, null, stylePos == 'fixed'),
|
|
1062
|
+
boxWidth = _styleCache.width = _styleCache.width || divBox.offsetWidth,
|
|
1063
|
+
boxHeight = _styleCache.height = _styleCache.height || divBox.offsetHeight,
|
|
1064
|
+
expanderWidth = (vertical && _instance.alignX > 0) ? expander.offsetWidth : 0,
|
|
1065
|
+
expanderHeight = (!vertical && _instance.alignY > 0) ? expander.offsetHeight : 0;
|
|
1066
|
+
|
|
1067
|
+
_invertMarginX = position.width;
|
|
1068
|
+
_invertMarginY = position.height;
|
|
1069
|
+
|
|
1070
|
+
switch (_instance.expandDirection)
|
|
1071
|
+
{
|
|
1072
|
+
case (_expandDirectionOption.DOWN):
|
|
1073
|
+
coords.left = position.left;
|
|
1074
|
+
coords.top = position.bottom;
|
|
1075
|
+
break;
|
|
1076
|
+
|
|
1077
|
+
case (_expandDirectionOption.UP):
|
|
1078
|
+
coords.left = position.left;
|
|
1079
|
+
coords.top = position.top - boxHeight;
|
|
1080
|
+
break;
|
|
1081
|
+
|
|
1082
|
+
case (_expandDirectionOption.RIGHT):
|
|
1083
|
+
coords.left = position.right;
|
|
1084
|
+
coords.top = position.top;
|
|
1085
|
+
break;
|
|
1086
|
+
|
|
1087
|
+
case (_expandDirectionOption.LEFT):
|
|
1088
|
+
coords.left = position.left - boxWidth;
|
|
1089
|
+
coords.top = position.top;
|
|
1090
|
+
break;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
if (vertical && _instance.alignX > 0)
|
|
1094
|
+
{
|
|
1095
|
+
if (_instance.alignX == _alignXOption.CENTER)
|
|
1096
|
+
coords.left += (expanderWidth / 2) - (boxWidth / 2);
|
|
1097
|
+
else
|
|
1098
|
+
coords.left = position.right - boxWidth;
|
|
1099
|
+
}
|
|
1100
|
+
else if (!vertical && _instance.alignY > 0)
|
|
1101
|
+
{
|
|
1102
|
+
if (_instance.alignY == _alignYOption.CENTER)
|
|
1103
|
+
coords.top += (expanderHeight / 2) - (boxHeight / 2);
|
|
1104
|
+
else
|
|
1105
|
+
coords.top = position.bottom - boxHeight;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
$lib.setPos(divBox, coords, true);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
function positionAtPointer(stylePos, clientX, clientY)
|
|
1112
|
+
{
|
|
1113
|
+
var coords = {},
|
|
1114
|
+
direction = _instance.animation.showDirection || 'right',
|
|
1115
|
+
divBox = _instance.element,
|
|
1116
|
+
boxWidth = _styleCache.width = _styleCache.width || divBox.offsetWidth,
|
|
1117
|
+
boxHeight = _styleCache.height = _styleCache.height || divBox.offsetHeight,
|
|
1118
|
+
scroll = $lib.getScrollPosition(),
|
|
1119
|
+
y = (stylePos != 'fixed') ? clientY + scroll.scrollTop : clientY,
|
|
1120
|
+
x = (stylePos != 'fixed') ? clientX + scroll.scrollLeft : clientX;
|
|
1121
|
+
|
|
1122
|
+
clearPosition();
|
|
1123
|
+
|
|
1124
|
+
if (_instance.expandDirection != null)
|
|
1125
|
+
direction = _expandDirectionOption.getName(_instance.expandDirection); // expand direction has precedence over animation direction
|
|
1126
|
+
|
|
1127
|
+
if (direction.indexOf('left') > -1)
|
|
1128
|
+
coords.left = x - boxWidth;
|
|
1129
|
+
else
|
|
1130
|
+
coords.left = x;
|
|
1131
|
+
|
|
1132
|
+
if (direction.indexOf('up') > -1)
|
|
1133
|
+
coords.top = y - boxHeight;
|
|
1134
|
+
else
|
|
1135
|
+
coords.top = y;
|
|
1136
|
+
|
|
1137
|
+
// unlike the auto position setting 'expand', the auto postion setting 'pointer' allows both horizontal and vertical alignment.
|
|
1138
|
+
|
|
1139
|
+
if (_instance.alignX == _alignXOption.CENTER)
|
|
1140
|
+
coords.left = x - (boxWidth / 2);
|
|
1141
|
+
else if (_instance.alignX > 0)
|
|
1142
|
+
coords.left = x - boxWidth;
|
|
1143
|
+
|
|
1144
|
+
if (_instance.alignY == _alignYOption.CENTER)
|
|
1145
|
+
coords.top = y - (boxHeight / 2);
|
|
1146
|
+
else if (_instance.alignY > 0)
|
|
1147
|
+
coords.top = y - boxHeight;
|
|
1148
|
+
|
|
1149
|
+
$lib.setPos(divBox, coords, true);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
function positionAuto(stylePos)
|
|
1153
|
+
{
|
|
1154
|
+
var divBox = _instance.element, position;
|
|
1155
|
+
|
|
1156
|
+
clearPosition();
|
|
1157
|
+
position = $lib.getPos(divBox, $lib.positionedParent(divBox), stylePos == 'fixed');
|
|
1158
|
+
|
|
1159
|
+
if (_instance.autoPosition <= _autoPositionOption.TOPRIGHT)
|
|
1160
|
+
{
|
|
1161
|
+
divBox.style.top = '0%';
|
|
1162
|
+
}
|
|
1163
|
+
else if (_instance.autoPosition <= _autoPositionOption.RIGHT)
|
|
1164
|
+
{
|
|
1165
|
+
divBox.style.top = '50%';
|
|
1166
|
+
divBox.style.marginTop = $lib.unit((position.height / 2) * -1);
|
|
1167
|
+
}
|
|
1168
|
+
else
|
|
1169
|
+
{
|
|
1170
|
+
divBox.style.bottom = '0%';
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
if (_instance.autoPosition == _autoPositionOption.TOPLEFT || _instance.autoPosition == _autoPositionOption.LEFT || _instance.autoPosition == _autoPositionOption.BOTTOMLEFT)
|
|
1174
|
+
{
|
|
1175
|
+
divBox.style.left = '0%';
|
|
1176
|
+
}
|
|
1177
|
+
else if (_instance.autoPosition == _autoPositionOption.TOPCENTER || _instance.autoPosition == _autoPositionOption.CENTER || _instance.autoPosition == _autoPositionOption.BOTTOMCENTER)
|
|
1178
|
+
{
|
|
1179
|
+
divBox.style.left = '50%';
|
|
1180
|
+
divBox.style.marginLeft = $lib.unit((position.width / 2) * -1);
|
|
1181
|
+
}
|
|
1182
|
+
else
|
|
1183
|
+
{
|
|
1184
|
+
divBox.style.right = '0%';
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
function fit()
|
|
1189
|
+
{
|
|
1190
|
+
var divBox = _instance.element,
|
|
1191
|
+
winSize = $lib.getWindowSize(),
|
|
1192
|
+
rect = $lib.getPos(divBox, null, true),
|
|
1193
|
+
autoPos = (_instance.autoPosition == _autoPositionOption.NONE || _instance.autoPosition == _autoPositionOption.EXPAND || _instance.autoPosition == _autoPositionOption.POINTER),
|
|
1194
|
+
fitX = (autoPos && (rect.left < 0 || rect.right > winSize.width)) ? true : false,
|
|
1195
|
+
fitY = (autoPos && (rect.top < 0 || rect.bottom > winSize.height)) ? true : false,
|
|
1196
|
+
vertical = (_instance.expandDirection == _expandDirectionOption.DOWN || _instance.expandDirection == _expandDirectionOption.UP);
|
|
1197
|
+
|
|
1198
|
+
_invertedX = _invertedY = _resizedX = _resizedY = false;
|
|
1199
|
+
divBox.style.removeProperty('--expander-offset');
|
|
1200
|
+
|
|
1201
|
+
if (fitX)
|
|
1202
|
+
{
|
|
1203
|
+
fitHorizontal(rect, winSize);
|
|
1204
|
+
|
|
1205
|
+
if (vertical)
|
|
1206
|
+
{
|
|
1207
|
+
$lib.removeClass(_instance.element, 'align-left align-center align-right');
|
|
1208
|
+
|
|
1209
|
+
if (divBox.style.left && divBox.style.left != 'auto')
|
|
1210
|
+
$lib.addClass(_instance.element, 'align-left');
|
|
1211
|
+
else
|
|
1212
|
+
$lib.addClass(_instance.element, 'align-right');
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
if (!fitY)
|
|
1216
|
+
divBox.style.top = $lib.unit(rect.top - parseFloat($.styleValue(divBox, 'margin-top', true))); // must be changed to match fixed position
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
if (fitY)
|
|
1220
|
+
{
|
|
1221
|
+
fitVertical(rect, winSize);
|
|
1222
|
+
|
|
1223
|
+
if (!vertical)
|
|
1224
|
+
{
|
|
1225
|
+
$lib.removeClass(_instance.element, 'align-top align-center align-bottom');
|
|
1226
|
+
|
|
1227
|
+
if (divBox.style.top && divBox.style.top != 'auto')
|
|
1228
|
+
$lib.addClass(_instance.element, 'align-top');
|
|
1229
|
+
else
|
|
1230
|
+
$lib.addClass(_instance.element, 'align-bottom');
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
if (!fitX)
|
|
1234
|
+
divBox.style.left = $lib.unit(rect.left - parseFloat($.styleValue(divBox, 'margin-left', true))); // must be changed to match fixed position
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
if (fitX || fitY)
|
|
1238
|
+
{
|
|
1239
|
+
divBox.style.position = 'fixed';
|
|
1240
|
+
setExpanderOffset(divBox, vertical);
|
|
1241
|
+
_instance.events.onAutoFit.fire(_instance, { fitX: fitX, fitY: fitY, invertedX: _invertedX, invertedY: _invertedY, resizedX: _resizedX, resizedY: _resizedY });
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
function fitVertical(rect, winSize)
|
|
1246
|
+
{
|
|
1247
|
+
var divBox = _instance.element,
|
|
1248
|
+
invertRect = getInvertRect(divBox, true),
|
|
1249
|
+
space = 0, invertPos = 0, invertSpace = 0, fits = (rect.height <= winSize.height),
|
|
1250
|
+
resize = function ()
|
|
1251
|
+
{
|
|
1252
|
+
if (fits || !_instance.autoResizeFit) return;
|
|
1253
|
+
|
|
1254
|
+
const cs = window.getComputedStyle(divBox),
|
|
1255
|
+
boxSizing = (cs.boxSizing || cs.getPropertyValue('box-sizing') || 'content-box').toLowerCase();
|
|
1256
|
+
|
|
1257
|
+
let baseSpace;
|
|
1258
|
+
if (_instance.resizeToMaxHeight)
|
|
1259
|
+
{
|
|
1260
|
+
baseSpace = winSize.height;
|
|
1261
|
+
divBox.style.top = $lib.unit(0);
|
|
1262
|
+
}
|
|
1263
|
+
else
|
|
1264
|
+
{
|
|
1265
|
+
baseSpace = (_invertedY) ? invertSpace : space;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
let finalHeight = baseSpace;
|
|
1269
|
+
|
|
1270
|
+
if (boxSizing === 'content-box') // subtract border+padding because style.height sets the content box
|
|
1271
|
+
{
|
|
1272
|
+
const devSize = $lib.borderAndPadding(divBox);
|
|
1273
|
+
finalHeight = baseSpace - devSize.height;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
divBox.style.height = (finalHeight > 0) ? $lib.unit(finalHeight) : '0px';
|
|
1277
|
+
_styleCache.height = null;
|
|
1278
|
+
_resizedY = true;
|
|
1279
|
+
};
|
|
1280
|
+
|
|
1281
|
+
// clear position and margin
|
|
1282
|
+
$lib.updateStyle(divBox.style, 'top:auto;bottom:auto;margin-top:0px !important;margin-bottom:0px !important;');
|
|
1283
|
+
|
|
1284
|
+
if (_instance.autoPosition != _autoPositionOption.EXPAND || !_instance.autoInvertFit
|
|
1285
|
+
|| (_instance.expandDirection != _expandDirectionOption.DOWN && _instance.expandDirection != _expandDirectionOption.UP))
|
|
1286
|
+
{
|
|
1287
|
+
if (rect.top < 0)
|
|
1288
|
+
divBox.style.top = $lib.unit(0);
|
|
1289
|
+
else
|
|
1290
|
+
divBox.style.bottom = $lib.unit(0);
|
|
1291
|
+
|
|
1292
|
+
return resize();
|
|
1293
|
+
}
|
|
1294
|
+
else if (_instance.expandDirection == _expandDirectionOption.DOWN)
|
|
1295
|
+
{
|
|
1296
|
+
if (rect.top < 0)
|
|
1297
|
+
{
|
|
1298
|
+
divBox.style.top = $lib.unit(0);
|
|
1299
|
+
return resize();
|
|
1300
|
+
}
|
|
1301
|
+
else if ((rect.top - _invertMarginY) > winSize.height)
|
|
1302
|
+
{
|
|
1303
|
+
divBox.style.bottom = $lib.unit(0);
|
|
1304
|
+
return resize();
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
space = winSize.height - rect.top;
|
|
1308
|
+
invertPos = invertRect.top - (invertRect.height + _invertMarginY);
|
|
1309
|
+
invertSpace = (invertPos < 0) ? invertRect.bottom - invertRect.height - _invertMarginY : invertRect.height;
|
|
1310
|
+
}
|
|
1311
|
+
else
|
|
1312
|
+
{
|
|
1313
|
+
if (rect.bottom > winSize.height)
|
|
1314
|
+
{
|
|
1315
|
+
divBox.style.bottom = $lib.unit(0);
|
|
1316
|
+
return resize();
|
|
1317
|
+
}
|
|
1318
|
+
else if ((rect.bottom + _invertMarginY) < 0)
|
|
1319
|
+
{
|
|
1320
|
+
divBox.style.top = $lib.unit(0);
|
|
1321
|
+
return resize();
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
space = (winSize.height < rect.bottom) ? winSize.height : rect.bottom;
|
|
1325
|
+
invertPos = invertRect.bottom + _invertMarginY;
|
|
1326
|
+
invertSpace = (invertPos < 0) ? 0 : winSize.height - invertPos;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
if (rect.height <= invertSpace)
|
|
1330
|
+
{
|
|
1331
|
+
// box fits inverted
|
|
1332
|
+
$lib.addClass(divBox, _instance.cssClassVerticalInverted || _classOption.VERTICALINVERTED);
|
|
1333
|
+
divBox.style.top = $lib.unit(invertPos);
|
|
1334
|
+
_invertedY = true;
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
else
|
|
1338
|
+
{
|
|
1339
|
+
// when invert space is larger, utilize that space
|
|
1340
|
+
if (space >= invertSpace)
|
|
1341
|
+
{
|
|
1342
|
+
if (fits && rect.top >= 0)
|
|
1343
|
+
divBox.style.bottom = $lib.unit(0);
|
|
1344
|
+
else
|
|
1345
|
+
divBox.style.top = (rect.top >= 0) ? $lib.unit(rect.top) : $lib.unit(0);
|
|
1346
|
+
}
|
|
1347
|
+
else
|
|
1348
|
+
divBox.style.top = (invertPos >= 0) ? $lib.unit(invertPos) : $lib.unit(0);
|
|
1349
|
+
|
|
1350
|
+
if (invertSpace > space)
|
|
1351
|
+
{
|
|
1352
|
+
$lib.addClass(divBox, _instance.cssClassVerticalInverted || _classOption.VERTICALINVERTED);
|
|
1353
|
+
_invertedY = true;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
if (!_instance.resizeToMaxHeight)
|
|
1357
|
+
fits = (space >= invertSpace) ? (rect.height <= space) : (rect.height <= invertSpace);
|
|
1358
|
+
|
|
1359
|
+
return resize();
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
function fitHorizontal(rect, winSize)
|
|
1364
|
+
{
|
|
1365
|
+
var divBox = _instance.element,
|
|
1366
|
+
invertRect = getInvertRect(divBox),
|
|
1367
|
+
space = 0, invertPos = 0, invertSpace = 0, fits = (rect.width <= winSize.width),
|
|
1368
|
+
resize = function ()
|
|
1369
|
+
{
|
|
1370
|
+
if (fits || !_instance.autoResizeFit) return;
|
|
1371
|
+
|
|
1372
|
+
const cs = window.getComputedStyle(divBox),
|
|
1373
|
+
boxSizing = (cs.boxSizing || cs.getPropertyValue('box-sizing') || 'content-box').toLowerCase();
|
|
1374
|
+
|
|
1375
|
+
let baseSpace;
|
|
1376
|
+
if (_instance.resizeToMaxWidth)
|
|
1377
|
+
{
|
|
1378
|
+
baseSpace = winSize.width;
|
|
1379
|
+
divBox.style.left = $lib.unit(0);
|
|
1380
|
+
}
|
|
1381
|
+
else
|
|
1382
|
+
{
|
|
1383
|
+
baseSpace = (_invertedX) ? invertSpace : space;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
let finalWidth = baseSpace;
|
|
1387
|
+
|
|
1388
|
+
if (boxSizing === 'content-box') // subtract border+padding because style.width sets the content box
|
|
1389
|
+
{
|
|
1390
|
+
const devSize = $lib.borderAndPadding(divBox);
|
|
1391
|
+
finalWidth = baseSpace - devSize.width;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
divBox.style.width = (finalWidth > 0) ? $lib.unit(finalWidth) : '0px';
|
|
1395
|
+
_styleCache.width = null;
|
|
1396
|
+
_resizedX = true;
|
|
1397
|
+
};
|
|
1398
|
+
|
|
1399
|
+
// clear position and margin
|
|
1400
|
+
$lib.updateStyle(divBox.style, 'left:auto;right:auto;margin-left:0px !important;margin-right:0px !important;');
|
|
1401
|
+
|
|
1402
|
+
if ((_instance.autoPosition != _autoPositionOption.EXPAND || !_instance.autoInvertFit)
|
|
1403
|
+
|| (_instance.expandDirection != _expandDirectionOption.RIGHT && _instance.expandDirection != _expandDirectionOption.LEFT))
|
|
1404
|
+
{
|
|
1405
|
+
if (rect.left < 0)
|
|
1406
|
+
divBox.style.left = $lib.unit(0);
|
|
1407
|
+
else
|
|
1408
|
+
divBox.style.right = $lib.unit(0);
|
|
1409
|
+
|
|
1410
|
+
return resize();
|
|
1411
|
+
}
|
|
1412
|
+
else if (_instance.expandDirection == _expandDirectionOption.RIGHT)
|
|
1413
|
+
{
|
|
1414
|
+
if (rect.left < 0)
|
|
1415
|
+
{
|
|
1416
|
+
divBox.style.left = $lib.unit(0);
|
|
1417
|
+
return resize();
|
|
1418
|
+
}
|
|
1419
|
+
else if ((rect.left - _invertMarginX) > winSize.width)
|
|
1420
|
+
{
|
|
1421
|
+
divBox.style.right = $lib.unit(0);
|
|
1422
|
+
return resize();
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
space = winSize.width - rect.left;
|
|
1426
|
+
invertPos = invertRect.left - (invertRect.width + _invertMarginX);
|
|
1427
|
+
invertSpace = (invertPos < 0) ? invertRect.right - invertRect.width - _invertMarginX : invertRect.width;
|
|
1428
|
+
}
|
|
1429
|
+
else
|
|
1430
|
+
{
|
|
1431
|
+
if (rect.right > winSize.width)
|
|
1432
|
+
{
|
|
1433
|
+
divBox.style.right = $lib.unit(0);
|
|
1434
|
+
return resize();
|
|
1435
|
+
}
|
|
1436
|
+
else if ((rect.right + _invertMarginX) < 0)
|
|
1437
|
+
{
|
|
1438
|
+
divBox.style.left = $lib.unit(0);
|
|
1439
|
+
return resize();
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
space = (winSize.width < rect.right) ? winSize.width : rect.right;
|
|
1443
|
+
invertPos = invertRect.right + _invertMarginX;
|
|
1444
|
+
invertSpace = (invertPos < 0) ? 0 : winSize.width - invertPos;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
if (rect.width <= invertSpace)
|
|
1448
|
+
{
|
|
1449
|
+
// box fits inverted
|
|
1450
|
+
$lib.addClass(divBox, _instance.cssClassHorizontalInverted || _classOption.HORIZONTALINVERTED);
|
|
1451
|
+
divBox.style.left = $lib.unit(invertPos);
|
|
1452
|
+
_invertedX = true;
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
else
|
|
1456
|
+
{
|
|
1457
|
+
// when invert space is larger, utilize that space
|
|
1458
|
+
if (space >= invertSpace)
|
|
1459
|
+
{
|
|
1460
|
+
if (fits && rect.left >= 0)
|
|
1461
|
+
divBox.style.right = $lib.unit(0);
|
|
1462
|
+
else
|
|
1463
|
+
divBox.style.left = (rect.left >= 0) ? $lib.unit(rect.left) : $lib.unit(0);
|
|
1464
|
+
}
|
|
1465
|
+
else
|
|
1466
|
+
divBox.style.left = (invertPos >= 0) ? $lib.unit(invertPos) : $lib.unit(0);
|
|
1467
|
+
|
|
1468
|
+
if (invertSpace > space)
|
|
1469
|
+
{
|
|
1470
|
+
$lib.addClass(divBox, _instance.cssClassHorizontalInverted || _classOption.HORIZONTALINVERTED);
|
|
1471
|
+
_invertedX = true;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
if (!_instance.resizeToMaxWidth)
|
|
1475
|
+
fits = (space >= invertSpace) ? (rect.width <= space) : (rect.width <= invertSpace);
|
|
1476
|
+
|
|
1477
|
+
return resize();
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
function setExpanderOffset(divBox, vertical)
|
|
1482
|
+
{
|
|
1483
|
+
if (!_instance.expander) return;
|
|
1484
|
+
|
|
1485
|
+
const boxRect = divBox.getBoundingClientRect(),
|
|
1486
|
+
expRect = _instance.expander.getBoundingClientRect(),
|
|
1487
|
+
expCenterX = expRect.left + expRect.width / 2,
|
|
1488
|
+
expCenterY = expRect.top + expRect.height / 2;
|
|
1489
|
+
|
|
1490
|
+
if (vertical)
|
|
1491
|
+
{
|
|
1492
|
+
if (divBox.classList.contains('align-left'))
|
|
1493
|
+
{
|
|
1494
|
+
const offsetX = Math.floor(expCenterX - boxRect.left);
|
|
1495
|
+
divBox.style.setProperty('--expander-offset', offsetX + 'px');
|
|
1496
|
+
} else if (divBox.classList.contains('align-right'))
|
|
1497
|
+
{
|
|
1498
|
+
const offsetX = Math.floor(boxRect.right - expCenterX);
|
|
1499
|
+
divBox.style.setProperty('--expander-offset', offsetX + 'px');
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
else
|
|
1503
|
+
{
|
|
1504
|
+
if (divBox.classList.contains('align-top'))
|
|
1505
|
+
{
|
|
1506
|
+
const offsetY = Math.floor(expCenterY - boxRect.top);
|
|
1507
|
+
divBox.style.setProperty('--expander-offset', offsetY + 'px');
|
|
1508
|
+
} else if (divBox.classList.contains('align-bottom'))
|
|
1509
|
+
{
|
|
1510
|
+
const offsetY = Math.floor(boxRect.bottom - expCenterY);
|
|
1511
|
+
divBox.style.setProperty('--expander-offset', offsetY + 'px');
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
function getInvertRect(divBox, vertical)
|
|
1517
|
+
{
|
|
1518
|
+
var cssClass = (vertical) ? _instance.cssClassVerticalInverted || _classOption.VERTICALINVERTED : _instance.cssClassHorizontalInverted || _classOption.HORIZONTALINVERTED;
|
|
1519
|
+
var rect;
|
|
1520
|
+
|
|
1521
|
+
if (!$lib.hasClass(divBox, cssClass))
|
|
1522
|
+
{
|
|
1523
|
+
$lib.addClass(divBox, cssClass);
|
|
1524
|
+
rect = $lib.getPos(divBox, null, true);
|
|
1525
|
+
$lib.removeClass(divBox, cssClass);
|
|
1526
|
+
}
|
|
1527
|
+
else
|
|
1528
|
+
rect = $lib.getPos(divBox, null, true);
|
|
1529
|
+
|
|
1530
|
+
return rect;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
function bindGlobalEvents()
|
|
1534
|
+
{
|
|
1535
|
+
$lib.on(window, 'resize', positionDelayed, null, _instance);
|
|
1536
|
+
$lib.on(window, 'scroll', positionDelayed, null, _instance);
|
|
1537
|
+
$lib.on(_instance.element, 'pointerdown pointerup', function () { _allowHide = false; }, null, _instance);
|
|
1538
|
+
$lib.on(_instance.element, 'pointercancel', function () { _allowHide = true; }, null, _instance); // touch scroll/long-press ends without pointerup
|
|
1539
|
+
$lib.on(_instance.element, 'keydown', function (e)
|
|
1540
|
+
{
|
|
1541
|
+
const doc = _instance.element.ownerDocument || document,
|
|
1542
|
+
activeElement = doc.activeElement;
|
|
1543
|
+
|
|
1544
|
+
if (e.defaultPrevented) // canceled by other handler, do not process enter key submission
|
|
1545
|
+
return;
|
|
1546
|
+
|
|
1547
|
+
if (_instance.enterKeySubmitter && e.key?.toLowerCase() == 'enter' && !e.shiftKey && activeElement && _instance.element.contains(activeElement))
|
|
1548
|
+
{
|
|
1549
|
+
let element = _instance.enterKeySubmitter;
|
|
1550
|
+
|
|
1551
|
+
element = (typeof element === 'string') ? $lib('#' + element) : element;
|
|
1552
|
+
$lib.fireEvent(element, 'click', true, true);
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
function bindOutsideClickHandler()
|
|
1558
|
+
{
|
|
1559
|
+
if (_instance.hideOnOutsideClick && !$lib.has(document, 'pointerup', checkHide))
|
|
1560
|
+
$lib.on(document, 'pointerup', checkHide);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
function removeOutsideClickHandler()
|
|
1564
|
+
{
|
|
1565
|
+
$lib.off(document, 'pointerup', checkHide);
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
function positionDelayed()
|
|
1569
|
+
{
|
|
1570
|
+
clearTimeout(_timerId);
|
|
1571
|
+
_timerId = setTimeout(position, 0);
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
function dispose()
|
|
1575
|
+
{
|
|
1576
|
+
$lib.off(window, 'resize', positionDelayed);
|
|
1577
|
+
$lib.off(window, 'scroll', positionDelayed);
|
|
1578
|
+
$lib.off(document, 'pointermove', trackPointer);
|
|
1579
|
+
$lib.off(document, 'pointerup', stopPointerTracking);
|
|
1580
|
+
|
|
1581
|
+
if (_resizeObserver)
|
|
1582
|
+
{
|
|
1583
|
+
_resizeObserver.disconnect();
|
|
1584
|
+
_resizeObserver = null;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
clearTimers();
|
|
1588
|
+
removeOutsideClickHandler();
|
|
1589
|
+
|
|
1590
|
+
if (_draggable)
|
|
1591
|
+
_draggable.disable();
|
|
1592
|
+
|
|
1593
|
+
_draggable = null;
|
|
1594
|
+
_pointerCoordinates = null;
|
|
1595
|
+
_styleCache = {};
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* @see {@link componyx.UI.base.methods}
|
|
1601
|
+
*/
|
|
1602
|
+
componyx.UI.Box.prototype = Object.create($base.methods);
|
|
1603
|
+
componyx.UI.Box.prototype.constructor = componyx.UI.Box;
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* AutoPositionOption
|
|
1607
|
+
* @readonly
|
|
1608
|
+
* @enum {number}
|
|
1609
|
+
*/
|
|
1610
|
+
componyx.UI.Box.AutoPositionOption =
|
|
1611
|
+
{
|
|
1612
|
+
NONE: 0,
|
|
1613
|
+
TOPLEFT: 1,
|
|
1614
|
+
TOPCENTER: 2,
|
|
1615
|
+
TOPRIGHT: 3,
|
|
1616
|
+
LEFT: 4,
|
|
1617
|
+
CENTER: 5,
|
|
1618
|
+
RIGHT: 6,
|
|
1619
|
+
BOTTOMLEFT: 7,
|
|
1620
|
+
BOTTOMCENTER: 8,
|
|
1621
|
+
BOTTOMRIGHT: 9,
|
|
1622
|
+
POINTER: 10,
|
|
1623
|
+
EXPAND: 11
|
|
1624
|
+
};
|
|
1625
|
+
|
|
1626
|
+
/**
|
|
1627
|
+
* ExpandDirectionOption
|
|
1628
|
+
* @readonly
|
|
1629
|
+
* @enum {number}
|
|
1630
|
+
*/
|
|
1631
|
+
componyx.UI.Box.ExpandDirectionOption =
|
|
1632
|
+
{
|
|
1633
|
+
DOWN: 0,
|
|
1634
|
+
RIGHT: 1,
|
|
1635
|
+
UP: 2,
|
|
1636
|
+
LEFT: 3,
|
|
1637
|
+
|
|
1638
|
+
getName: function (value) { return $base.static.getKeyByValue(this, value).toLowerCase(); }
|
|
1639
|
+
};
|
|
1640
|
+
|
|
1641
|
+
/**
|
|
1642
|
+
* AlignXOption
|
|
1643
|
+
* @readonly
|
|
1644
|
+
* @enum {number}
|
|
1645
|
+
*/
|
|
1646
|
+
componyx.UI.Box.AlignXOption =
|
|
1647
|
+
{
|
|
1648
|
+
LEFT: 0,
|
|
1649
|
+
CENTER: 1,
|
|
1650
|
+
RIGHT: 2,
|
|
1651
|
+
|
|
1652
|
+
getName: function (value) { return $base.static.getKeyByValue(this, value).toLowerCase(); }
|
|
1653
|
+
};
|
|
1654
|
+
|
|
1655
|
+
/**
|
|
1656
|
+
* AlignYOption
|
|
1657
|
+
* @readonly
|
|
1658
|
+
* @enum {number}
|
|
1659
|
+
*/
|
|
1660
|
+
componyx.UI.Box.AlignYOption =
|
|
1661
|
+
{
|
|
1662
|
+
TOP: 0,
|
|
1663
|
+
CENTER: 1,
|
|
1664
|
+
BOTTOM: 2,
|
|
1665
|
+
|
|
1666
|
+
getName: function (value) { return $base.static.getKeyByValue(this, value).toLowerCase(); }
|
|
1667
|
+
};
|
|
1668
|
+
|
|
1669
|
+
/**
|
|
1670
|
+
* AnimationTypeOption
|
|
1671
|
+
* @readonly
|
|
1672
|
+
* @enum {number}
|
|
1673
|
+
*/
|
|
1674
|
+
componyx.UI.Box.AnimationTypeOption =
|
|
1675
|
+
{
|
|
1676
|
+
NONE: 0,
|
|
1677
|
+
SLIDE: 1,
|
|
1678
|
+
REVEAL: 2,
|
|
1679
|
+
CSS: 3
|
|
1680
|
+
};
|
|
1681
|
+
})(window);
|
|
1682
|
+
|
|
1683
|
+
const Box = componyx.UI.Box;
|
|
1684
|
+
|
|
1685
|
+
export { Box };
|