bm-core-ui 2.7.0
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/CHANGELOG.md +1624 -0
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/build/@types/index.d.ts +14078 -0
- package/build/BMCodeEditor/BMCodeEditor.js +707 -0
- package/build/BMCollectionView/BMCollectionView.js +5861 -0
- package/build/BMCollectionView/BMCollectionViewCell.js +688 -0
- package/build/BMCollectionView/BMCollectionViewFlowLayout.js +4467 -0
- package/build/BMCollectionView/BMCollectionViewLayout.js +830 -0
- package/build/BMCollectionView/BMCollectionViewLayoutAttributes.js +673 -0
- package/build/BMCollectionView/BMCollectionViewMasonryLayout.js +491 -0
- package/build/BMCollectionView/BMCollectionViewStackLayout.js +634 -0
- package/build/BMCollectionView/BMCollectionViewTileLayout.js +1121 -0
- package/build/BMCoreUI.css +2833 -0
- package/build/BMView/BMAttributedLabelView.js +310 -0
- package/build/BMView/BMLayoutConstraint_v2.5.js +1813 -0
- package/build/BMView/BMLayoutGuide.js +192 -0
- package/build/BMView/BMLayoutSizeClass.js +466 -0
- package/build/BMView/BMMenu.js +574 -0
- package/build/BMView/BMScrollView.js +247 -0
- package/build/BMView/BMTextField.js +512 -0
- package/build/BMView/BMTextFieldDelegate.js +71 -0
- package/build/BMView/BMView_v2.5.js +3572 -0
- package/build/BMView/BMViewport.js +221 -0
- package/build/BMViewLayoutEditor/BMLayoutEditor.js +6117 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorConstraintSettings.js +417 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorDelegate.js +59 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingCells.js +1653 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettings.js +1480 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsComplexCells.js +431 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorSettingsDelegate.js +46 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorVariablesController.js +460 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorViewGroupSettings.js +293 -0
- package/build/BMViewLayoutEditor/BMLayoutEditorViewSettings.js +382 -0
- package/build/BMViewLayoutEditor/BMLayoutVariableProvider.js +202 -0
- package/build/BMWindow/BMConfirmationPopup.js +477 -0
- package/build/BMWindow/BMKeyboardShortcut.js +151 -0
- package/build/BMWindow/BMPopover/BMPopover.js +492 -0
- package/build/BMWindow/BMToolWindow.js +71 -0
- package/build/BMWindow/BMWindow.js +2000 -0
- package/build/Core/BMAnimationContext.js +1181 -0
- package/build/Core/BMColor.js +991 -0
- package/build/Core/BMCoreUI.js +470 -0
- package/build/Core/BMFunctionCollection.js +110 -0
- package/build/Core/BMIndexPath.js +165 -0
- package/build/Core/BMInset.js +138 -0
- package/build/Core/BMKeyPath.js +100 -0
- package/build/Core/BMPoint.js +291 -0
- package/build/Core/BMRect.js +556 -0
- package/build/Core/BMSize.js +137 -0
- package/build/iScroll/LICENSE +22 -0
- package/build/iScroll/iscroll-probe.js +2154 -0
- package/build/images/AlignBottom.png +0 -0
- package/build/images/AlignCenterX.png +0 -0
- package/build/images/AlignCenterY.png +0 -0
- package/build/images/AlignLeading.png +0 -0
- package/build/images/AlignTop.png +0 -0
- package/build/images/AlignTrailing.png +0 -0
- package/build/images/AllConstraints.png +0 -0
- package/build/images/BottomConstraint.png +0 -0
- package/build/images/CenterXConstraint.png +0 -0
- package/build/images/CenterYConstraint.png +0 -0
- package/build/images/CoreUI2.png +0 -0
- package/build/images/CoreUI2@2x.png +0 -0
- package/build/images/Desktop.png +0 -0
- package/build/images/DesktopMini.png +0 -0
- package/build/images/EqualHeight.png +0 -0
- package/build/images/EqualHorizontalSpacing.png +0 -0
- package/build/images/EqualHorizontalSpacingInSuperview.png +0 -0
- package/build/images/EqualVerticalSpacing.png +0 -0
- package/build/images/EqualVerticalSpacingInSuperview.png +0 -0
- package/build/images/EqualWidth.png +0 -0
- package/build/images/HeightConstraint.png +0 -0
- package/build/images/InactiveConstraints.png +0 -0
- package/build/images/Layout.png +0 -0
- package/build/images/LayoutVariables.png +0 -0
- package/build/images/LeftConstraint.png +0 -0
- package/build/images/OwnConstraints.png +0 -0
- package/build/images/Phone.png +0 -0
- package/build/images/PhoneLandscape.png +0 -0
- package/build/images/PhoneLandscapeMini.png +0 -0
- package/build/images/PhoneMini.png +0 -0
- package/build/images/PhonePortrait.png +0 -0
- package/build/images/PhonePortraitMini.png +0 -0
- package/build/images/Properties.png +0 -0
- package/build/images/RightConstraint.png +0 -0
- package/build/images/SubviewConstraints.png +0 -0
- package/build/images/Tablet.png +0 -0
- package/build/images/TabletLandscape.png +0 -0
- package/build/images/TabletLandscapeMini.png +0 -0
- package/build/images/TabletMini.png +0 -0
- package/build/images/TabletPortrait.png +0 -0
- package/build/images/TabletPortraitMini.png +0 -0
- package/build/images/TopConstraint.png +0 -0
- package/build/images/WidthConstraint.png +0 -0
- package/build/index.js +40 -0
- package/lib/@types/BMCoreUI.min.d.ts +14078 -0
- package/lib/BMCoreUI.min.js +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// @type interface BMLayoutVariation
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The specification of an object that represents a variation of a value within a CoreUI layout.
|
|
5
|
+
*/
|
|
6
|
+
function BMLayoutVariation() {} // <constructor>
|
|
7
|
+
|
|
8
|
+
BMLayoutVariation.prototype = {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The name of the item to which this variation applies.
|
|
12
|
+
*/
|
|
13
|
+
get name() { // <String>
|
|
14
|
+
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The size class for which this variation is active.
|
|
19
|
+
*/
|
|
20
|
+
get sizeClass() { // <BMLayoutSizeClass>
|
|
21
|
+
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The value of this variation.
|
|
26
|
+
*/
|
|
27
|
+
get value() { // <any>
|
|
28
|
+
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// @endtype
|
|
33
|
+
|
|
34
|
+
// @type interface BMLayoutVariableVariation extends BMLayoutVariation
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The specification of an object that represents a variation of a layout variable within a CoreUI layout.
|
|
38
|
+
*/
|
|
39
|
+
function BMLayoutVariableVariation() {} // <constructor>
|
|
40
|
+
|
|
41
|
+
BMLayoutVariableVariation.prototype = {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The value of this variation.
|
|
45
|
+
*/
|
|
46
|
+
get value() { // <Number>
|
|
47
|
+
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// @endtype
|
|
52
|
+
|
|
53
|
+
// @type interface BMLayoutVariableProvider
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The specification for a `BMLayoutVariableProvider` object, which is used to provide information to the layout editor regarding which
|
|
57
|
+
* of the currently defined layout variables are applicable to the current context.
|
|
58
|
+
*
|
|
59
|
+
* The `BMView` class itself implements this interface and can be used whenever any specific behaviour is not required for adding, modifying
|
|
60
|
+
* or removing layout variables.
|
|
61
|
+
*
|
|
62
|
+
* All of the methods defined in this protocol are required; omitting any method will lead to a runtime error when the layout editor
|
|
63
|
+
* attempts to invoke it on the provider object.
|
|
64
|
+
*/
|
|
65
|
+
function BMLayoutVariableProvider() {} // <constructor>
|
|
66
|
+
|
|
67
|
+
BMLayoutVariableProvider.prototype = {
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Invoked by the layout editor to determine if layout variables are available.
|
|
71
|
+
* If layout variables are unavailable, the layout editor will not allow the creation of layout variables
|
|
72
|
+
* and display a message to the user indicating this.
|
|
73
|
+
* @return <Boolean> `YES` if layout variables are available, `NO` otherwise.
|
|
74
|
+
*/
|
|
75
|
+
canUseLayoutVariables() {
|
|
76
|
+
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Invoked by the layout editor if layout variables are unavailable.
|
|
81
|
+
* This method should return a string that represents the error message that will be displayed
|
|
82
|
+
* to the use if layout variables are unavailable.
|
|
83
|
+
* @return <String> A message to display to the user.
|
|
84
|
+
*/
|
|
85
|
+
unavailableLayoutVariablesUserLabel() {
|
|
86
|
+
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Invoked by the layout editor during its initialization to cause this layout variable provider
|
|
91
|
+
* to prepare the layout variables that should be available in the current context.
|
|
92
|
+
*
|
|
93
|
+
* The layout editor will invoke this method only once during initialization and before any other method is
|
|
94
|
+
* invoked on this layout variable provider.
|
|
95
|
+
*/
|
|
96
|
+
prepareLayoutVariables() {
|
|
97
|
+
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* This getter must return an object that represent the currently defined layout variables.
|
|
102
|
+
* The property names represent the layout variable names and their values represent each variable's value.
|
|
103
|
+
* The layout editor will not modify the object returned by this getter and it must also not be modified by any
|
|
104
|
+
* external source throughout its lifetime.
|
|
105
|
+
*
|
|
106
|
+
* The layout editor may invoke this method several times throughout its lifecycle, typically whenever
|
|
107
|
+
* the layout variables popup is opened or whenever autocomplete suggestions should be displayed while
|
|
108
|
+
* the user is editing a constraint's constant.
|
|
109
|
+
*
|
|
110
|
+
* The layout variables returned by this method must also be registered with CoreUI.
|
|
111
|
+
*/
|
|
112
|
+
get layoutVariables() { // <Object<String, Number>>
|
|
113
|
+
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Invoked by the layout editor to obtain the variations defined for the given layout variables.
|
|
118
|
+
* Layout variable providers should typically obtain the variations from CoreUI as layout variables with
|
|
119
|
+
* the same name must have the same variations in all contexts in which they apply.
|
|
120
|
+
* @param named <String> The name of the layout variable.
|
|
121
|
+
* @return <[BMLayoutVariableVariation]> An array of variations for the given layout variable.
|
|
122
|
+
*/
|
|
123
|
+
variationsForLayoutVariableNamed(named) {
|
|
124
|
+
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* This method will be invoked by the layout editor when the user creates a new layout variable
|
|
129
|
+
* with the given value.
|
|
130
|
+
* This method will also be invoked whenever the default value of a layout variable changes.
|
|
131
|
+
*
|
|
132
|
+
* The layout variable provider must register this layout variable with CoreUI.
|
|
133
|
+
* @param named <String> The name to use for this layout variable.
|
|
134
|
+
* {
|
|
135
|
+
* @param withValue <Number> The default value to use for this layout variable, when there are no
|
|
136
|
+
* active size classes variations.
|
|
137
|
+
* }
|
|
138
|
+
*/
|
|
139
|
+
registerLayoutVariableNamed(named, {withValue: value}) {
|
|
140
|
+
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* This method will be invoked to rename an existing layout variable.
|
|
145
|
+
* @param named <String> The layout variable's current name.
|
|
146
|
+
* {
|
|
147
|
+
* @param toName <String> The new name to use for the layout variable.
|
|
148
|
+
* }
|
|
149
|
+
*/
|
|
150
|
+
renameLayoutVariableNamed(named, {toName: newName}) {
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* This method will be invoked by the layout editor when the user deletes a previously created layout variable.
|
|
155
|
+
*
|
|
156
|
+
* The layout variable provider must also unregister this layout variable from CoreUI.
|
|
157
|
+
* @param named <String> The name of the layout variable to remove.
|
|
158
|
+
*/
|
|
159
|
+
unregisterLayoutVariableNamed(named) {
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Invoked by the layout editor when the user sets a variation for the given layout variable
|
|
164
|
+
* when the given size class is active.
|
|
165
|
+
* If a variation for the given layout variable already exists for the given size class,
|
|
166
|
+
* its value should be updated to the specified value.
|
|
167
|
+
*
|
|
168
|
+
* The layout variable provider must also register this variation with CoreUI.
|
|
169
|
+
* @param value <Number> The value for the given layout variable when the given size class is active.
|
|
170
|
+
* {
|
|
171
|
+
* @param named <String> The name of the layout variable.
|
|
172
|
+
* @param inSizeClass <BMLayoutSizeClass> The size class for which this variation will be active.
|
|
173
|
+
* }
|
|
174
|
+
*/
|
|
175
|
+
setLayoutVariableValue(value, {named: name, inSizeClass: sizeClass}) {
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Invoked by the layout editor when the user removes a variation for the given
|
|
180
|
+
* layout variable for the given size class.
|
|
181
|
+
*
|
|
182
|
+
* The layout variable provider must also unregister this variation from CoreUI.
|
|
183
|
+
* @param name <String> The name of the layout variable.
|
|
184
|
+
* {
|
|
185
|
+
* @param inSizeClass <BMLayoutSizeClass> The size class from which to remove this variation.
|
|
186
|
+
* }
|
|
187
|
+
*/
|
|
188
|
+
removeVariationForLayoutVariableNamed(name, {inSizeClass: sizeClass}) {
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Invoked by the layout editor when editing finishes and this layout variable provider should persist
|
|
193
|
+
* any changes that have occurred to the layout variables. This method may be invoked several times while
|
|
194
|
+
* the layout editor is open.
|
|
195
|
+
*/
|
|
196
|
+
persistLayoutVariables() {
|
|
197
|
+
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// @endtype
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { BMRectMake } from "../Core/BMRect";
|
|
4
|
+
import { BMExtend, NO, YES } from "../Core/BMCoreUI";
|
|
5
|
+
import { BMWindow } from "./BMWindow";
|
|
6
|
+
import { BMView } from "../BMView/BMView_v2.5";
|
|
7
|
+
import { BMLayoutAttribute } from "../BMView/BMLayoutConstraint_v2.5";
|
|
8
|
+
import { BMKeyboardShortcut } from "./BMKeyboardShortcut";
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// @type BMConfirmationPopupResult
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A series of constants describing which action the user has taken in reponse
|
|
16
|
+
* to a confirmation popup.
|
|
17
|
+
*/
|
|
18
|
+
export const BMConfirmationPopupResult = Object.freeze({ // <enum>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Indicates that the user hasn't yet taken a decision.
|
|
22
|
+
*/
|
|
23
|
+
Undecided: {}, // <enum>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Indicates that the user has selected the "Cancel" button or closed the confirmation popup.
|
|
27
|
+
*/
|
|
28
|
+
Cancelled: {}, // <enum>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Indicates that the user has selected the negative action.
|
|
32
|
+
*/
|
|
33
|
+
Declined: {}, // <enum>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Indicates that the user has selected the positive action.
|
|
37
|
+
*/
|
|
38
|
+
Confirmed: {} // <enum>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// @endtype
|
|
44
|
+
|
|
45
|
+
// @type BMAlertPopup extends BMWindow
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A sublcass of `BMAlertPopup` that is specialized for displaying an alert popup with a title, a text message and
|
|
49
|
+
* a confirmation button.
|
|
50
|
+
*
|
|
51
|
+
* To create a alert popup, use the static `alertPopupWithTitle(_, {})` method.
|
|
52
|
+
*
|
|
53
|
+
* You can display your confirmation popup using the usual `bringToFrontAnimated(_)` method, but for convenience you can also
|
|
54
|
+
* use the `confirm()` method that returns a promise which resolves when the user dismisses the alert.
|
|
55
|
+
*/
|
|
56
|
+
export function BMAlertPopup() {} // <constructor>
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
BMAlertPopup.prototype = BMExtend(Object.create(BMWindow.prototype), {
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Represents the action that the user has taken.
|
|
63
|
+
*/
|
|
64
|
+
_result: BMConfirmationPopupResult.Undecided, // <BMConfirmationPopupResult>
|
|
65
|
+
|
|
66
|
+
get result() {
|
|
67
|
+
return this._result;
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A promise that resolves when the user takes a decision in response to this
|
|
72
|
+
* popup. The value returned when the promise resolves will never be `.Undecided`.
|
|
73
|
+
*/
|
|
74
|
+
_resolution: undefined, // <Promise<BMConfirmationPopupResult>>
|
|
75
|
+
|
|
76
|
+
get resolution() {
|
|
77
|
+
return this._resolution;
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Used to resolve the `resolution` promise.
|
|
82
|
+
*/
|
|
83
|
+
_resolve: undefined, // <void ^ (BMConfirmationPopupResult)>
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The popup's title. Ideally this should be used to provide a succint description
|
|
87
|
+
* of what the user confirms.
|
|
88
|
+
*/
|
|
89
|
+
_title: undefined, // <String>
|
|
90
|
+
|
|
91
|
+
get title() {
|
|
92
|
+
return this._title;
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
set title(title) {
|
|
96
|
+
if (title == this._title) return;
|
|
97
|
+
|
|
98
|
+
this._title = title;
|
|
99
|
+
|
|
100
|
+
if (this._titleView) {
|
|
101
|
+
this._titleView.node.innerText = title;
|
|
102
|
+
this._titleView.invalidateIntrinsicSize();
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The popup's body text. Ideally this should be used to provide additional information about
|
|
108
|
+
* the action that is about to occur.
|
|
109
|
+
*/
|
|
110
|
+
_text: undefined, // <String>
|
|
111
|
+
|
|
112
|
+
get text() {
|
|
113
|
+
return this._text;
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
set text(text) {
|
|
117
|
+
if (text == this._text) return;
|
|
118
|
+
|
|
119
|
+
this._text = text;
|
|
120
|
+
|
|
121
|
+
if (this._textView) {
|
|
122
|
+
this._textView.node.innerText = text;
|
|
123
|
+
this._textView.invalidateIntrinsicSize();
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The popup's body text. Ideally this should be used to provide additional information about
|
|
130
|
+
* the action that is about to occur. Unlike `text`, setting this property will not convert HTML tags to text.
|
|
131
|
+
*/
|
|
132
|
+
get HTML() { // <String>
|
|
133
|
+
return this._text;
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
set HTML(text) {
|
|
137
|
+
if (text == this._text) return;
|
|
138
|
+
|
|
139
|
+
this._text = text;
|
|
140
|
+
|
|
141
|
+
if (this._textView) {
|
|
142
|
+
this._textView.node.innerHTML = text;
|
|
143
|
+
this._textView.invalidateIntrinsicSize();
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The text to use for the alert's button.
|
|
149
|
+
*/
|
|
150
|
+
_positiveActionText: undefined, // <String>
|
|
151
|
+
|
|
152
|
+
get positiveActionText() {
|
|
153
|
+
return this._positiveActionText;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
set positiveActionText(text) {
|
|
157
|
+
if (text == this._positiveActionText) return;
|
|
158
|
+
|
|
159
|
+
this._positiveActionText = text;
|
|
160
|
+
|
|
161
|
+
if (this._positiveActionButton) {
|
|
162
|
+
this._positiveActionButton.node.innerText = text;
|
|
163
|
+
this._positiveActionButton.invalidateIntrinsicSize();
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
// @override - BMWindow
|
|
168
|
+
get frameSizePriority() {
|
|
169
|
+
return 1;
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// @override - BMWindow
|
|
173
|
+
get frameHorizontalPositionLayoutAttribute() {
|
|
174
|
+
return BMLayoutAttribute.CenterX;
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
// @override - BMWindow
|
|
178
|
+
get frameVerticalPositionLayoutAttribute() {
|
|
179
|
+
return BMLayoutAttribute.CenterY;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Designated initializer. Initializes this alert popup with the given labels.
|
|
184
|
+
* @param title <String> The popup's title.
|
|
185
|
+
* {
|
|
186
|
+
* @param text <String> The popup's body text.
|
|
187
|
+
* @param actionText <String, nullable> Defaults to `OK`. The text to display on the action button.
|
|
188
|
+
* }
|
|
189
|
+
* @return <BMAlertPopup> This alert popup.
|
|
190
|
+
*/
|
|
191
|
+
initWithTitle(title, {text, actionText = 'OK'}) {
|
|
192
|
+
const frame = BMRectMake(0, 0, 0, 0);
|
|
193
|
+
|
|
194
|
+
BMWindow.prototype.initWithFrame.call(this, frame);
|
|
195
|
+
|
|
196
|
+
this.contentView.contentNode.classList.add('BMWindowBackground');
|
|
197
|
+
|
|
198
|
+
this._resolution = new Promise(resolve => {
|
|
199
|
+
this._resolve = resolve;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
this._title = title;
|
|
203
|
+
this._text = text;
|
|
204
|
+
this._positiveActionText = actionText;
|
|
205
|
+
|
|
206
|
+
// Title View
|
|
207
|
+
|
|
208
|
+
this._titleView = BMView.view();
|
|
209
|
+
this._titleView.supportsAutomaticIntrinsicSize = YES;
|
|
210
|
+
this._titleView.node.classList.add('BMTitle');
|
|
211
|
+
this._titleView.node.innerText = title;
|
|
212
|
+
|
|
213
|
+
this.contentView.addSubview(this._titleView);
|
|
214
|
+
this._titleView.leading.equalTo(this.contentView.leading, {plus: 32}).isActive = YES;
|
|
215
|
+
this._titleView.top.equalTo(this.contentView.top, {plus: 32}).isActive = YES;
|
|
216
|
+
this._titleView.trailing.lessThanOrEqualTo(this.contentView.trailing, {plus: -32}).isActive = YES;
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
// Body
|
|
220
|
+
|
|
221
|
+
this._textView = BMView.view();
|
|
222
|
+
this._textView.supportsAutomaticIntrinsicSize = YES;
|
|
223
|
+
this._textView.node.classList.add('BMLabel');
|
|
224
|
+
this._textView.node.innerText = text;
|
|
225
|
+
|
|
226
|
+
this.contentView.addSubview(this._textView);
|
|
227
|
+
this._textView.leading.equalTo(this._titleView.leading).isActive = YES;
|
|
228
|
+
this._textView.top.equalTo(this._titleView.bottom, {plus: 32}).isActive = YES;
|
|
229
|
+
this._textView.trailing.lessThanOrEqualTo(this.contentView.trailing, {plus: -32}).isActive = YES;
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
// Positive button
|
|
233
|
+
|
|
234
|
+
this._positiveActionButton = BMView.view();
|
|
235
|
+
this._positiveActionButton.supportsAutomaticIntrinsicSize = YES;
|
|
236
|
+
this._positiveActionButton.node.classList.add('BMButton');
|
|
237
|
+
this._positiveActionButton.node.innerText = actionText;
|
|
238
|
+
|
|
239
|
+
this.contentView.addSubview(this._positiveActionButton);
|
|
240
|
+
this._positiveActionButton.trailing.equalTo(this.contentView.trailing, {plus: -32}).isActive = YES;
|
|
241
|
+
this._positiveActionButton.bottom.equalTo(this.contentView.bottom, {plus: -32}).isActive = YES;
|
|
242
|
+
this._positiveActionButton.top.equalTo(this._textView.bottom, {plus: 64}).isActive = YES;
|
|
243
|
+
|
|
244
|
+
this._positiveActionButton.node.addEventListener('click', event => this._confirm());
|
|
245
|
+
|
|
246
|
+
this.registerKeyboardShortcut(BMKeyboardShortcut.keyboardShortcutWithKeyCode('Enter', {target: this, action: '_confirm'}));
|
|
247
|
+
|
|
248
|
+
const escapeKeyboardShortcut = BMKeyboardShortcut.keyboardShortcutWithKeyCode('Escape', {target: this, action: '_escape'});
|
|
249
|
+
escapeKeyboardShortcut.preventsDefault = YES;
|
|
250
|
+
this.registerKeyboardShortcut(escapeKeyboardShortcut);
|
|
251
|
+
|
|
252
|
+
return this;
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* Confirms the action, then dismisses this confirmation popup.
|
|
256
|
+
* If the result is already settled, this method will have no effect.
|
|
257
|
+
*/
|
|
258
|
+
_escape() {
|
|
259
|
+
this._confirm();
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Confirms the action, then dismisses this confirmation popup.
|
|
264
|
+
* If the result is already settled, this method will have no effect.
|
|
265
|
+
*/
|
|
266
|
+
_confirm() {
|
|
267
|
+
if (this._result == BMConfirmationPopupResult.Undecided) {
|
|
268
|
+
this._result = BMConfirmationPopupResult.Confirmed;
|
|
269
|
+
this._resolve(BMConfirmationPopupResult.Confirmed);
|
|
270
|
+
|
|
271
|
+
this.dismissAnimated(YES);
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Shows this confirmation window on screen, then returns a promise that resolves when the user takes an
|
|
277
|
+
* action in response.
|
|
278
|
+
* @return <Promise<BMConfirmationPopupResult>> A promise that resolves with the user's action.
|
|
279
|
+
*/
|
|
280
|
+
confirm() {
|
|
281
|
+
this.bringToFrontAnimated(YES);
|
|
282
|
+
|
|
283
|
+
return this._resolution;
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
// @override - BMWindow
|
|
287
|
+
dismissAnimated() {
|
|
288
|
+
// Since the window can be dismissed by clicking outside in certain cases, this would be equivalent to pressing "OK".
|
|
289
|
+
if (this._result == BMConfirmationPopupResult.Undecided) {
|
|
290
|
+
this._result = BMConfirmationPopupResult.Confirmed;
|
|
291
|
+
this._resolve(BMConfirmationPopupResult.Confirmed);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return BMWindow.prototype.dismissAnimated.apply(this, arguments);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Constructs and returns an alert popup that is initialized with the given title, text and button labels.
|
|
301
|
+
* @param title <String> The popup's title.
|
|
302
|
+
* {
|
|
303
|
+
* @param text <String> The popup's body text.
|
|
304
|
+
* @param actionText <String, nullable> Defaults to `"OK"`. The text to display on the positive action button.
|
|
305
|
+
* }
|
|
306
|
+
* @return <BMAlertPopup> An alert popup.
|
|
307
|
+
*/
|
|
308
|
+
BMAlertPopup.alertPopupWithTitle = function (title, {text, actionText = 'OK'}) {
|
|
309
|
+
return (new BMAlertPopup).initWithTitle(title, {text, actionText});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// @endtype
|
|
313
|
+
|
|
314
|
+
// @type BMConfirmationPopup extends BMAlertPopup
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* A sublcass of `BMAlertPopup` that is specialized for displaying a confirmation popup with a title, a text message and
|
|
318
|
+
* a series of buttons that can be used to easily request and handle confirmation for potentially dangerous actions.
|
|
319
|
+
*
|
|
320
|
+
* To create a confirmation popup, use the static `confirmationPopupWithTitle(_, {})` method.
|
|
321
|
+
*
|
|
322
|
+
* You can display your confirmation popup using the usual `bringToFrontAnimated(_)` method, but for convenience you can also
|
|
323
|
+
* use the `confirm()` method that returns a promise which resolves when the user takes a decision.
|
|
324
|
+
*/
|
|
325
|
+
function BMConfirmationPopup() {} // <constructor>
|
|
326
|
+
|
|
327
|
+
BMConfirmationPopup.prototype = BMExtend(Object.create(BMAlertPopup.prototype), {
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* The text to use for the positive button.
|
|
331
|
+
*/
|
|
332
|
+
_negativeActionText: undefined, // <String>
|
|
333
|
+
|
|
334
|
+
get negativeActionText() {
|
|
335
|
+
return this._negativeActionText;
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
set negativeActionText(text) {
|
|
339
|
+
if (text == this._negativeActionText) return;
|
|
340
|
+
|
|
341
|
+
this._negativeActionText = text;
|
|
342
|
+
|
|
343
|
+
if (this._negativeActionButton) {
|
|
344
|
+
this._negativeActionButton.node.innerText = text;
|
|
345
|
+
this._negativeActionButton.invalidateIntrinsicSize();
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Controls whether a "Cancel" button will be available on this confirmation popup.
|
|
351
|
+
*/
|
|
352
|
+
_showsCancelButton: NO, // <Boolean>
|
|
353
|
+
|
|
354
|
+
get showsCancelButton() {
|
|
355
|
+
return this._showsCancelButton;
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
set showsCancelButton(shows) {
|
|
359
|
+
this._showsCancelButton = shows;
|
|
360
|
+
|
|
361
|
+
if (this._cancelButton) {
|
|
362
|
+
this._cancelButton.isVisible = shows;
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Designated initializer. Initializes this confirmation popup with the given labels.
|
|
368
|
+
* @param title <String> The popup's title.
|
|
369
|
+
* {
|
|
370
|
+
* @param text <String> The popup's body text.
|
|
371
|
+
* @param positiveActionText <String> The text to display on the positive action button.
|
|
372
|
+
* @param negativeActionText <String> The text to display on the negative action button.
|
|
373
|
+
* }
|
|
374
|
+
* @return <BMConfirmationPopup> This confirmation popup.
|
|
375
|
+
*/
|
|
376
|
+
initWithTitle(title, {text, positiveActionText, negativeActionText}) {
|
|
377
|
+
BMAlertPopup.prototype.initWithTitle.call(this, title, {text, actionText: positiveActionText});
|
|
378
|
+
|
|
379
|
+
this._negativeActionText = negativeActionText;
|
|
380
|
+
|
|
381
|
+
// Negative button
|
|
382
|
+
|
|
383
|
+
this._negativeActionButton = BMView.view();
|
|
384
|
+
this._negativeActionButton.supportsAutomaticIntrinsicSize = YES;
|
|
385
|
+
this._negativeActionButton.node.classList.add('BMButton', 'BMButtonWeak');
|
|
386
|
+
this._negativeActionButton.node.innerText = negativeActionText;
|
|
387
|
+
|
|
388
|
+
this.contentView.addSubview(this._negativeActionButton);
|
|
389
|
+
this._negativeActionButton.leading.equalTo(this.contentView.leading, {plus: 32}).isActive = YES;
|
|
390
|
+
this._negativeActionButton.bottom.equalTo(this.contentView.bottom, {plus: -32}).isActive = YES;
|
|
391
|
+
this._negativeActionButton.top.equalTo(this._textView.bottom, {plus: 64}).isActive = YES;
|
|
392
|
+
|
|
393
|
+
this._negativeActionButton.node.addEventListener('click', event => this._decline());
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
// Cancel button
|
|
397
|
+
|
|
398
|
+
this._cancelButton = BMView.view();
|
|
399
|
+
this._cancelButton.supportsAutomaticIntrinsicSize = YES;
|
|
400
|
+
this._cancelButton.node.classList.add('BMButton', 'BMButtonWeak');
|
|
401
|
+
this._cancelButton.node.innerText = 'Cancel';
|
|
402
|
+
this._cancelButton.isVisible = NO;
|
|
403
|
+
|
|
404
|
+
this.contentView.addSubview(this._cancelButton);
|
|
405
|
+
this._cancelButton.trailing.equalTo(this._positiveActionButton.leading, {plus: -32}).isActive = YES;
|
|
406
|
+
this._cancelButton.bottom.equalTo(this.contentView.bottom, {plus: -32}).isActive = YES;
|
|
407
|
+
this._cancelButton.top.equalTo(this._textView.bottom, {plus: 64}).isActive = YES;
|
|
408
|
+
this._cancelButton.leading.greaterThanOrEqualTo(this._negativeActionButton.trailing, {plus: 64}).isActive = YES;
|
|
409
|
+
|
|
410
|
+
this._cancelButton.node.addEventListener('click', event => this._cancel());
|
|
411
|
+
|
|
412
|
+
return this;
|
|
413
|
+
},
|
|
414
|
+
|
|
415
|
+
_escape() {
|
|
416
|
+
if (this._showsCancelButton) {
|
|
417
|
+
this._cancel();
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
this._decline();
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Declines the action, then dismisses this confirmation popup.
|
|
426
|
+
* If the result is already settled, this method will have no effect.
|
|
427
|
+
*/
|
|
428
|
+
_decline() {
|
|
429
|
+
if (this._result == BMConfirmationPopupResult.Undecided) {
|
|
430
|
+
this._result = BMConfirmationPopupResult.Declined;
|
|
431
|
+
this._resolve(BMConfirmationPopupResult.Declined);
|
|
432
|
+
|
|
433
|
+
this.dismissAnimated(YES);
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Cancels the action, then dismisses this confirmation popup.
|
|
439
|
+
* If the result is already settled, this method will have no effect.
|
|
440
|
+
*/
|
|
441
|
+
_cancel() {
|
|
442
|
+
if (this._result == BMConfirmationPopupResult.Undecided) {
|
|
443
|
+
this._result = BMConfirmationPopupResult.Cancelled;
|
|
444
|
+
this._resolve(BMConfirmationPopupResult.Cancelled);
|
|
445
|
+
|
|
446
|
+
this.dismissAnimated(YES);
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
// @override - BMWindow
|
|
451
|
+
dismissAnimated() {
|
|
452
|
+
// Since the window can be dismissed by clicking outside in certain cases, this would be equivalent to pressing "Cancel".
|
|
453
|
+
if (this._result == BMConfirmationPopupResult.Undecided) {
|
|
454
|
+
this._result = BMConfirmationPopupResult.Cancelled;
|
|
455
|
+
this._resolve(BMConfirmationPopupResult.Cancelled);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return BMWindow.prototype.dismissAnimated.apply(this, arguments);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Constructs and returns a confirmation popup that is initialized with the given title, text and button labels.
|
|
465
|
+
* @param title <String> The popup's title.
|
|
466
|
+
* {
|
|
467
|
+
* @param text <String> The popup's body text.
|
|
468
|
+
* @param positiveActionText <String> The text to display on the positive action button.
|
|
469
|
+
* @param negativeActionText <String> The text to display on the negative action button.
|
|
470
|
+
* }
|
|
471
|
+
* @return <BMConfirmationPopup> A confirmation popup.
|
|
472
|
+
*/
|
|
473
|
+
BMConfirmationPopup.confirmationPopupWithTitle = function (title, {text, positiveActionText, negativeActionText}) {
|
|
474
|
+
return (new BMConfirmationPopup).initWithTitle(title, {text, positiveActionText, negativeActionText});
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// @endtype
|