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.
Files changed (99) hide show
  1. package/CHANGELOG.md +1624 -0
  2. package/LICENSE +21 -0
  3. package/README.md +145 -0
  4. package/build/@types/index.d.ts +14078 -0
  5. package/build/BMCodeEditor/BMCodeEditor.js +707 -0
  6. package/build/BMCollectionView/BMCollectionView.js +5861 -0
  7. package/build/BMCollectionView/BMCollectionViewCell.js +688 -0
  8. package/build/BMCollectionView/BMCollectionViewFlowLayout.js +4467 -0
  9. package/build/BMCollectionView/BMCollectionViewLayout.js +830 -0
  10. package/build/BMCollectionView/BMCollectionViewLayoutAttributes.js +673 -0
  11. package/build/BMCollectionView/BMCollectionViewMasonryLayout.js +491 -0
  12. package/build/BMCollectionView/BMCollectionViewStackLayout.js +634 -0
  13. package/build/BMCollectionView/BMCollectionViewTileLayout.js +1121 -0
  14. package/build/BMCoreUI.css +2833 -0
  15. package/build/BMView/BMAttributedLabelView.js +310 -0
  16. package/build/BMView/BMLayoutConstraint_v2.5.js +1813 -0
  17. package/build/BMView/BMLayoutGuide.js +192 -0
  18. package/build/BMView/BMLayoutSizeClass.js +466 -0
  19. package/build/BMView/BMMenu.js +574 -0
  20. package/build/BMView/BMScrollView.js +247 -0
  21. package/build/BMView/BMTextField.js +512 -0
  22. package/build/BMView/BMTextFieldDelegate.js +71 -0
  23. package/build/BMView/BMView_v2.5.js +3572 -0
  24. package/build/BMView/BMViewport.js +221 -0
  25. package/build/BMViewLayoutEditor/BMLayoutEditor.js +6117 -0
  26. package/build/BMViewLayoutEditor/BMLayoutEditorConstraintSettings.js +417 -0
  27. package/build/BMViewLayoutEditor/BMLayoutEditorDelegate.js +59 -0
  28. package/build/BMViewLayoutEditor/BMLayoutEditorSettingCells.js +1653 -0
  29. package/build/BMViewLayoutEditor/BMLayoutEditorSettings.js +1480 -0
  30. package/build/BMViewLayoutEditor/BMLayoutEditorSettingsComplexCells.js +431 -0
  31. package/build/BMViewLayoutEditor/BMLayoutEditorSettingsDelegate.js +46 -0
  32. package/build/BMViewLayoutEditor/BMLayoutEditorVariablesController.js +460 -0
  33. package/build/BMViewLayoutEditor/BMLayoutEditorViewGroupSettings.js +293 -0
  34. package/build/BMViewLayoutEditor/BMLayoutEditorViewSettings.js +382 -0
  35. package/build/BMViewLayoutEditor/BMLayoutVariableProvider.js +202 -0
  36. package/build/BMWindow/BMConfirmationPopup.js +477 -0
  37. package/build/BMWindow/BMKeyboardShortcut.js +151 -0
  38. package/build/BMWindow/BMPopover/BMPopover.js +492 -0
  39. package/build/BMWindow/BMToolWindow.js +71 -0
  40. package/build/BMWindow/BMWindow.js +2000 -0
  41. package/build/Core/BMAnimationContext.js +1181 -0
  42. package/build/Core/BMColor.js +991 -0
  43. package/build/Core/BMCoreUI.js +470 -0
  44. package/build/Core/BMFunctionCollection.js +110 -0
  45. package/build/Core/BMIndexPath.js +165 -0
  46. package/build/Core/BMInset.js +138 -0
  47. package/build/Core/BMKeyPath.js +100 -0
  48. package/build/Core/BMPoint.js +291 -0
  49. package/build/Core/BMRect.js +556 -0
  50. package/build/Core/BMSize.js +137 -0
  51. package/build/iScroll/LICENSE +22 -0
  52. package/build/iScroll/iscroll-probe.js +2154 -0
  53. package/build/images/AlignBottom.png +0 -0
  54. package/build/images/AlignCenterX.png +0 -0
  55. package/build/images/AlignCenterY.png +0 -0
  56. package/build/images/AlignLeading.png +0 -0
  57. package/build/images/AlignTop.png +0 -0
  58. package/build/images/AlignTrailing.png +0 -0
  59. package/build/images/AllConstraints.png +0 -0
  60. package/build/images/BottomConstraint.png +0 -0
  61. package/build/images/CenterXConstraint.png +0 -0
  62. package/build/images/CenterYConstraint.png +0 -0
  63. package/build/images/CoreUI2.png +0 -0
  64. package/build/images/CoreUI2@2x.png +0 -0
  65. package/build/images/Desktop.png +0 -0
  66. package/build/images/DesktopMini.png +0 -0
  67. package/build/images/EqualHeight.png +0 -0
  68. package/build/images/EqualHorizontalSpacing.png +0 -0
  69. package/build/images/EqualHorizontalSpacingInSuperview.png +0 -0
  70. package/build/images/EqualVerticalSpacing.png +0 -0
  71. package/build/images/EqualVerticalSpacingInSuperview.png +0 -0
  72. package/build/images/EqualWidth.png +0 -0
  73. package/build/images/HeightConstraint.png +0 -0
  74. package/build/images/InactiveConstraints.png +0 -0
  75. package/build/images/Layout.png +0 -0
  76. package/build/images/LayoutVariables.png +0 -0
  77. package/build/images/LeftConstraint.png +0 -0
  78. package/build/images/OwnConstraints.png +0 -0
  79. package/build/images/Phone.png +0 -0
  80. package/build/images/PhoneLandscape.png +0 -0
  81. package/build/images/PhoneLandscapeMini.png +0 -0
  82. package/build/images/PhoneMini.png +0 -0
  83. package/build/images/PhonePortrait.png +0 -0
  84. package/build/images/PhonePortraitMini.png +0 -0
  85. package/build/images/Properties.png +0 -0
  86. package/build/images/RightConstraint.png +0 -0
  87. package/build/images/SubviewConstraints.png +0 -0
  88. package/build/images/Tablet.png +0 -0
  89. package/build/images/TabletLandscape.png +0 -0
  90. package/build/images/TabletLandscapeMini.png +0 -0
  91. package/build/images/TabletMini.png +0 -0
  92. package/build/images/TabletPortrait.png +0 -0
  93. package/build/images/TabletPortraitMini.png +0 -0
  94. package/build/images/TopConstraint.png +0 -0
  95. package/build/images/WidthConstraint.png +0 -0
  96. package/build/index.js +40 -0
  97. package/lib/@types/BMCoreUI.min.d.ts +14078 -0
  98. package/lib/BMCoreUI.min.js +1 -0
  99. package/package.json +58 -0
@@ -0,0 +1,192 @@
1
+ // @ts-check
2
+
3
+ import {YES, NO, BMExtend} from '../Core/BMCoreUI'
4
+ import {BMPointMake} from '../Core/BMPoint'
5
+ import {BMLayoutAttribute, BMLayoutConstraintRelation, BMLayoutConstraint} from './BMLayoutConstraint_v2.5'
6
+ import {BMView} from './BMView_v2.5'
7
+
8
+ // @type BMLayoutGuide extends BMView
9
+
10
+ /**
11
+ * The layout guide view is a view that can be dragged and translates its dragged position into constraints related to its superview.
12
+ * This makes it possible to use it to implement behaviours such as resizable or movable panels.
13
+ */
14
+ export function BMLayoutGuide () {} // <constructor>
15
+
16
+ BMLayoutGuide.prototype = BMExtend({}, BMView.prototype, {
17
+ // @override - BMView
18
+ get supportsAutomaticIntrinsicSize() {
19
+ return NO;
20
+ },
21
+
22
+ /**
23
+ * This layout guide's position.
24
+ */
25
+ _position: BMPointMake(), // <BMPoint>
26
+
27
+ /**
28
+ * Set to `YES` after this layout guide has been dragged once.
29
+ */
30
+ _dragged: NO, // <Boolean>
31
+
32
+ /**
33
+ * The horizontal layout attribute that will be used when building this layout guide's horizontal constraint.
34
+ */
35
+ _horizontalConstraintAnchor: BMLayoutAttribute.Leading, // <BMLayoutAttribute>
36
+
37
+ /**
38
+ * The vertical layout attribute that will be used when building this layout guide's vertical constraint.
39
+ */
40
+ _verticalConstraintAnchor: BMLayoutAttribute.Top, // <BMLayoutAttribute>
41
+
42
+ // @override - BMView
43
+ initWithDOMNode(node) {
44
+ BMView.prototype.initWithDOMNode.call(this, node);
45
+
46
+ node.addEventListener('mousedown', event => {
47
+ this._dragged = YES;
48
+
49
+ let lastPosition;
50
+ if (this._horizontalConstraintAnchor == BMLayoutAttribute.Trailing) {
51
+ this._position = BMPointMake(this.node.offsetLeft + this.node.offsetWidth - this.node.parentNode.offsetWidth, this.node.offsetTop + this.node.offsetHeight - this.node.parentNode.offsetHeight);
52
+ lastPosition = BMPointMake(event.clientX, event.clientY);
53
+ }
54
+ else {
55
+ this._position = BMPointMake(this.node.offsetLeft, this.node.offsetTop);
56
+ lastPosition = BMPointMake(event.clientX, event.clientY);
57
+ }
58
+
59
+ let mouseMoveEventListener = event => {
60
+ let position = BMPointMake(event.clientX, event.clientY);
61
+ this._position = BMPointMake(this._position.x + position.x - lastPosition.x, this._position.y + position.y - lastPosition.y);
62
+ lastPosition = position;
63
+ if (this.superview) this.layout();
64
+ event.preventDefault();
65
+ };
66
+
67
+ // Upon starting a drag event, add a mask over the entire viewport that uses the layout guide's cursor
68
+ let cursor = window.getComputedStyle(this.node).cursor;
69
+
70
+ let mask = document.createElement('div');
71
+ mask.className = 'BMLayoutGuideMask';
72
+ mask.style.cursor = cursor;
73
+ document.body.appendChild(mask);
74
+
75
+ let mouseUpEventListener = event => {
76
+ window.removeEventListener('mousemove', mouseMoveEventListener, YES);
77
+ window.removeEventListener('mouseup', mouseUpEventListener, YES);
78
+ mask.remove();
79
+ }
80
+
81
+ window.addEventListener('mousemove', mouseMoveEventListener, YES);
82
+ window.addEventListener('mouseup', mouseUpEventListener, YES);
83
+
84
+ event.preventDefault();
85
+ });
86
+
87
+ let touchDragPoint;
88
+
89
+ node.addEventListener('touchstart', /** @type {TouchEvent} */ event => {
90
+ // If there is already a drag in progress, don't process this new event
91
+ if (typeof touchDragPoint !== 'undefined') {
92
+ return;
93
+ }
94
+
95
+ // Only use the first touch point
96
+ touchDragPoint = event.changedTouches[0].identifier;
97
+ this._dragged = YES;
98
+
99
+ let lastPosition;
100
+ if (this._horizontalConstraintAnchor == BMLayoutAttribute.Trailing) {
101
+ this._position = BMPointMake(this.node.offsetLeft + this.node.offsetWidth - this.node.parentNode.offsetWidth, this.node.offsetTop + this.node.offsetHeight - this.node.parentNode.offsetHeight);
102
+ lastPosition = BMPointMake(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
103
+ }
104
+ else {
105
+ this._position = BMPointMake(this.node.offsetLeft, this.node.offsetTop);
106
+ lastPosition = BMPointMake(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
107
+ }
108
+
109
+ let mouseMoveEventListener = event => {
110
+ // Look for the actively tracked touch point
111
+ let touch;
112
+ for (let changedTouch of event.changedTouches) {
113
+ if (changedTouch.identifier == touchDragPoint) {
114
+ touch = changedTouch;
115
+ break;
116
+ }
117
+ }
118
+
119
+ // If the actively tracked touch point did not move, do not process this event
120
+ if (!touch) return;
121
+
122
+ let position = BMPointMake(touch.clientX, touch.clientY);
123
+ this._position = BMPointMake(this._position.x + position.x - lastPosition.x, this._position.y + position.y - lastPosition.y);
124
+ lastPosition = position;
125
+ if (this.superview) this.layout();
126
+ event.preventDefault();
127
+ };
128
+
129
+ let mouseUpEventListener = event => {
130
+ touchDragPoint = undefined;
131
+ window.removeEventListener('touchmove', mouseMoveEventListener);
132
+ window.removeEventListener('touchend', mouseUpEventListener);
133
+ window.removeEventListener('touchcancel', mouseUpEventListener);
134
+ }
135
+
136
+ window.addEventListener('touchmove', mouseMoveEventListener);
137
+ window.addEventListener('touchend', mouseUpEventListener);
138
+ window.removeEventListener('touchcancel', mouseUpEventListener);
139
+
140
+ event.preventDefault();
141
+ });
142
+
143
+ return this;
144
+
145
+ },
146
+
147
+ /**
148
+ * Sets this layout guide's position. If this guide has been
149
+ * dragged, setting this values does nothing.
150
+ */
151
+ set initialPosition(position) { // <BMPoint>
152
+ if (!this._dragged) {
153
+ this._position = position.copy();
154
+ if (this.superview) this.layout();
155
+ }
156
+ },
157
+
158
+ // @override - BMView
159
+ internalConstraints() {
160
+ let constraints = BMView.prototype.internalConstraints.call(this);
161
+
162
+ if (this._superviewLeftConstraint) {
163
+ this._superviewLeftConstraint.constant = this._position.x;
164
+ this._superviewTopConstraint.constant = this._position.y;
165
+
166
+ constraints.push(this._superviewLeftConstraint, this._superviewTopConstraint);
167
+ }
168
+ else {
169
+ // Their reported positioning is always the parent scroll view's scroll offset
170
+ constraints.push(this._superviewLeftConstraint = BMLayoutConstraint.internalConstraintWithView(this, {
171
+ attribute: this._horizontalConstraintAnchor,
172
+ relatedBy: BMLayoutConstraintRelation.Equals,
173
+ toView: this.superview,
174
+ secondAttribute: this._horizontalConstraintAnchor,
175
+ constant: this._position.x,
176
+ priority: 500
177
+ }));
178
+ constraints.push(this._superviewTopConstraint = BMLayoutConstraint.internalConstraintWithView(this, {
179
+ attribute: this._verticalConstraintAnchor,
180
+ relatedBy: BMLayoutConstraintRelation.Equals,
181
+ toView: this.superview,
182
+ secondAttribute: this._verticalConstraintAnchor,
183
+ constant: this._position.y,
184
+ priority: 500
185
+ }));
186
+ }
187
+
188
+ return constraints;
189
+ }
190
+ });
191
+
192
+ // @endtype
@@ -0,0 +1,466 @@
1
+ // @type BMLayoutDimensionClass
2
+
3
+ import {NO} from '../Core/BMCoreUI'
4
+
5
+ /**
6
+ * Constants that describe the size class of a dimension of the screen or an area of the screen.
7
+ * The exact relationship between these constants and the size breakpoints to which they apply
8
+ * is managed internally by CoreUI and is not exposed within this enum.
9
+ */
10
+ export var BMLayoutDimensionClass = Object.freeze({ // <enum>
11
+
12
+ /**
13
+ * Indicates that this dimension is compact, best suited for phone layouts.
14
+ */
15
+ Compact: 'C', // <enum>
16
+
17
+ /**
18
+ * Indicates that this dimension is regular, best suited for tablets and small laptops.
19
+ */
20
+ Regular: 'R', // <enum>
21
+
22
+ /**
23
+ * Indicates that this dimension is extended, best suited for desktop monitors, laptops and larger tablets.
24
+ */
25
+ Extended: 'E', // <enum>
26
+
27
+ /**
28
+ * Indicates that this dimension is unspecified. For configurations that depend upon a specific size class, this specifies
29
+ * that the configuration will apply to all dimensions.
30
+ */
31
+ Any: '_', // <enum>
32
+
33
+ });
34
+
35
+ /**
36
+ * Returns the appropriate layout dimension class for the given size.
37
+ * @param size <Number> The size.
38
+ * @return <BMLayoutDimensionClass> The dimension class.
39
+ */
40
+ export function BMLayoutDimensionClassForSize(size) {
41
+ if (!size) {
42
+ return BMLayoutDimensionClass.Extended;
43
+ }
44
+ else if (size < 600) {
45
+ return BMLayoutDimensionClass.Compact;
46
+ }
47
+ else if (size <= 1024) {
48
+ return BMLayoutDimensionClass.Regular;
49
+ }
50
+ else {
51
+ return BMLayoutDimensionClass.Extended;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Returns the appropriate maximal size for the given layout dimension class.
57
+ * @param dimensionClass <BMLayoutDimensionClass> The layout dimension class.
58
+ * @return <Number> The size.
59
+ */
60
+ export function BMSizeForLayoutDimensionClass(dimensionClass) {
61
+ if (dimensionClass == BMLayoutDimensionClass.Compact) {
62
+ return 600;
63
+ }
64
+ else if (dimensionClass == BMLayoutDimensionClass.Regular) {
65
+ return 1024;
66
+ }
67
+ else {
68
+ return 0;
69
+ }
70
+ }
71
+
72
+ // @endtype
73
+
74
+ // @type BMLayoutSizeClassDeviceKind
75
+
76
+ /**
77
+ * Constants that describe the simplified device kind based on the screen's diagonal.
78
+ */
79
+ export var BMLayoutSizeClassDeviceKind = Object.freeze({ // <enum>
80
+
81
+ /**
82
+ * Indicates that the device is a phone based on the size of its screen.
83
+ */
84
+ Phone: 'S', // <enum>
85
+
86
+ /**
87
+ * Indicates that the device is a tablet based on the size of its screen.
88
+ */
89
+ Tablet: 'T', // <enum>
90
+
91
+ /**
92
+ * Indicates that the device is larger than a tablet based on the size of its screen.
93
+ */
94
+ Extended: '_', // <enum>
95
+
96
+ });
97
+
98
+ // @endtype
99
+
100
+ // @type BMLayoutOrientation
101
+
102
+ /**
103
+ * Constants that describe the orientation of the screen or an area of the screen.
104
+ */
105
+ export var BMLayoutOrientation = Object.freeze({ // <enum>
106
+
107
+ /**
108
+ * Indicates a portrait orientation, where the width is smaller than the height.
109
+ */
110
+ Portrait: 'P', // <enum>
111
+
112
+ /**
113
+ * Indicates a landscape orientation, where the width is greater than or equal to the height.
114
+ */
115
+ Landscape: 'L', // <enum>
116
+
117
+ /**
118
+ * Indicates that this orientation is unspecified. For configurations that depend upon a specific orientation, this specifies
119
+ * that the configuration will apply to all orientations.
120
+ */
121
+ Any: '_', // <enum>
122
+
123
+ });
124
+
125
+ // @endtype
126
+
127
+ // @type BMLayoutSizeClass
128
+
129
+ /**
130
+ * A layout size class describes the approximate size of the viewport or a portion of the viewport.
131
+ * It is used to vary view and layout attributes to ensure an appropriate display on various
132
+ * types of displays.
133
+ *
134
+ * In a view hierarchy, the size class refers to the entire hierarchy's size class - individual views
135
+ * cannot declare their own specific size class - however the root of the view hierarchy may decide whether the
136
+ * size class it uses depends on the size of the view hierarchy or the entire viewport.
137
+ *
138
+ * Layout classes are created by invoking the `layoutSizeClassWithWidthClass(_, {heightClass, orientation})` static method
139
+ * and not through the constructor.
140
+ * Some common size classes are available via specialized static methods:
141
+ * * `phoneSizeClass()`
142
+ * * `phoneSizeClassWithOrientation(_)`
143
+ * * `tabletSizeClass()`
144
+ * * `tabletSizeClassWithOrientation(_)`
145
+ */
146
+ export function BMLayoutSizeClass() {} // <constructor>
147
+
148
+ BMLayoutSizeClass.prototype = {
149
+
150
+ /**
151
+ * The simplified width dimension size class.
152
+ */
153
+ _widthSizeClass: BMLayoutSizeClass.Extended, // <BMLayoutSizeClass>
154
+
155
+ get widthSizeClass() {
156
+ return this._widthSizeClass;
157
+ },
158
+
159
+ /**
160
+ * The maximum width to which this size class applies.
161
+ */
162
+ _maximumWidth: 0, // <Number>
163
+
164
+ get maximumWidth() {
165
+ return this._maximumWidth;
166
+ },
167
+
168
+ /**
169
+ * The simplified height dimension size class.
170
+ */
171
+ _heightSizeClass: BMLayoutSizeClass.Extended, // <BMLayoutSizeClass>
172
+
173
+ get heightSizeClass() {
174
+ return this._heightSizeClass;
175
+ },
176
+
177
+ /**
178
+ * The maximum height to which this size class applies.
179
+ */
180
+ _maximumHeight: 0, // <Number>
181
+
182
+ get maximumHeight() {
183
+ return this._maximumHeight;
184
+ },
185
+
186
+ /**
187
+ * The orientation.
188
+ */
189
+ _orientation: BMLayoutOrientation.Any, // <BMLayoutOrientation>
190
+
191
+ get orientation() {
192
+ return this._orientation;
193
+ },
194
+
195
+ /**
196
+ * The simplified device type.
197
+ */
198
+ _deviceKind: BMLayoutSizeClassDeviceKind.Extended, // <BMLayoutSizeClassDeviceKind>
199
+
200
+ get deviceType() {
201
+ return this._deviceKind;
202
+ },
203
+
204
+ /**
205
+ * The maximum diagonal to which this size class applies.
206
+ */
207
+ _maximumDiagonal: 0, // <Number>
208
+
209
+ get maximumDiagonal() {
210
+ return this._maximumDiagonal;
211
+ },
212
+
213
+ /**
214
+ * A number specifying the priority this size class has over other compatible size classes.
215
+ */
216
+ _priority: 0, // <Number>
217
+
218
+ get priority() {
219
+ return this._priority;
220
+ },
221
+
222
+ /**
223
+ * Used internally by CoreUI for storage and identification.
224
+ */
225
+ _hashString: undefined, // <String>
226
+
227
+ /**
228
+ * Invoked by CoreUI during creation to create the hash string associated
229
+ * with this size class.
230
+ */
231
+ _createHashString() {
232
+ let hashTokens = [];
233
+
234
+ // Compute the hash string to be able to store this size class efficiently
235
+ if (this._maximumWidth) {
236
+ hashTokens.push('w' + this._maximumWidth.toFixed());
237
+ }
238
+
239
+ if (this._maximumHeight) {
240
+ hashTokens.push('h' + this._maximumWidth.toFixed());
241
+ }
242
+
243
+ if (this._maximumDiagonal) {
244
+ hashTokens.push('d' + this._maximumDiagonal.toFixed());
245
+ }
246
+
247
+ if (this._orientation != BMLayoutOrientation.Any) {
248
+ hashTokens.push(this._orientation);
249
+ }
250
+
251
+ this._hashString = hashTokens.join(' ');
252
+ },
253
+
254
+ /**
255
+ * Compares this size class to the given size class, returning `YES` if they are identical and
256
+ * `NO` otherwise. Note that in most cases, size class objects are reused across CoreUI, so identical
257
+ * size classes should have identical references as well.
258
+ * @param sizeClass <BMLayoutSizeClass, nullable> The size class against which to compare this size class.
259
+ * @return <Boolean> `YES` if the size classes are identical or `NO` otherwise.
260
+ */
261
+ isEqualToSizeClass(sizeClass) {
262
+ if (!sizeClass) return NO;
263
+
264
+ return this._hashString == sizeClass._hashString;
265
+ },
266
+
267
+ /**
268
+ * Returns a string representation of this size class.
269
+ * @return <String> A string.
270
+ */
271
+ toString() {
272
+ return this._hashString;
273
+ }
274
+ }
275
+
276
+ // A map that is used internally by CoreUI and contains all of the layout size classes that are currently active.
277
+ var _BMActiveLayoutSizeClasses = new Map;
278
+
279
+ /**
280
+ * Constructs and returns a layout size class initialized with the given requirements.
281
+ * @param maximumWidth <Number, nullable> An optional maximum width that a viewport may have to match this size class.
282
+ * {
283
+ * @param maximumHeight <Number, nullable> An optional maximum height that a viewport may have to match this size class.
284
+ * @param maximumDiagonal <Number, nullable> An optional maximum diagonal that a viewport may have to match this size class.
285
+ * @param orientation <BMLayoutOrientation, nullable> Defaults to .Any. An optional orientation that a viewport is required to have in
286
+ * order to match this size class.
287
+ * }
288
+ */
289
+ BMLayoutSizeClass.layoutSizeClassWithMaximumWidth = function (width, args) {
290
+ let sizeClass = new BMLayoutSizeClass();
291
+
292
+ sizeClass._widthSizeClass = BMLayoutDimensionClassForSize(width);
293
+ sizeClass._maximumWidth = width;
294
+ sizeClass._heightSizeClass = BMLayoutDimensionClassForSize(args.maximumHeight);
295
+ sizeClass._maximumHeight = args.maximumHeight;
296
+ sizeClass._orientation = args.orientation || BMLayoutOrientation.Any;
297
+ sizeClass._maximumDiagonal = args.maximumDiagonal || 0;
298
+
299
+ // TODO: Assign a priority, exact semantics TBD
300
+ let priority = 0;
301
+ if (sizeClass._maximumWidth) priority += 10;
302
+ if (sizeClass._maximumHeight) priority += 10;
303
+ if (args.orientation !== BMLayoutOrientation.Any) priority += 1;
304
+
305
+ sizeClass._priority = priority;
306
+
307
+ sizeClass._createHashString();
308
+
309
+ // If there is already a global reference to this size class, return it
310
+ if (_BMActiveLayoutSizeClasses[sizeClass._hashString]) {
311
+ return _BMActiveLayoutSizeClasses[sizeClass._hashString];
312
+ }
313
+
314
+ // Otherwise store a global reference and return the newly created size class
315
+ _BMActiveLayoutSizeClasses[sizeClass._hashString] = sizeClass;
316
+ return sizeClass;
317
+ }
318
+
319
+ /**
320
+ * Constructs and returns a layout size class object initialized with the given requirements.
321
+ * @param widthSizeClass <BMLayoutDimensionClass> The simplified width size class.
322
+ * {
323
+ * @param heightSizeClass <BMLayoutDimensionClass> The simplified height size class.
324
+ * @param orientation <BMLayoutOrientation, nullable> Defaults to .Any. The orientation.
325
+ * }
326
+ * @return <BMLayoutSizeClass> A size class.
327
+ */
328
+ BMLayoutSizeClass.layoutSizeClassWithWidthClass = function (widthSizeClass, args) {
329
+ let sizeClass = new BMLayoutSizeClass();
330
+
331
+ sizeClass._widthSizeClass = widthSizeClass;
332
+ sizeClass._maximumWidth = BMSizeForLayoutDimensionClass(widthSizeClass);
333
+ sizeClass._heightSizeClass = args.heightSizeClass;
334
+ sizeClass._maximumHeight = BMSizeForLayoutDimensionClass(args.heightSizeClass);
335
+ sizeClass._orientation = args.orientation || BMLayoutOrientation.Any;
336
+ sizeClass._maximumDiagonal = 0;
337
+
338
+ // TODO: Assign a priority, exact semantics TBD
339
+ let priority = 0;
340
+ if (sizeClass._maximumWidth) priority += 10;
341
+ if (sizeClass._maximumHeight) priority += 10;
342
+ if (args.orientation !== BMLayoutOrientation.Any) priority += 1;
343
+
344
+ sizeClass._priority = priority;
345
+
346
+ sizeClass._createHashString();
347
+
348
+ // If there is already a global reference to this size class, return it
349
+ if (_BMActiveLayoutSizeClasses[sizeClass._hashString]) {
350
+ return _BMActiveLayoutSizeClasses[sizeClass._hashString];
351
+ }
352
+
353
+ // Otherwise store a global reference and return the newly created size class
354
+ _BMActiveLayoutSizeClasses[sizeClass._hashString] = sizeClass;
355
+ return sizeClass;
356
+ }
357
+
358
+ /**
359
+ * Returns a size class that matches phones.
360
+ * @return <BMLayoutSizeClass> A size class.
361
+ */
362
+ BMLayoutSizeClass.phoneSizeClass = function () {
363
+ return this.phoneSizeClassWithOrientation(BMLayoutOrientation.Any);
364
+ }
365
+
366
+ /**
367
+ * Returns a size class that matches phones whose screen is in the given orientation.
368
+ * @param orientation <BMLayoutOrientation, nullable> Defaults to .Any. The orientation.
369
+ * @return <BMLayoutSizeClass> A size class.
370
+ */
371
+ BMLayoutSizeClass.phoneSizeClassWithOrientation = function (orientation) {
372
+ let sizeClass = new BMLayoutSizeClass();
373
+
374
+ sizeClass._maximumDiagonal = 1000;
375
+ sizeClass._orientation = orientation || BMLayoutOrientation.Any;
376
+
377
+ sizeClass._createHashString();
378
+
379
+ // If there is already a global reference to this size class, return it
380
+ if (_BMActiveLayoutSizeClasses[sizeClass._hashString]) {
381
+ return _BMActiveLayoutSizeClasses[sizeClass._hashString];
382
+ }
383
+
384
+ // Otherwise store a global reference and return the newly created size class
385
+ _BMActiveLayoutSizeClasses[sizeClass._hashString] = sizeClass;
386
+ return sizeClass;
387
+ }
388
+
389
+ /**
390
+ * Returns a size class that matches tablets.
391
+ * @return <BMLayoutSizeClass> A size class.
392
+ */
393
+ BMLayoutSizeClass.tabletSizeClass = function () {
394
+ return this.tabletSizeClassWithOrientation(BMLayoutOrientation.Any);
395
+ }
396
+
397
+ /**
398
+ * Returns a size class that matches tablets whose screen is in the given orientation.
399
+ * @param orientation <BMLayoutOrientation, nullable> Defaults to .Any. The orientation.
400
+ * @return <BMLayoutSizeClass> A size class.
401
+ */
402
+ BMLayoutSizeClass.tabletSizeClassWithOrientation = function (orientation) {
403
+ let sizeClass = new BMLayoutSizeClass();
404
+
405
+ sizeClass._maximumDiagonal = 1450;
406
+ sizeClass._orientation = orientation || BMLayoutOrientation.Any;
407
+
408
+ sizeClass._createHashString();
409
+
410
+ // If there is already a global reference to this size class, return it
411
+ if (_BMActiveLayoutSizeClasses[sizeClass._hashString]) {
412
+ return _BMActiveLayoutSizeClasses[sizeClass._hashString];
413
+ }
414
+
415
+ // Otherwise store a global reference and return the newly created size class
416
+ _BMActiveLayoutSizeClasses[sizeClass._hashString] = sizeClass;
417
+ return sizeClass;
418
+ }
419
+
420
+ /**
421
+ * Used internally to create a size class from a hash string.
422
+ * @param hashString <String> The hash string.
423
+ * @return <BMLayoutSizeClass> A size class.
424
+ */
425
+ BMLayoutSizeClass._layoutSizeClassForHashString = function (hashString) {
426
+ // If there is already a global reference to this size class, return it
427
+ if (_BMActiveLayoutSizeClasses[hashString]) {
428
+ return _BMActiveLayoutSizeClasses[hashString];
429
+ }
430
+
431
+ // Otherwise parse the hash string and store the newly created reference for future use
432
+ let tokens = hashString.split(' ');
433
+ let sizeClass = new BMLayoutSizeClass();
434
+ sizeClass._hashString = hashString;
435
+
436
+ for (let token of tokens) {
437
+ let type = token.charAt(0);
438
+ switch (type) {
439
+ case 'w':
440
+ sizeClass._maximumWidth = parseInt(token.substring(1, token.length));
441
+ sizeClass._widthSizeClass = BMLayoutDimensionClassForSize(sizeClass._maximumWidth);
442
+ break;
443
+ case 'h':
444
+ sizeClass._maximumHeight = parseInt(token.substring(1, token.length));
445
+ sizeClass._heightSizeClass = BMLayoutDimensionClassForSize(sizeClass._maximumHeight);
446
+ break;
447
+ case 'd':
448
+ sizeClass._maximumDiagonal = parseInt(token.substring(1, token.length));
449
+ break;
450
+ case 'P':
451
+ sizeClass._orientation = BMLayoutOrientation.Portrait;
452
+ break;
453
+ case 'L':
454
+ sizeClass._orientation = BMLayoutOrientation.Landscape;
455
+ break;
456
+ case 'p':
457
+ sizeClass._priority = parseInt(token.substring(1, token.length));
458
+ break;
459
+ }
460
+ }
461
+
462
+ _BMActiveLayoutSizeClasses[sizeClass._hashString] = sizeClass;
463
+ return sizeClass;
464
+ }
465
+
466
+ // @endtype