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,688 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {YES, NO, BMExtend, BMCopyProperties} from '../Core/BMCoreUI'
|
|
4
|
+
import {BMRectMake} from '../Core/BMRect'
|
|
5
|
+
import {BMLayoutConstraint, BMLayoutAttribute, BMLayoutConstraintRelation} from '../BMView/BMLayoutConstraint_v2.5'
|
|
6
|
+
import {BMView} from '../BMView/BMView_v2.5'
|
|
7
|
+
import {BMCollectionViewLayoutAttributesType, BMCollectionViewLayoutAttributesStyleDefaults} from './BMCollectionViewLayoutAttributes'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// @type BMJQueryShim
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The JQuery shim is an object that is compatible with the few jQuery methods used by CoreUI.
|
|
14
|
+
* All of the functions map directly to standard DOM methods.
|
|
15
|
+
*/
|
|
16
|
+
export function BMJQueryShim() {} // <constructor>
|
|
17
|
+
|
|
18
|
+
BMJQueryShim.prototype = {
|
|
19
|
+
/**
|
|
20
|
+
* The DOM node managed by this shim.
|
|
21
|
+
*/
|
|
22
|
+
0: document.body, // <DOMNode>
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Applies the given CSS properties to the DOM node managed by this shim.
|
|
26
|
+
* @param key <String> The CSS key.
|
|
27
|
+
* @param value <AnyObject> The CSS value.
|
|
28
|
+
*/
|
|
29
|
+
css(key, value) {
|
|
30
|
+
if (typeof key === 'string') {
|
|
31
|
+
this[0].style[key] = value;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
for (const cssKey in key) {
|
|
35
|
+
this[0].style[cssKey] = key[cssKey];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Applies the given CSS properties to the DOM node managed by this shim.
|
|
42
|
+
* @param props <Dictionary<AnyObject>> The key-value map of CSS properties to apply.
|
|
43
|
+
*/
|
|
44
|
+
// css(props) {
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns the `offsetWidth` property of this shim's node.
|
|
48
|
+
* @return <Number> The `offsetWidth`.
|
|
49
|
+
*/
|
|
50
|
+
width() {
|
|
51
|
+
return this[0].offsetWidth;
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns the `offsetHeight` property of this shim's node.
|
|
56
|
+
* @return <Number> The `offsetHeight`.
|
|
57
|
+
*/
|
|
58
|
+
height() {
|
|
59
|
+
return this[0].offsetHeight;
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns an object containing the `offsetLeft` and `offsetTop` properties of this shim's node.
|
|
64
|
+
* @return <Object> The requested properties.
|
|
65
|
+
*/
|
|
66
|
+
offset() {
|
|
67
|
+
return {left: this[0].offsetLeft, top: this[0].offsetTop};
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Appends the DOM node managed by the given jQuery shim to this shim's DOM node.
|
|
72
|
+
* @param shim <BMJQueryShim> The shim containing the node to add.
|
|
73
|
+
*/
|
|
74
|
+
append(shim) {
|
|
75
|
+
if (typeof shim === 'string') {
|
|
76
|
+
this[0].insertAdjacentHTML('beforeend', shim);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this[0].append(shim[0]);
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Removes the contents of this shim's DOM node.
|
|
84
|
+
*/
|
|
85
|
+
empty() {
|
|
86
|
+
this[0].innerHTML = '';
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Removes this shim's DOM node.
|
|
91
|
+
*/
|
|
92
|
+
remove() {
|
|
93
|
+
this[0].remove();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Constructs and returns a jQuery shim for the given DOM node.
|
|
100
|
+
* @param node <DOMNode> The node for which to construct a shim.
|
|
101
|
+
* @return <BMJQueryShim> A jQuery shim.
|
|
102
|
+
*/
|
|
103
|
+
BMJQueryShim.shimWithDOMNode = function (node) {
|
|
104
|
+
if ('$' in window) {
|
|
105
|
+
return $(node);
|
|
106
|
+
}
|
|
107
|
+
const shim = new BMJQueryShim();
|
|
108
|
+
shim[0] = node;
|
|
109
|
+
return shim;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// @endtype
|
|
113
|
+
|
|
114
|
+
// When set to YES, this will cause collection view cells to extend view
|
|
115
|
+
const BM_USE_BMVIEW_SUBCLASS = YES;
|
|
116
|
+
|
|
117
|
+
// @type BMCollectionViewCell extends BMView
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A controller object that manages a cell view instance and its associated retain count.
|
|
121
|
+
* The cell is used as a controller for both regular cells, supplementary views and decoration views.
|
|
122
|
+
* The represented item type is not strongly associated with the actual cell, but it may be inferred from its reuse identifier
|
|
123
|
+
* and associated attributes.
|
|
124
|
+
*
|
|
125
|
+
* Cells should not be instantiated manually; they will be constructed and provided by the collection view when requested using one of the <code>dequeueCell...</code> methods.
|
|
126
|
+
*/
|
|
127
|
+
export function BMCollectionViewCell() { // <constructor>
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var BMCell = BMCollectionViewCell; // <Class>
|
|
131
|
+
|
|
132
|
+
// #FLAG
|
|
133
|
+
BMCollectionViewCell.prototype = BMExtend(BM_USE_BMVIEW_SUBCLASS ? Object.create(BMView.prototype) : {}, {
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The number of times the cell was retained.
|
|
137
|
+
* Subclasses should not override this getter.
|
|
138
|
+
*/
|
|
139
|
+
get retainCount() { // <Number>
|
|
140
|
+
return this._retainCount + this._manageCount;
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Returns YES if the cell is managed by the collection view, NO otherwise.
|
|
145
|
+
* Subclasses should not override this getter.
|
|
146
|
+
*/
|
|
147
|
+
get isManaged() {
|
|
148
|
+
return this._manageCount > 0;
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Returns YES if the cell is retained or managed by the collection view, NO otherwise.
|
|
153
|
+
* Subclasses should not override this getter.
|
|
154
|
+
*/
|
|
155
|
+
get isRetained() {
|
|
156
|
+
return this.retainCount > 0;
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
160
|
+
get _frame() {
|
|
161
|
+
return this._attributes && this._attributes.frame;
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
165
|
+
get frame() {
|
|
166
|
+
return this._attributes && this._attributes.frame;
|
|
167
|
+
},
|
|
168
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
169
|
+
set frame(frame) {
|
|
170
|
+
// NOTE: A cell's frame is controlled by its layout attributes, therefore this operation is a no-op
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
get supportsAutomaticIntrinsicSize() {
|
|
174
|
+
// Use automatic intrinsic size when measuring this cell if it has no subviews
|
|
175
|
+
if (this._isMeasuring && !this._subviews.length) {
|
|
176
|
+
return YES;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return NO;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The collection view that created this cell.
|
|
184
|
+
* Subclasses should not override this property.
|
|
185
|
+
*/
|
|
186
|
+
collectionView: undefined, // <BMCollectionView>
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @deprecated Deprecated. Use the <code>node</code> property instead.
|
|
190
|
+
* The jQuery element managed by this cell.
|
|
191
|
+
* Subclasses should not override this property.
|
|
192
|
+
*/
|
|
193
|
+
_element: undefined, // <BMJQueryShim>
|
|
194
|
+
get element() { return this._element || (this._element = BMJQueryShim.shimWithDOMNode(this.node)); },
|
|
195
|
+
|
|
196
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
197
|
+
/**
|
|
198
|
+
* The DOM node managed by this cell.
|
|
199
|
+
*/
|
|
200
|
+
//node: undefined, // <DOMNode>
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The type of item this cell represents.
|
|
204
|
+
* Subclasses should not override this property.
|
|
205
|
+
*/
|
|
206
|
+
itemType: BMCollectionViewLayoutAttributesType.Cell, // <BMCollectionViewLayoutAttributesType>
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The cell's reuse identifier which corresponds to the template's reuse identifier.
|
|
210
|
+
*/
|
|
211
|
+
_reuseIdentifier: undefined, // <String>
|
|
212
|
+
|
|
213
|
+
get reuseIdentifier() {
|
|
214
|
+
return this._reuseIdentifier;
|
|
215
|
+
},
|
|
216
|
+
set reuseIdentifier(identifier) {
|
|
217
|
+
if (identifier != this._reuseIdentifier && this.collectionView.assignsReuseIdentifierAsClass) {
|
|
218
|
+
if (this._reuseIdentifier) {
|
|
219
|
+
this.node.classList.remove(`BMCollectionViewCell-${this._reuseIdentifier}`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (identifier) {
|
|
223
|
+
this.node.classList.add(`BMCollectionViewCell-${identifier}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
this._reuseIdentifier = identifier;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* The cell's size and position relative to its own frame.
|
|
233
|
+
*/
|
|
234
|
+
_bounds: BMRectMake(), // <BMRect>
|
|
235
|
+
|
|
236
|
+
get bounds() { return this._bounds; },
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Invoked just before this cell's bounds are about to change to the given bounds.
|
|
240
|
+
* This method is invoked before the bounds have actually been changed and before any associated animation has run.
|
|
241
|
+
* Subclasses can override this method to react to bound updates.
|
|
242
|
+
* The default implementation does nothing.
|
|
243
|
+
* @param bounds <BMRect> The new bounds.
|
|
244
|
+
*/
|
|
245
|
+
boundsWillChangeToBounds(bounds) {
|
|
246
|
+
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Invoked repeatedly during animations while this cell's bounds are changing.
|
|
251
|
+
* Subclasses can override this method to react to bound updates. Note that as this method is invoked once per animation frame
|
|
252
|
+
* any update within this method should be as fast as possible to avoid framerate drops.
|
|
253
|
+
* The default implementation does nothing.
|
|
254
|
+
* @param bounds <BMRect> The new bounds.
|
|
255
|
+
*/
|
|
256
|
+
boundsDidTransitionToBounds(bounds) {
|
|
257
|
+
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Invoked after this cell's bounds have been updated and any associated animation has finished running.
|
|
262
|
+
* Subclasses can override this method to react to bound updates.
|
|
263
|
+
* The default implementation does nothing.
|
|
264
|
+
* @param bounds <BMRect> The previous bounds.
|
|
265
|
+
*/
|
|
266
|
+
boundsDidChangeFromBounds(bounds) {
|
|
267
|
+
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Animatable. The cell attributes used to render this cell.
|
|
272
|
+
* Subclasses should not override this property.
|
|
273
|
+
*/
|
|
274
|
+
_attributes: undefined, // <BMCollectionViewLayoutAttributes>
|
|
275
|
+
|
|
276
|
+
get attributes() {
|
|
277
|
+
return this._attributes;
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
set attributes(attributes) {
|
|
281
|
+
|
|
282
|
+
var oldAttributes = this._attributes;
|
|
283
|
+
if (this._attributes) {
|
|
284
|
+
this._attributes.cell = undefined;
|
|
285
|
+
this._previousFrame = oldAttributes.frame.copy();
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
this._previousFrame = undefined;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
this._attributes = attributes;
|
|
292
|
+
if (!attributes) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
attributes.cell = undefined;
|
|
296
|
+
|
|
297
|
+
// Clear the old styles
|
|
298
|
+
if (oldAttributes) {
|
|
299
|
+
if (oldAttributes.style) {
|
|
300
|
+
attributes.style = attributes.style || {};
|
|
301
|
+
|
|
302
|
+
for (var key in oldAttributes.style) {
|
|
303
|
+
if (attributes.style[key] === undefined) attributes.style[key] = BMCollectionViewLayoutAttributesStyleDefaults[key];
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Setting the cell property of the attributes will cause the attributes to automatically apply themselves to this cell
|
|
309
|
+
if (attributes) {
|
|
310
|
+
attributes.cell = this;
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* The index path that this cell is currently bound to.
|
|
316
|
+
* Subclasses should not override this getter.
|
|
317
|
+
*/
|
|
318
|
+
get indexPath() { // <BMIndexPath>
|
|
319
|
+
return this._attributes ? this._attributes.indexPath : undefined;
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* A special version of retain used only by the collection view.
|
|
324
|
+
* Subclasses should not override this method.
|
|
325
|
+
* @return <BMCollectionViewCell> This cell.
|
|
326
|
+
*/
|
|
327
|
+
_manage: function () {
|
|
328
|
+
if (this._manageCount) return this;
|
|
329
|
+
|
|
330
|
+
this._manageCount++;
|
|
331
|
+
|
|
332
|
+
this.collectionView.cellWasManaged(this);
|
|
333
|
+
if (this.retainCount === 1) {
|
|
334
|
+
this.prepareForDisplay();
|
|
335
|
+
this.collectionView.cellShouldRender(this);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return this;
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* A special version of release used only by the collection view.
|
|
343
|
+
* Subclasses should not override this method.
|
|
344
|
+
*/
|
|
345
|
+
_unmanage: function () {
|
|
346
|
+
if (!this._manageCount) return;
|
|
347
|
+
|
|
348
|
+
this._manageCount--;
|
|
349
|
+
|
|
350
|
+
this.collectionView.cellWasUnmanaged(this);
|
|
351
|
+
if (this.retainCount === 0) {
|
|
352
|
+
this.prepareForReuse();
|
|
353
|
+
this.collectionView.cellWasReleased(this);
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Retains ownership of this cell, preventing the collection view from recycling it, until it is released.
|
|
359
|
+
* If the object backing this cell is removed from the data set while it's still retained, the cell may be destroyed,
|
|
360
|
+
* guaranteeing that it won't be reused later.
|
|
361
|
+
* Subclasses that override this method should invoke the superclass method at some point in their implementation.
|
|
362
|
+
* @return <BMCollectionViewCell> This cell.
|
|
363
|
+
*/
|
|
364
|
+
retain: function () {
|
|
365
|
+
this._retainCount++;
|
|
366
|
+
|
|
367
|
+
if (this.retainCount == 1) {
|
|
368
|
+
this.prepareForDisplay();
|
|
369
|
+
this.collectionView.cellShouldRender(this);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return this;
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Relinquishes ownership of this cell. If the retain count reaches 0, the cell may be recycled.
|
|
377
|
+
* You should only release cells that you previously retained, otherwise the collection view may behave
|
|
378
|
+
* in an undefined manner.
|
|
379
|
+
* Subclasses that override this method should invoke the superclass method at some point in their implementation.
|
|
380
|
+
*/
|
|
381
|
+
release: function () {
|
|
382
|
+
this._retainCount--;
|
|
383
|
+
|
|
384
|
+
if (this.retainCount == 0) {
|
|
385
|
+
this.prepareForReuse();
|
|
386
|
+
this.collectionView.cellWasReleased(this);
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Invoked by the collection view to recycle this cell, preparing it for reuse later. This implicitly invokes _unmanage().
|
|
392
|
+
* If this cell is not fully released after invoking this method, it will notify the collection view to destroy it.
|
|
393
|
+
* Subclasses that override this method should invoke the superclass method at some point in their implementation.
|
|
394
|
+
* Note that after the superclass implementation is invoked, the cell will have been either collected or invalidated.
|
|
395
|
+
*/
|
|
396
|
+
recycle: function () {
|
|
397
|
+
this._unmanage();
|
|
398
|
+
|
|
399
|
+
this.invalidate();
|
|
400
|
+
|
|
401
|
+
//this.collectionView.cellWasUnmanaged(this);
|
|
402
|
+
if (this.retainCount > 0) {
|
|
403
|
+
this.collectionView.cellWasInvalidated(this);
|
|
404
|
+
this.destroy();
|
|
405
|
+
|
|
406
|
+
// A cell that was invalidated can no longer be retained or released, otherwise there is a risk of resurrecting it
|
|
407
|
+
this._manage = function () {};
|
|
408
|
+
this._unmanage = this._manage;
|
|
409
|
+
this.retain = this._manage;
|
|
410
|
+
this.release = this.retain;
|
|
411
|
+
this.recycle = this.retain;
|
|
412
|
+
this.releaseRecycledCell = this.retain;
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Invoked by the collection view to recycle this cell, preparing it for reuse later. This implicitly invokes release().
|
|
418
|
+
* If this cell is not fully released after invoking this method, it will notify the collection view to destroy it.
|
|
419
|
+
* Subclasses that override this method should invoke the superclass method at some point in their implementation.
|
|
420
|
+
* Note that after the superclass implementation is invoked, the cell will have been either collected or invalidated.
|
|
421
|
+
*/
|
|
422
|
+
releaseRecycledCell: function () {
|
|
423
|
+
this.release();
|
|
424
|
+
|
|
425
|
+
this.invalidate();
|
|
426
|
+
|
|
427
|
+
if (this.retainCount > 0) {
|
|
428
|
+
this.collectionView.cellWasInvalidated(this);
|
|
429
|
+
this.destroy();
|
|
430
|
+
|
|
431
|
+
// A cell that was invalidated can no longer be retained or released, otherwise there is a risk of resurrecting it
|
|
432
|
+
this._manage = function () {};
|
|
433
|
+
this._unmanage = this._manage;
|
|
434
|
+
this.retain = this._manage;
|
|
435
|
+
this.release = this.retain;
|
|
436
|
+
this.recycle = this.retain;
|
|
437
|
+
this.releaseRecycledCell = this.retain;
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Should be set to YES to hide the cell, or NO to reveal it.
|
|
443
|
+
*/
|
|
444
|
+
_isHidden: NO, // <Boolean>
|
|
445
|
+
|
|
446
|
+
get isHidden() {
|
|
447
|
+
return this._isHidden;
|
|
448
|
+
},
|
|
449
|
+
set isHidden(hidden) {
|
|
450
|
+
if (this._isHidden != hidden) {
|
|
451
|
+
if (hidden) {
|
|
452
|
+
this._hide();
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
this._show();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Hides this cell from the layout without recycling it.
|
|
462
|
+
* If the cell is already hidden, this method does nothing.
|
|
463
|
+
*/
|
|
464
|
+
_hide: function () {
|
|
465
|
+
this._isHidden = YES;
|
|
466
|
+
this.node.classList.add('BMCollectionViewCellHidden');
|
|
467
|
+
},
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Reveals a previously hidden cell.
|
|
471
|
+
* If the cell is already visible, this method does nothing.
|
|
472
|
+
*/
|
|
473
|
+
_show: function () {
|
|
474
|
+
this._isHidden = NO;
|
|
475
|
+
this.node.classList.remove('BMCollectionViewCellHidden');
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
479
|
+
_prepareForAutomaticIntrinsicSize() {
|
|
480
|
+
for (let subview of this._subviews) {
|
|
481
|
+
subview._prepareForAutomaticIntrinsicSize();
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (this._isMeasuring) {
|
|
485
|
+
if (this._subviews.length) {
|
|
486
|
+
// If this cell's size can be determined via its subview's constraints, use the size of
|
|
487
|
+
// the cell's subview as its measurement
|
|
488
|
+
BMCopyProperties(this._node.style, {width: '100%', height: '100%'});
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
if (this._requiredWidth) {
|
|
492
|
+
// Otherwise derive the measured size using the instrinsic CSS size
|
|
493
|
+
BMCopyProperties(this._node.style, {width: this._requiredWidth + 'px', height: 'auto'});
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
// Otherwise derive the measured size using the instrinsic CSS size
|
|
497
|
+
BMCopyProperties(this._node.style, {width: 'auto', height: 'auto'});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
504
|
+
_supportsAutomaticIntrinsicSize: NO,
|
|
505
|
+
|
|
506
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
507
|
+
/**
|
|
508
|
+
* Temporarily set to `YES` while this cell is being measured.
|
|
509
|
+
*/
|
|
510
|
+
_isMeasuring: NO,
|
|
511
|
+
|
|
512
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
513
|
+
internalConstraints() {
|
|
514
|
+
var constraints = [];
|
|
515
|
+
|
|
516
|
+
if (this._isMeasuring) return constraints;
|
|
517
|
+
|
|
518
|
+
if (this._rootViewLeftConstraint) {
|
|
519
|
+
if (this.attributes) {
|
|
520
|
+
this._rootViewWidthConstraint.constant = this.attributes.frame.size.width;
|
|
521
|
+
this._rootViewHeightConstraint.constant = this.attributes.frame.size.height;
|
|
522
|
+
}
|
|
523
|
+
constraints.push(this._rootViewLeftConstraint, this._rootViewTopConstraint, this._rootViewWidthConstraint, this._rootViewHeightConstraint);
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
constraints.push(
|
|
527
|
+
this._rootViewLeftConstraint = BMLayoutConstraint.internalConstraintWithView(this, {attribute: BMLayoutAttribute.Left, relatedBy: BMLayoutConstraintRelation.Equals, constant: 0}),
|
|
528
|
+
this._rootViewTopConstraint = BMLayoutConstraint.internalConstraintWithView(this, {attribute: BMLayoutAttribute.Top, relatedBy: BMLayoutConstraintRelation.Equals, constant: 0}),
|
|
529
|
+
this._rootViewWidthConstraint = BMLayoutConstraint.internalConstraintWithView(this, {attribute: BMLayoutAttribute.Width, relatedBy: BMLayoutConstraintRelation.Equals, constant: this.attributes ? this.attributes.frame.size.width : 0}),
|
|
530
|
+
this._rootViewHeightConstraint = BMLayoutConstraint.internalConstraintWithView(this, {attribute: BMLayoutAttribute.Height, relatedBy: BMLayoutConstraintRelation.Equals, constant: this.attributes ? this.attributes.frame.size.height : 0})
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
return constraints;
|
|
535
|
+
|
|
536
|
+
},
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Invoked prior to this cell being updated as part of an animated data update.
|
|
541
|
+
* Subclasses can override this method to perform any changes necessary for this update or add additional
|
|
542
|
+
* animations to run as part of the update.
|
|
543
|
+
* Note this method will always be invoked with an active animation context.
|
|
544
|
+
* The default implementation does nothing.
|
|
545
|
+
*/
|
|
546
|
+
prepareForAnimatedUpdate() {
|
|
547
|
+
|
|
548
|
+
},
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Invoked prior to this cell being collected for reuse by the collection view.
|
|
552
|
+
* Subclasses can override this method to perform any changes necessary for reusing this cell.
|
|
553
|
+
* Subclasses should invoke the superclass method at some point in their implementation.
|
|
554
|
+
*/
|
|
555
|
+
prepareForReuse() {
|
|
556
|
+
|
|
557
|
+
},
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Invoked prior to this cell being shown on the screen either after being initialized or after having been previously collected.
|
|
561
|
+
* Subclasses can override this method to perform any changes necesarry for displaying this cell.
|
|
562
|
+
* Subclasses should invoke the superclass method at some point in their implementaiton.
|
|
563
|
+
*/
|
|
564
|
+
prepareForDisplay() {
|
|
565
|
+
|
|
566
|
+
},
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Invoked prior to this cell being destroyed either because its data set object has been removed while this cell was still
|
|
570
|
+
* being retained or because its owning collection view was released.
|
|
571
|
+
* Subclasses can override this method to perform any changes necessary for cleanup, such as removing global event listeners/
|
|
572
|
+
* The default implementation currently does nothing, but subclasses should nevertheless invoke the superclass method at some
|
|
573
|
+
* point in their implementation.
|
|
574
|
+
* After this method returns, the cell's node will be removed from the document and this cell will no longer be reused.
|
|
575
|
+
*/
|
|
576
|
+
invalidate() {
|
|
577
|
+
|
|
578
|
+
},
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Invoked by the collection view when this cell can no longer be recycled and should be destroyed.
|
|
582
|
+
* Subclasses that require any additional cleanup before being destroyed should override this method
|
|
583
|
+
* and perform any necessary cleanup here.
|
|
584
|
+
* After this method returns, the collection view will remove this cell's node from the DOM and will no
|
|
585
|
+
* longer reuse this cell.
|
|
586
|
+
* Subclasses overriding this method should invoke the superclass method at the end of their implementation.
|
|
587
|
+
* After this method is invoked, all references to this cell should be cleared to allow the garbage collector
|
|
588
|
+
* to reclaim its memory.
|
|
589
|
+
*/
|
|
590
|
+
destroy() {
|
|
591
|
+
BMView.prototype.release.call(this);
|
|
592
|
+
},
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* @deprecated Currently unused.
|
|
596
|
+
*
|
|
597
|
+
* A property instructing the collection view whether the cell contains asynchronous components used when initializing and the collection view
|
|
598
|
+
* should await for those asynchronous components to complete before actually rendering the cell.
|
|
599
|
+
* When this getter returns <code>NO</code>, the collection view will invoke <code>initNonatomic</code> on this cell after the base initializer
|
|
600
|
+
* has returned and await for the promise returned by that method to resolve before continuing its operation.
|
|
601
|
+
* Note that collection view will only await for nonatomic code only during the initial loading and during data updates, in other cases, <code>initNonatomic</code>
|
|
602
|
+
* will be invoked as normally, but the collection will not block awaiting for it to resolve - therefore cell subclasses that use asynchronous should be
|
|
603
|
+
* prepared to handle the cases where they are used before their nonatomic resources have finished loading.
|
|
604
|
+
*/
|
|
605
|
+
get initializesAtomically() { // <Boolean>
|
|
606
|
+
return YES;
|
|
607
|
+
},
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Designated initializer. Invoked immediately after creation to initialize this cell.
|
|
611
|
+
* Subclasses that need custom initialization should invoke the superclass method early on in their implementation to ensure
|
|
612
|
+
* that the superclass components are correctly initialized.
|
|
613
|
+
* @param collectionView <BMCollectionView> The calling collection view.
|
|
614
|
+
* {
|
|
615
|
+
* @param reuseIdentifier <String> The reuse identifier of this cell. The collection view will use this property to return a cell
|
|
616
|
+
* with the correct contents when reusing elements.
|
|
617
|
+
* @param node <DOMNode> The DOM node managed by this cell.
|
|
618
|
+
* @param kind <BMCollectionViewLayoutAttributesType, nullable> Defaults to `.Cell`. The kind of cell.
|
|
619
|
+
* }
|
|
620
|
+
* @return <BMCollectionViewCell> This cell.
|
|
621
|
+
*/
|
|
622
|
+
initWithCollectionView(collectionView, args) {
|
|
623
|
+
this._retainCount = 0;
|
|
624
|
+
this._manageCount = 0;
|
|
625
|
+
|
|
626
|
+
this.collectionView = collectionView;
|
|
627
|
+
|
|
628
|
+
// #FLAG BM_USE_BMVIEW_SUBCLASS
|
|
629
|
+
if (BM_USE_BMVIEW_SUBCLASS) {
|
|
630
|
+
BMView.prototype.initWithDOMNode.call(this, args.node);
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
this.node = args.node;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
this.reuseIdentifier = args.reuseIdentifier;
|
|
637
|
+
|
|
638
|
+
if (args.kind) this.itemType = args.kind;
|
|
639
|
+
|
|
640
|
+
return this;
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
_collectionViewDidBecomeVisible() {
|
|
644
|
+
for (const subview of this.allSubviews) {
|
|
645
|
+
subview.viewDidBecomeVisible();
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
|
|
649
|
+
_collectionViewDidBecomeInvisible() {
|
|
650
|
+
for (const subview of this.allSubviews) {
|
|
651
|
+
subview.viewDidBecomeInvisible();
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* @deprecated Currently unused.
|
|
657
|
+
*
|
|
658
|
+
* Invoked when cell subtypes return <code>NO</code> from <code>initializesAtomically</code>.
|
|
659
|
+
* Subtypes should asynchronously perform any work they need, returning a promise that resolves when that work is finished.
|
|
660
|
+
* When this method is invoked during data updates and the initial loading, collection view will await for the promise returned
|
|
661
|
+
* by this method to resolve before displaying any changes to the user.
|
|
662
|
+
*/
|
|
663
|
+
initNonatomic: async function () {
|
|
664
|
+
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Creates and returns a new <code>BMCollectionViewCell</code> that will be managed by the given collection view.
|
|
670
|
+
* This constructor should not be invoked manually; the collection view itself should decide when it is appropriate to construct new cells.
|
|
671
|
+
* @param collectionView <BMCollectionView> The calling collection view.
|
|
672
|
+
* {
|
|
673
|
+
* @param withReuseIdentifier <String> The reuse identifier of this cell. The collection view will use this property to return a cell
|
|
674
|
+
* with the correct contents when reusing elements.
|
|
675
|
+
* @param node <DOMNode> The DOM node managed by this cell.
|
|
676
|
+
* }
|
|
677
|
+
* @return <BMCollectionViewCell> A cell.
|
|
678
|
+
*/
|
|
679
|
+
export function BMCollectionViewCellMakeForCollectionView(collectionView, options) {
|
|
680
|
+
return (new BMCollectionViewCell).initWithCollectionView(collectionView, options);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* @deprecated Deprecated. Use <code>BMCollectionViewCellMakeForCollectionView</code> instead.
|
|
685
|
+
*/
|
|
686
|
+
var BMCellMakeForCollectionView = BMCollectionViewCellMakeForCollectionView;
|
|
687
|
+
|
|
688
|
+
// @endtype
|