@hpcc-js/layout 2.51.0 → 2.51.1

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/dist/index.js CHANGED
@@ -20,8 +20,8 @@
20
20
  }
21
21
 
22
22
  var PKG_NAME = "@hpcc-js/layout";
23
- var PKG_VERSION = "2.51.0";
24
- var BUILD_VERSION = "2.107.0";
23
+ var PKG_VERSION = "2.51.1";
24
+ var BUILD_VERSION = "2.108.2";
25
25
 
26
26
  /******************************************************************************
27
27
  Copyright (c) Microsoft Corporation.
@@ -3499,704 +3499,711 @@
3499
3499
  FlexGrid.prototype.publish("widgetsFlexBasis", [], "array", "Array of flex-basis values keyed on the widgets array");
3500
3500
  FlexGrid.prototype.publish("widgets", [], "widgetArray", "Array of widgets to be rendered as list items");
3501
3501
 
3502
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3503
-
3504
3502
  function getDefaultExportFromCjs (x) {
3505
3503
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3506
3504
  }
3507
3505
 
3508
- var gridList$1 = {exports: {}};
3509
-
3510
- (function (module, exports) {
3511
- (function (root, factory) {
3512
- {
3513
- // Node. Does not work with strict CommonJS, but
3514
- // only CommonJS-like environments that support module.exports,
3515
- // like Node.
3516
- module.exports = factory();
3517
- }
3518
- }(commonjsGlobal, function() {
3519
-
3520
- var GridList = function(items, options) {
3521
- /**
3522
- * A GridList manages the two-dimensional positions from a list of items,
3523
- * within a virtual matrix.
3524
- *
3525
- * The GridList's main function is to convert the item positions from one
3526
- * grid size to another, maintaining as much of their order as possible.
3527
- *
3528
- * The GridList's second function is to handle collisions when moving an item
3529
- * over another.
3530
- *
3531
- * The positioning algorithm places items in columns. Starting from left to
3532
- * right, going through each column top to bottom.
3533
- *
3534
- * The size of an item is expressed using the number of cols and rows it
3535
- * takes up within the grid (w and h)
3536
- *
3537
- * The position of an item is express using the col and row position within
3538
- * the grid (x and y)
3539
- *
3540
- * An item is an object of structure:
3541
- * {
3542
- * w: 3, h: 1,
3543
- * x: 0, y: 1
3544
- * }
3545
- */
3546
-
3547
- this._options = options;
3548
- for (var k in this.defaults) {
3549
- if (!this._options.hasOwnProperty(k)) {
3550
- this._options[k] = this.defaults[k];
3551
- }
3552
- }
3553
-
3554
- this.items = items;
3555
-
3556
- this._adjustSizeOfItems();
3557
-
3558
- this.generateGrid();
3559
- };
3560
-
3561
- GridList.cloneItems = function(items, _items) {
3562
- /**
3563
- * Clone items with a deep level of one. Items are not referenced but their
3564
- * properties are
3565
- */
3566
- var i,
3567
- k;
3568
- if (_items === undefined) {
3569
- _items = [];
3570
- }
3571
- for (i = 0; i < items.length; i++) {
3572
- // XXX: this is good because we don't want to lose item reference, but
3573
- // maybe we should clear their properties since some might be optional
3574
- if (!_items[i]) {
3575
- _items[i] = {};
3576
- }
3577
- for (k in items[i]) {
3578
- _items[i][k] = items[i][k];
3579
- }
3580
- }
3581
- return _items;
3582
- };
3583
-
3584
- GridList.prototype = {
3585
-
3586
- defaults: {
3587
- lanes: 5,
3588
- direction: 'horizontal'
3589
- },
3590
-
3591
- /**
3592
- * Illustates grid as text-based table, using a number identifier for each
3593
- * item. E.g.
3594
- *
3595
- * #| 0 1 2 3 4 5 6 7 8 9 10 11 12 13
3596
- * --------------------------------------------
3597
- * 0| 00 02 03 04 04 06 08 08 08 12 12 13 14 16
3598
- * 1| 01 -- 03 05 05 07 09 10 11 11 -- 13 15 --
3599
- *
3600
- * Warn: Does not work if items don't have a width or height specified
3601
- * besides their position in the grid.
3602
- */
3603
- toString: function() {
3604
- var widthOfGrid = this.grid.length,
3605
- output = '\n #|',
3606
- border = '\n --',
3607
- item,
3608
- i,
3609
- j;
3610
-
3611
- // Render the table header
3612
- for (i = 0; i < widthOfGrid; i++) {
3613
- output += ' ' + this._padNumber(i, ' ');
3614
- border += '---';
3615
- } output += border;
3616
-
3617
- // Render table contents row by row, as we go on the y axis
3618
- for (i = 0; i < this._options.lanes; i++) {
3619
- output += '\n' + this._padNumber(i, ' ') + '|';
3620
- for (j = 0; j < widthOfGrid; j++) {
3621
- output += ' ';
3622
- item = this.grid[j][i];
3623
- output += item ? this._padNumber(this.items.indexOf(item), '0') : '--';
3624
- }
3625
- } output += '\n';
3626
- return output;
3627
- },
3628
-
3629
- generateGrid: function() {
3630
- /**
3631
- * Build the grid structure from scratch, with the current item positions
3632
- */
3633
- var i;
3634
- this._resetGrid();
3635
- for (i = 0; i < this.items.length; i++) {
3636
- this._markItemPositionToGrid(this.items[i]);
3637
- }
3638
- },
3639
-
3640
- resizeGrid: function(lanes) {
3641
- var currentColumn = 0;
3642
-
3643
- this._options.lanes = lanes;
3644
- this._adjustSizeOfItems();
3645
-
3646
- this._sortItemsByPosition();
3647
- this._resetGrid();
3648
-
3649
- // The items will be sorted based on their index within the this.items array,
3650
- // that is their "1d position"
3651
- for (var i = 0; i < this.items.length; i++) {
3652
- var item = this.items[i],
3653
- position = this._getItemPosition(item);
3654
-
3655
- this._updateItemPosition(
3656
- item, this.findPositionForItem(item, {x: currentColumn, y: 0}));
3657
-
3658
- // New items should never be placed to the left of previous items
3659
- currentColumn = Math.max(currentColumn, position.x);
3660
- }
3661
-
3662
- this._pullItemsToLeft();
3663
- },
3664
-
3665
- findPositionForItem: function(item, start, fixedRow) {
3666
- /**
3667
- * This method has two options for the position we want for the item:
3668
- * - Starting from a certain row/column number and only looking for
3669
- * positions to its right
3670
- * - Accepting positions for a certain row number only (use-case: items
3671
- * being shifted to the left/right as a result of collisions)
3672
- *
3673
- * @param {Object<x:Number, y:Number, w:Number, h:Number} item
3674
- * @param {Object<x:Number, y:Number} start Position from which to start
3675
- * the search.
3676
- * @param {Number} [fixedRow] If provided, we're going to try to find a
3677
- * position for the new item on it. If doesn't fit there, we're going
3678
- * to put it on the first row.
3679
- *
3680
- * @returns {Number[2]} x and y.
3681
- */
3682
-
3683
- var x, y, position;
3684
-
3685
- // Start searching for a position from the horizontal position of the
3686
- // rightmost item from the grid
3687
- for (x = start.x; x < this.grid.length; x++) {
3688
- if (fixedRow !== undefined) {
3689
- position = [x, fixedRow];
3690
-
3691
- if (this._itemFitsAtPosition(item, position)) {
3692
- return position;
3693
- }
3694
- } else {
3695
- for (y = start.y; y < this._options.lanes; y++) {
3696
- position = [x, y];
3697
-
3698
- if (this._itemFitsAtPosition(item, position)) {
3699
- return position;
3700
- }
3701
- }
3702
- }
3703
- }
3704
-
3705
- // If we've reached this point, we need to start a new column
3706
- var newCol = this.grid.length,
3707
- newRow = 0;
3708
-
3709
- if (fixedRow !== undefined &&
3710
- this._itemFitsAtPosition(item, [newCol, fixedRow])) {
3711
- newRow = fixedRow;
3712
- }
3713
-
3714
- return [newCol, newRow];
3715
- },
3716
-
3717
- moveItemToPosition: function(item, newPosition) {
3718
- var position = this._getItemPosition({
3719
- x: newPosition[0],
3720
- y: newPosition[1],
3721
- w: item.w,
3722
- h: item.h
3723
- });
3724
-
3725
- this._updateItemPosition(item, [position.x, position.y]);
3726
- this._resolveCollisions(item);
3727
- },
3728
-
3729
- resizeItem: function(item, size) {
3730
- /**
3731
- * Resize an item and resolve collisions.
3732
- *
3733
- * @param {Object} item A reference to an item that's part of the grid.
3734
- * @param {Object} size
3735
- * @param {Number} [size.w=item.w] The new width.
3736
- * @param {Number} [size.h=item.h] The new height.
3737
- */
3738
-
3739
- var width = size.w || item.w,
3740
- height = size.h || item.h;
3741
-
3742
- this._updateItemSize(item, width, height);
3743
-
3744
- this._resolveCollisions(item);
3745
-
3746
- this._pullItemsToLeft();
3747
- },
3748
-
3749
- getChangedItems: function(initialItems, idAttribute) {
3750
- /**
3751
- * Compare the current items against a previous snapshot and return only
3752
- * the ones that changed their attributes in the meantime. This includes both
3753
- * position (x, y) and size (w, h)
3754
- *
3755
- * Since both their position and size can change, the items need an
3756
- * additional identifier attribute to match them with their previous state
3757
- */
3758
- var changedItems = [];
3759
-
3760
- for (var i = 0; i < initialItems.length; i++) {
3761
- var item = this._getItemByAttribute(idAttribute,
3762
- initialItems[i][idAttribute]);
3763
-
3764
- if (item.x !== initialItems[i].x ||
3765
- item.y !== initialItems[i].y ||
3766
- item.w !== initialItems[i].w ||
3767
- item.h !== initialItems[i].h) {
3768
- changedItems.push(item);
3769
- }
3770
- }
3771
-
3772
- return changedItems;
3773
- },
3774
-
3775
- _sortItemsByPosition: function() {
3776
- this.items.sort(function(item1, item2) {
3777
- var position1 = this._getItemPosition(item1),
3778
- position2 = this._getItemPosition(item2);
3779
-
3780
- // Try to preserve columns.
3781
- if (position1.x != position2.x) {
3782
- return position1.x - position2.x;
3783
- }
3784
-
3785
- if (position1.y != position2.y) {
3786
- return position1.y - position2.y;
3787
- }
3788
-
3789
- // The items are placed on the same position.
3790
- return 0;
3791
- }.bind(this));
3792
- },
3793
-
3794
- _adjustSizeOfItems: function() {
3795
- /**
3796
- * Some items can have 100% height or 100% width. Those dimmensions are
3797
- * expressed as 0. We need to ensure a valid width and height for each of
3798
- * those items as the number of items per lane.
3799
- */
3800
-
3801
- for (var i = 0; i < this.items.length; i++) {
3802
- var item = this.items[i];
3803
-
3804
- // This can happen only the first time items are checked.
3805
- // We need the property to have a value for all the items so that the
3806
- // `cloneItems` method will merge the properties properly. If we only set
3807
- // it to the items that need it then the following can happen:
3808
- //
3809
- // cloneItems([{id: 1, autoSize: true}, {id: 2}],
3810
- // [{id: 2}, {id: 1, autoSize: true}]);
3811
- //
3812
- // will result in
3813
- //
3814
- // [{id: 1, autoSize: true}, {id: 2, autoSize: true}]
3815
- if (item.autoSize === undefined) {
3816
- item.autoSize = item.w === 0 || item.h === 0;
3817
- }
3818
-
3819
- if (item.autoSize) {
3820
- if (this._options.direction === 'horizontal') {
3821
- item.h = this._options.lanes;
3822
- } else {
3823
- item.w = this._options.lanes;
3824
- }
3825
- }
3826
- }
3827
- },
3828
-
3829
- _resetGrid: function() {
3830
- this.grid = [];
3831
- },
3832
-
3833
- _itemFitsAtPosition: function(item, newPosition) {
3834
- /**
3835
- * Check that an item wouldn't overlap with another one if placed at a
3836
- * certain position within the grid
3837
- */
3838
-
3839
- var position = this._getItemPosition(item),
3840
- x, y;
3841
-
3842
- // No coordonate can be negative
3843
- if (newPosition[0] < 0 || newPosition[1] < 0) {
3844
- return false;
3845
- }
3846
-
3847
- // Make sure the item isn't larger than the entire grid
3848
- if (newPosition[1] + position.h > this._options.lanes) {
3849
- return false;
3850
- }
3851
-
3852
- // Make sure the position doesn't overlap with an already positioned
3853
- // item.
3854
- for (x = newPosition[0]; x < newPosition[0] + position.w; x++) {
3855
- var col = this.grid[x];
3856
-
3857
- // Surely a column that hasn't even been created yet is available
3858
- if (!col) {
3859
- continue;
3860
- }
3861
-
3862
- for (y = newPosition[1]; y < newPosition[1] + position.h; y++) {
3863
- // Any space occupied by an item can continue to be occupied by the
3864
- // same item.
3865
- if (col[y] && col[y] !== item) {
3866
- return false;
3867
- }
3868
- }
3869
- }
3870
-
3871
- return true;
3872
- },
3873
-
3874
- _updateItemPosition: function(item, position) {
3875
- if (item.x !== null && item.y !== null) {
3876
- this._deleteItemPositionFromGrid(item);
3877
- }
3878
-
3879
- this._setItemPosition(item, position);
3880
-
3881
- this._markItemPositionToGrid(item);
3882
- },
3883
-
3884
- _updateItemSize: function(item, width, height) {
3885
- /**
3886
- * @param {Object} item A reference to a grid item.
3887
- * @param {Number} width The new width.
3888
- * @param {Number} height The new height.
3889
- */
3890
-
3891
- if (item.x !== null && item.y !== null) {
3892
- this._deleteItemPositionFromGrid(item);
3893
- }
3894
-
3895
- item.w = width;
3896
- item.h = height;
3897
-
3898
- this._markItemPositionToGrid(item);
3899
- },
3900
-
3901
- _markItemPositionToGrid: function(item) {
3902
- /**
3903
- * Mark the grid cells that are occupied by an item. This prevents items
3904
- * from overlapping in the grid
3905
- */
3906
-
3907
- var position = this._getItemPosition(item),
3908
- x, y;
3909
-
3910
- // Ensure that the grid has enough columns to accomodate the current item.
3911
- this._ensureColumns(position.x + position.w);
3912
-
3913
- for (x = position.x; x < position.x + position.w; x++) {
3914
- for (y = position.y; y < position.y + position.h; y++) {
3915
- this.grid[x][y] = item;
3916
- }
3917
- }
3918
- },
3919
-
3920
- _deleteItemPositionFromGrid: function(item) {
3921
- var position = this._getItemPosition(item),
3922
- x, y;
3923
-
3924
- for (x = position.x; x < position.x + position.w; x++) {
3925
- // It can happen to try to remove an item from a position not generated
3926
- // in the grid, probably when loading a persisted grid of items. No need
3927
- // to create a column to be able to remove something from it, though
3928
- if (!this.grid[x]) {
3929
- continue;
3930
- }
3931
-
3932
- for (y = position.y; y < position.y + position.h; y++) {
3933
- // Don't clear the cell if it's been occupied by a different widget in
3934
- // the meantime (e.g. when an item has been moved over this one, and
3935
- // thus by continuing to clear this item's previous position you would
3936
- // cancel the first item's move, leaving it without any position even)
3937
- if (this.grid[x][y] == item) {
3938
- this.grid[x][y] = null;
3939
- }
3940
- }
3941
- }
3942
- },
3943
-
3944
- _ensureColumns: function(N) {
3945
- /**
3946
- * Ensure that the grid has at least N columns available.
3947
- */
3948
- var i;
3949
- for (i = 0; i < N; i++) {
3950
- if (!this.grid[i]) {
3951
- this.grid.push(new GridCol(this._options.lanes));
3952
- }
3953
- }
3954
- },
3955
-
3956
- _getItemsCollidingWithItem: function(item) {
3957
- var collidingItems = [];
3958
- for (var i = 0; i < this.items.length; i++) {
3959
- if (item != this.items[i] &&
3960
- this._itemsAreColliding(item, this.items[i])) {
3961
- collidingItems.push(i);
3962
- }
3963
- }
3964
- return collidingItems;
3965
- },
3966
-
3967
- _itemsAreColliding: function(item1, item2) {
3968
- var position1 = this._getItemPosition(item1),
3969
- position2 = this._getItemPosition(item2);
3970
-
3971
- return !(position2.x >= position1.x + position1.w ||
3972
- position2.x + position2.w <= position1.x ||
3973
- position2.y >= position1.y + position1.h ||
3974
- position2.y + position2.h <= position1.y);
3975
- },
3976
-
3977
- _resolveCollisions: function(item) {
3978
- if (!this._tryToResolveCollisionsLocally(item)) {
3979
- this._pullItemsToLeft(item);
3980
- }
3981
- this._pullItemsToLeft();
3982
- },
3983
-
3984
- _tryToResolveCollisionsLocally: function(item) {
3985
- /**
3986
- * Attempt to resolve the collisions after moving a an item over one or more
3987
- * other items within the grid, by shifting the position of the colliding
3988
- * items around the moving one. This might result in subsequent collisions,
3989
- * in which case we will revert all position permutations. To be able to
3990
- * revert to the initial item positions, we create a virtual grid in the
3991
- * process
3992
- */
3993
- var collidingItems = this._getItemsCollidingWithItem(item);
3994
- if (!collidingItems.length) {
3995
- return true;
3996
- }
3997
- var _gridList = new GridList([], this._options),
3998
- leftOfItem,
3999
- rightOfItem,
4000
- aboveOfItem,
4001
- belowOfItem;
4002
-
4003
- GridList.cloneItems(this.items, _gridList.items);
4004
- _gridList.generateGrid();
4005
-
4006
- for (var i = 0; i < collidingItems.length; i++) {
4007
- var collidingItem = _gridList.items[collidingItems[i]],
4008
- collidingPosition = this._getItemPosition(collidingItem);
4009
-
4010
- // We use a simple algorithm for moving items around when collisions occur:
4011
- // In this prioritized order, we try to move a colliding item around the
4012
- // moving one:
4013
- // 1. to its left side
4014
- // 2. above it
4015
- // 3. under it
4016
- // 4. to its right side
4017
- var position = this._getItemPosition(item);
4018
-
4019
- leftOfItem = [position.x - collidingPosition.w, collidingPosition.y];
4020
- rightOfItem = [position.x + position.w, collidingPosition.y];
4021
- aboveOfItem = [collidingPosition.x, position.y - collidingPosition.h];
4022
- belowOfItem = [collidingPosition.x, position.y + position.h];
4023
-
4024
- if (_gridList._itemFitsAtPosition(collidingItem, leftOfItem)) {
4025
- _gridList._updateItemPosition(collidingItem, leftOfItem);
4026
- } else if (_gridList._itemFitsAtPosition(collidingItem, aboveOfItem)) {
4027
- _gridList._updateItemPosition(collidingItem, aboveOfItem);
4028
- } else if (_gridList._itemFitsAtPosition(collidingItem, belowOfItem)) {
4029
- _gridList._updateItemPosition(collidingItem, belowOfItem);
4030
- } else if (_gridList._itemFitsAtPosition(collidingItem, rightOfItem)) {
4031
- _gridList._updateItemPosition(collidingItem, rightOfItem);
4032
- } else {
4033
- // Collisions failed, we must use the pullItemsToLeft method to arrange
4034
- // the other items around this item with fixed position. This is our
4035
- // plan B for when local collision resolving fails.
4036
- return false;
4037
- }
4038
- }
4039
- // If we reached this point it means we managed to resolve the collisions
4040
- // from one single iteration, just by moving the colliding items around. So
4041
- // we accept this scenario and marge the brached-out grid instance into the
4042
- // original one
4043
- GridList.cloneItems(_gridList.items, this.items);
4044
- this.generateGrid();
4045
- return true;
4046
- },
4047
-
4048
- _pullItemsToLeft: function(fixedItem) {
4049
- /**
4050
- * Build the grid from scratch, by using the current item positions and
4051
- * pulling them as much to the left as possible, removing as space between
4052
- * them as possible.
4053
- *
4054
- * If a "fixed item" is provided, its position will be kept intact and the
4055
- * rest of the items will be layed around it.
4056
- */
4057
-
4058
-
4059
- // Start a fresh grid with the fixed item already placed inside
4060
- this._sortItemsByPosition();
4061
- this._resetGrid();
4062
-
4063
- // Start the grid with the fixed item as the first positioned item
4064
- if (fixedItem) {
4065
- var fixedPosition = this._getItemPosition(fixedItem);
4066
- this._updateItemPosition(fixedItem, [fixedPosition.x, fixedPosition.y]);
4067
- }
4068
-
4069
- for (var i = 0; i < this.items.length; i++) {
4070
- var item = this.items[i],
4071
- position = this._getItemPosition(item);
4072
-
4073
- // The fixed item keeps its exact position
4074
- if (fixedItem && item == fixedItem) {
4075
- continue;
4076
- }
4077
-
4078
- var x = this._findLeftMostPositionForItem(item),
4079
- newPosition = this.findPositionForItem(
4080
- item, {x: x, y: 0}, position.y);
4081
-
4082
- this._updateItemPosition(item, newPosition);
4083
- }
4084
- },
4085
-
4086
- _findLeftMostPositionForItem: function(item) {
4087
- /**
4088
- * When pulling items to the left, we need to find the leftmost position for
4089
- * an item, with two considerations in mind:
4090
- * - preserving its current row
4091
- * - preserving the previous horizontal order between items
4092
- */
4093
-
4094
- var tail = 0,
4095
- position = this._getItemPosition(item);
4096
-
4097
- for (var i = 0; i < this.grid.length; i++) {
4098
- for (var j = position.y; j < position.y + position.h; j++) {
4099
- var otherItem = this.grid[i][j];
4100
-
4101
- if (!otherItem) {
4102
- continue;
4103
- }
4104
-
4105
- var otherPosition = this._getItemPosition(otherItem);
4106
-
4107
- if (this.items.indexOf(otherItem) < this.items.indexOf(item)) {
4108
- tail = otherPosition.x + otherPosition.w;
4109
- }
4110
- }
4111
- }
4112
-
4113
- return tail;
4114
- },
4115
-
4116
- _getItemByAttribute: function(key, value) {
4117
- for (var i = 0; i < this.items.length; i++) {
4118
- if (this.items[i][key] === value) {
4119
- return this.items[i];
4120
- }
4121
- }
4122
- return null;
4123
- },
4124
-
4125
- _padNumber: function(nr, prefix) {
4126
- // Currently works for 2-digit numbers (<100)
4127
- return nr >= 10 ? nr : prefix + nr;
4128
- },
4129
-
4130
- _getItemPosition: function(item) {
4131
- /**
4132
- * If the direction is vertical we need to rotate the grid 90 deg to the
4133
- * left. Thus, we simulate the fact that items are being pulled to the top.
4134
- *
4135
- * Since the items have widths and heights, if we apply the classic
4136
- * counter-clockwise 90 deg rotation
4137
- *
4138
- * [0 -1]
4139
- * [1 0]
4140
- *
4141
- * then the top left point of an item will become the bottom left point of
4142
- * the rotated item. To adjust for this, we need to subtract from the y
4143
- * position the height of the original item - the width of the rotated item.
4144
- *
4145
- * However, if we do this then we'll reverse some actions: resizing the
4146
- * width of an item will stretch the item to the left instead of to the
4147
- * right; resizing an item that doesn't fit into the grid will push the
4148
- * items around it instead of going on a new row, etc.
4149
- *
4150
- * We found it better to do a vertical flip of the grid after rotating it.
4151
- * This restores the direction of the actions and greatly simplifies the
4152
- * transformations.
4153
- */
4154
-
4155
- if (this._options.direction === 'horizontal') {
4156
- return item;
4157
- } else {
4158
- return {
4159
- x: item.y,
4160
- y: item.x,
4161
- w: item.h,
4162
- h: item.w
4163
- };
4164
- }
4165
- },
4166
-
4167
- _setItemPosition: function(item, position) {
4168
- /**
4169
- * See _getItemPosition.
4170
- */
4171
-
4172
- if (this._options.direction === 'horizontal') {
4173
- item.x = position[0];
4174
- item.y = position[1];
4175
- } else {
4176
- // We're supposed to subtract the rotated item's height which is actually
4177
- // the non-rotated item's width.
4178
- item.x = position[1];
4179
- item.y = position[0];
4180
- }
4181
- }
4182
- };
4183
-
4184
- var GridCol = function(lanes) {
4185
- for (var i = 0; i < lanes; i++) {
4186
- this.push(null);
4187
- }
4188
- };
4189
-
4190
- // Extend the Array prototype
4191
- GridCol.prototype = [];
4192
-
4193
- // This module will have direct access to the GridList class
4194
- return GridList;
4195
-
4196
- }));
4197
- } (gridList$1));
4198
-
4199
- var gridListExports = gridList$1.exports;
3506
+ var gridList$2 = {exports: {}};
3507
+
3508
+ var gridList$1 = gridList$2.exports;
3509
+
3510
+ var hasRequiredGridList;
3511
+
3512
+ function requireGridList () {
3513
+ if (hasRequiredGridList) return gridList$2.exports;
3514
+ hasRequiredGridList = 1;
3515
+ (function (module, exports) {
3516
+ (function (root, factory) {
3517
+ {
3518
+ // Node. Does not work with strict CommonJS, but
3519
+ // only CommonJS-like environments that support module.exports,
3520
+ // like Node.
3521
+ module.exports = factory();
3522
+ }
3523
+ }(gridList$1, function() {
3524
+
3525
+ var GridList = function(items, options) {
3526
+ /**
3527
+ * A GridList manages the two-dimensional positions from a list of items,
3528
+ * within a virtual matrix.
3529
+ *
3530
+ * The GridList's main function is to convert the item positions from one
3531
+ * grid size to another, maintaining as much of their order as possible.
3532
+ *
3533
+ * The GridList's second function is to handle collisions when moving an item
3534
+ * over another.
3535
+ *
3536
+ * The positioning algorithm places items in columns. Starting from left to
3537
+ * right, going through each column top to bottom.
3538
+ *
3539
+ * The size of an item is expressed using the number of cols and rows it
3540
+ * takes up within the grid (w and h)
3541
+ *
3542
+ * The position of an item is express using the col and row position within
3543
+ * the grid (x and y)
3544
+ *
3545
+ * An item is an object of structure:
3546
+ * {
3547
+ * w: 3, h: 1,
3548
+ * x: 0, y: 1
3549
+ * }
3550
+ */
3551
+
3552
+ this._options = options;
3553
+ for (var k in this.defaults) {
3554
+ if (!this._options.hasOwnProperty(k)) {
3555
+ this._options[k] = this.defaults[k];
3556
+ }
3557
+ }
3558
+
3559
+ this.items = items;
3560
+
3561
+ this._adjustSizeOfItems();
3562
+
3563
+ this.generateGrid();
3564
+ };
3565
+
3566
+ GridList.cloneItems = function(items, _items) {
3567
+ /**
3568
+ * Clone items with a deep level of one. Items are not referenced but their
3569
+ * properties are
3570
+ */
3571
+ var i,
3572
+ k;
3573
+ if (_items === undefined) {
3574
+ _items = [];
3575
+ }
3576
+ for (i = 0; i < items.length; i++) {
3577
+ // XXX: this is good because we don't want to lose item reference, but
3578
+ // maybe we should clear their properties since some might be optional
3579
+ if (!_items[i]) {
3580
+ _items[i] = {};
3581
+ }
3582
+ for (k in items[i]) {
3583
+ _items[i][k] = items[i][k];
3584
+ }
3585
+ }
3586
+ return _items;
3587
+ };
3588
+
3589
+ GridList.prototype = {
3590
+
3591
+ defaults: {
3592
+ lanes: 5,
3593
+ direction: 'horizontal'
3594
+ },
3595
+
3596
+ /**
3597
+ * Illustates grid as text-based table, using a number identifier for each
3598
+ * item. E.g.
3599
+ *
3600
+ * #| 0 1 2 3 4 5 6 7 8 9 10 11 12 13
3601
+ * --------------------------------------------
3602
+ * 0| 00 02 03 04 04 06 08 08 08 12 12 13 14 16
3603
+ * 1| 01 -- 03 05 05 07 09 10 11 11 -- 13 15 --
3604
+ *
3605
+ * Warn: Does not work if items don't have a width or height specified
3606
+ * besides their position in the grid.
3607
+ */
3608
+ toString: function() {
3609
+ var widthOfGrid = this.grid.length,
3610
+ output = '\n #|',
3611
+ border = '\n --',
3612
+ item,
3613
+ i,
3614
+ j;
3615
+
3616
+ // Render the table header
3617
+ for (i = 0; i < widthOfGrid; i++) {
3618
+ output += ' ' + this._padNumber(i, ' ');
3619
+ border += '---';
3620
+ } output += border;
3621
+
3622
+ // Render table contents row by row, as we go on the y axis
3623
+ for (i = 0; i < this._options.lanes; i++) {
3624
+ output += '\n' + this._padNumber(i, ' ') + '|';
3625
+ for (j = 0; j < widthOfGrid; j++) {
3626
+ output += ' ';
3627
+ item = this.grid[j][i];
3628
+ output += item ? this._padNumber(this.items.indexOf(item), '0') : '--';
3629
+ }
3630
+ } output += '\n';
3631
+ return output;
3632
+ },
3633
+
3634
+ generateGrid: function() {
3635
+ /**
3636
+ * Build the grid structure from scratch, with the current item positions
3637
+ */
3638
+ var i;
3639
+ this._resetGrid();
3640
+ for (i = 0; i < this.items.length; i++) {
3641
+ this._markItemPositionToGrid(this.items[i]);
3642
+ }
3643
+ },
3644
+
3645
+ resizeGrid: function(lanes) {
3646
+ var currentColumn = 0;
3647
+
3648
+ this._options.lanes = lanes;
3649
+ this._adjustSizeOfItems();
3650
+
3651
+ this._sortItemsByPosition();
3652
+ this._resetGrid();
3653
+
3654
+ // The items will be sorted based on their index within the this.items array,
3655
+ // that is their "1d position"
3656
+ for (var i = 0; i < this.items.length; i++) {
3657
+ var item = this.items[i],
3658
+ position = this._getItemPosition(item);
3659
+
3660
+ this._updateItemPosition(
3661
+ item, this.findPositionForItem(item, {x: currentColumn, y: 0}));
3662
+
3663
+ // New items should never be placed to the left of previous items
3664
+ currentColumn = Math.max(currentColumn, position.x);
3665
+ }
3666
+
3667
+ this._pullItemsToLeft();
3668
+ },
3669
+
3670
+ findPositionForItem: function(item, start, fixedRow) {
3671
+ /**
3672
+ * This method has two options for the position we want for the item:
3673
+ * - Starting from a certain row/column number and only looking for
3674
+ * positions to its right
3675
+ * - Accepting positions for a certain row number only (use-case: items
3676
+ * being shifted to the left/right as a result of collisions)
3677
+ *
3678
+ * @param {Object<x:Number, y:Number, w:Number, h:Number} item
3679
+ * @param {Object<x:Number, y:Number} start Position from which to start
3680
+ * the search.
3681
+ * @param {Number} [fixedRow] If provided, we're going to try to find a
3682
+ * position for the new item on it. If doesn't fit there, we're going
3683
+ * to put it on the first row.
3684
+ *
3685
+ * @returns {Number[2]} x and y.
3686
+ */
3687
+
3688
+ var x, y, position;
3689
+
3690
+ // Start searching for a position from the horizontal position of the
3691
+ // rightmost item from the grid
3692
+ for (x = start.x; x < this.grid.length; x++) {
3693
+ if (fixedRow !== undefined) {
3694
+ position = [x, fixedRow];
3695
+
3696
+ if (this._itemFitsAtPosition(item, position)) {
3697
+ return position;
3698
+ }
3699
+ } else {
3700
+ for (y = start.y; y < this._options.lanes; y++) {
3701
+ position = [x, y];
3702
+
3703
+ if (this._itemFitsAtPosition(item, position)) {
3704
+ return position;
3705
+ }
3706
+ }
3707
+ }
3708
+ }
3709
+
3710
+ // If we've reached this point, we need to start a new column
3711
+ var newCol = this.grid.length,
3712
+ newRow = 0;
3713
+
3714
+ if (fixedRow !== undefined &&
3715
+ this._itemFitsAtPosition(item, [newCol, fixedRow])) {
3716
+ newRow = fixedRow;
3717
+ }
3718
+
3719
+ return [newCol, newRow];
3720
+ },
3721
+
3722
+ moveItemToPosition: function(item, newPosition) {
3723
+ var position = this._getItemPosition({
3724
+ x: newPosition[0],
3725
+ y: newPosition[1],
3726
+ w: item.w,
3727
+ h: item.h
3728
+ });
3729
+
3730
+ this._updateItemPosition(item, [position.x, position.y]);
3731
+ this._resolveCollisions(item);
3732
+ },
3733
+
3734
+ resizeItem: function(item, size) {
3735
+ /**
3736
+ * Resize an item and resolve collisions.
3737
+ *
3738
+ * @param {Object} item A reference to an item that's part of the grid.
3739
+ * @param {Object} size
3740
+ * @param {Number} [size.w=item.w] The new width.
3741
+ * @param {Number} [size.h=item.h] The new height.
3742
+ */
3743
+
3744
+ var width = size.w || item.w,
3745
+ height = size.h || item.h;
3746
+
3747
+ this._updateItemSize(item, width, height);
3748
+
3749
+ this._resolveCollisions(item);
3750
+
3751
+ this._pullItemsToLeft();
3752
+ },
3753
+
3754
+ getChangedItems: function(initialItems, idAttribute) {
3755
+ /**
3756
+ * Compare the current items against a previous snapshot and return only
3757
+ * the ones that changed their attributes in the meantime. This includes both
3758
+ * position (x, y) and size (w, h)
3759
+ *
3760
+ * Since both their position and size can change, the items need an
3761
+ * additional identifier attribute to match them with their previous state
3762
+ */
3763
+ var changedItems = [];
3764
+
3765
+ for (var i = 0; i < initialItems.length; i++) {
3766
+ var item = this._getItemByAttribute(idAttribute,
3767
+ initialItems[i][idAttribute]);
3768
+
3769
+ if (item.x !== initialItems[i].x ||
3770
+ item.y !== initialItems[i].y ||
3771
+ item.w !== initialItems[i].w ||
3772
+ item.h !== initialItems[i].h) {
3773
+ changedItems.push(item);
3774
+ }
3775
+ }
3776
+
3777
+ return changedItems;
3778
+ },
3779
+
3780
+ _sortItemsByPosition: function() {
3781
+ this.items.sort(function(item1, item2) {
3782
+ var position1 = this._getItemPosition(item1),
3783
+ position2 = this._getItemPosition(item2);
3784
+
3785
+ // Try to preserve columns.
3786
+ if (position1.x != position2.x) {
3787
+ return position1.x - position2.x;
3788
+ }
3789
+
3790
+ if (position1.y != position2.y) {
3791
+ return position1.y - position2.y;
3792
+ }
3793
+
3794
+ // The items are placed on the same position.
3795
+ return 0;
3796
+ }.bind(this));
3797
+ },
3798
+
3799
+ _adjustSizeOfItems: function() {
3800
+ /**
3801
+ * Some items can have 100% height or 100% width. Those dimmensions are
3802
+ * expressed as 0. We need to ensure a valid width and height for each of
3803
+ * those items as the number of items per lane.
3804
+ */
3805
+
3806
+ for (var i = 0; i < this.items.length; i++) {
3807
+ var item = this.items[i];
3808
+
3809
+ // This can happen only the first time items are checked.
3810
+ // We need the property to have a value for all the items so that the
3811
+ // `cloneItems` method will merge the properties properly. If we only set
3812
+ // it to the items that need it then the following can happen:
3813
+ //
3814
+ // cloneItems([{id: 1, autoSize: true}, {id: 2}],
3815
+ // [{id: 2}, {id: 1, autoSize: true}]);
3816
+ //
3817
+ // will result in
3818
+ //
3819
+ // [{id: 1, autoSize: true}, {id: 2, autoSize: true}]
3820
+ if (item.autoSize === undefined) {
3821
+ item.autoSize = item.w === 0 || item.h === 0;
3822
+ }
3823
+
3824
+ if (item.autoSize) {
3825
+ if (this._options.direction === 'horizontal') {
3826
+ item.h = this._options.lanes;
3827
+ } else {
3828
+ item.w = this._options.lanes;
3829
+ }
3830
+ }
3831
+ }
3832
+ },
3833
+
3834
+ _resetGrid: function() {
3835
+ this.grid = [];
3836
+ },
3837
+
3838
+ _itemFitsAtPosition: function(item, newPosition) {
3839
+ /**
3840
+ * Check that an item wouldn't overlap with another one if placed at a
3841
+ * certain position within the grid
3842
+ */
3843
+
3844
+ var position = this._getItemPosition(item),
3845
+ x, y;
3846
+
3847
+ // No coordonate can be negative
3848
+ if (newPosition[0] < 0 || newPosition[1] < 0) {
3849
+ return false;
3850
+ }
3851
+
3852
+ // Make sure the item isn't larger than the entire grid
3853
+ if (newPosition[1] + position.h > this._options.lanes) {
3854
+ return false;
3855
+ }
3856
+
3857
+ // Make sure the position doesn't overlap with an already positioned
3858
+ // item.
3859
+ for (x = newPosition[0]; x < newPosition[0] + position.w; x++) {
3860
+ var col = this.grid[x];
3861
+
3862
+ // Surely a column that hasn't even been created yet is available
3863
+ if (!col) {
3864
+ continue;
3865
+ }
3866
+
3867
+ for (y = newPosition[1]; y < newPosition[1] + position.h; y++) {
3868
+ // Any space occupied by an item can continue to be occupied by the
3869
+ // same item.
3870
+ if (col[y] && col[y] !== item) {
3871
+ return false;
3872
+ }
3873
+ }
3874
+ }
3875
+
3876
+ return true;
3877
+ },
3878
+
3879
+ _updateItemPosition: function(item, position) {
3880
+ if (item.x !== null && item.y !== null) {
3881
+ this._deleteItemPositionFromGrid(item);
3882
+ }
3883
+
3884
+ this._setItemPosition(item, position);
3885
+
3886
+ this._markItemPositionToGrid(item);
3887
+ },
3888
+
3889
+ _updateItemSize: function(item, width, height) {
3890
+ /**
3891
+ * @param {Object} item A reference to a grid item.
3892
+ * @param {Number} width The new width.
3893
+ * @param {Number} height The new height.
3894
+ */
3895
+
3896
+ if (item.x !== null && item.y !== null) {
3897
+ this._deleteItemPositionFromGrid(item);
3898
+ }
3899
+
3900
+ item.w = width;
3901
+ item.h = height;
3902
+
3903
+ this._markItemPositionToGrid(item);
3904
+ },
3905
+
3906
+ _markItemPositionToGrid: function(item) {
3907
+ /**
3908
+ * Mark the grid cells that are occupied by an item. This prevents items
3909
+ * from overlapping in the grid
3910
+ */
3911
+
3912
+ var position = this._getItemPosition(item),
3913
+ x, y;
3914
+
3915
+ // Ensure that the grid has enough columns to accomodate the current item.
3916
+ this._ensureColumns(position.x + position.w);
3917
+
3918
+ for (x = position.x; x < position.x + position.w; x++) {
3919
+ for (y = position.y; y < position.y + position.h; y++) {
3920
+ this.grid[x][y] = item;
3921
+ }
3922
+ }
3923
+ },
3924
+
3925
+ _deleteItemPositionFromGrid: function(item) {
3926
+ var position = this._getItemPosition(item),
3927
+ x, y;
3928
+
3929
+ for (x = position.x; x < position.x + position.w; x++) {
3930
+ // It can happen to try to remove an item from a position not generated
3931
+ // in the grid, probably when loading a persisted grid of items. No need
3932
+ // to create a column to be able to remove something from it, though
3933
+ if (!this.grid[x]) {
3934
+ continue;
3935
+ }
3936
+
3937
+ for (y = position.y; y < position.y + position.h; y++) {
3938
+ // Don't clear the cell if it's been occupied by a different widget in
3939
+ // the meantime (e.g. when an item has been moved over this one, and
3940
+ // thus by continuing to clear this item's previous position you would
3941
+ // cancel the first item's move, leaving it without any position even)
3942
+ if (this.grid[x][y] == item) {
3943
+ this.grid[x][y] = null;
3944
+ }
3945
+ }
3946
+ }
3947
+ },
3948
+
3949
+ _ensureColumns: function(N) {
3950
+ /**
3951
+ * Ensure that the grid has at least N columns available.
3952
+ */
3953
+ var i;
3954
+ for (i = 0; i < N; i++) {
3955
+ if (!this.grid[i]) {
3956
+ this.grid.push(new GridCol(this._options.lanes));
3957
+ }
3958
+ }
3959
+ },
3960
+
3961
+ _getItemsCollidingWithItem: function(item) {
3962
+ var collidingItems = [];
3963
+ for (var i = 0; i < this.items.length; i++) {
3964
+ if (item != this.items[i] &&
3965
+ this._itemsAreColliding(item, this.items[i])) {
3966
+ collidingItems.push(i);
3967
+ }
3968
+ }
3969
+ return collidingItems;
3970
+ },
3971
+
3972
+ _itemsAreColliding: function(item1, item2) {
3973
+ var position1 = this._getItemPosition(item1),
3974
+ position2 = this._getItemPosition(item2);
3975
+
3976
+ return !(position2.x >= position1.x + position1.w ||
3977
+ position2.x + position2.w <= position1.x ||
3978
+ position2.y >= position1.y + position1.h ||
3979
+ position2.y + position2.h <= position1.y);
3980
+ },
3981
+
3982
+ _resolveCollisions: function(item) {
3983
+ if (!this._tryToResolveCollisionsLocally(item)) {
3984
+ this._pullItemsToLeft(item);
3985
+ }
3986
+ this._pullItemsToLeft();
3987
+ },
3988
+
3989
+ _tryToResolveCollisionsLocally: function(item) {
3990
+ /**
3991
+ * Attempt to resolve the collisions after moving a an item over one or more
3992
+ * other items within the grid, by shifting the position of the colliding
3993
+ * items around the moving one. This might result in subsequent collisions,
3994
+ * in which case we will revert all position permutations. To be able to
3995
+ * revert to the initial item positions, we create a virtual grid in the
3996
+ * process
3997
+ */
3998
+ var collidingItems = this._getItemsCollidingWithItem(item);
3999
+ if (!collidingItems.length) {
4000
+ return true;
4001
+ }
4002
+ var _gridList = new GridList([], this._options),
4003
+ leftOfItem,
4004
+ rightOfItem,
4005
+ aboveOfItem,
4006
+ belowOfItem;
4007
+
4008
+ GridList.cloneItems(this.items, _gridList.items);
4009
+ _gridList.generateGrid();
4010
+
4011
+ for (var i = 0; i < collidingItems.length; i++) {
4012
+ var collidingItem = _gridList.items[collidingItems[i]],
4013
+ collidingPosition = this._getItemPosition(collidingItem);
4014
+
4015
+ // We use a simple algorithm for moving items around when collisions occur:
4016
+ // In this prioritized order, we try to move a colliding item around the
4017
+ // moving one:
4018
+ // 1. to its left side
4019
+ // 2. above it
4020
+ // 3. under it
4021
+ // 4. to its right side
4022
+ var position = this._getItemPosition(item);
4023
+
4024
+ leftOfItem = [position.x - collidingPosition.w, collidingPosition.y];
4025
+ rightOfItem = [position.x + position.w, collidingPosition.y];
4026
+ aboveOfItem = [collidingPosition.x, position.y - collidingPosition.h];
4027
+ belowOfItem = [collidingPosition.x, position.y + position.h];
4028
+
4029
+ if (_gridList._itemFitsAtPosition(collidingItem, leftOfItem)) {
4030
+ _gridList._updateItemPosition(collidingItem, leftOfItem);
4031
+ } else if (_gridList._itemFitsAtPosition(collidingItem, aboveOfItem)) {
4032
+ _gridList._updateItemPosition(collidingItem, aboveOfItem);
4033
+ } else if (_gridList._itemFitsAtPosition(collidingItem, belowOfItem)) {
4034
+ _gridList._updateItemPosition(collidingItem, belowOfItem);
4035
+ } else if (_gridList._itemFitsAtPosition(collidingItem, rightOfItem)) {
4036
+ _gridList._updateItemPosition(collidingItem, rightOfItem);
4037
+ } else {
4038
+ // Collisions failed, we must use the pullItemsToLeft method to arrange
4039
+ // the other items around this item with fixed position. This is our
4040
+ // plan B for when local collision resolving fails.
4041
+ return false;
4042
+ }
4043
+ }
4044
+ // If we reached this point it means we managed to resolve the collisions
4045
+ // from one single iteration, just by moving the colliding items around. So
4046
+ // we accept this scenario and marge the brached-out grid instance into the
4047
+ // original one
4048
+ GridList.cloneItems(_gridList.items, this.items);
4049
+ this.generateGrid();
4050
+ return true;
4051
+ },
4052
+
4053
+ _pullItemsToLeft: function(fixedItem) {
4054
+ /**
4055
+ * Build the grid from scratch, by using the current item positions and
4056
+ * pulling them as much to the left as possible, removing as space between
4057
+ * them as possible.
4058
+ *
4059
+ * If a "fixed item" is provided, its position will be kept intact and the
4060
+ * rest of the items will be layed around it.
4061
+ */
4062
+
4063
+
4064
+ // Start a fresh grid with the fixed item already placed inside
4065
+ this._sortItemsByPosition();
4066
+ this._resetGrid();
4067
+
4068
+ // Start the grid with the fixed item as the first positioned item
4069
+ if (fixedItem) {
4070
+ var fixedPosition = this._getItemPosition(fixedItem);
4071
+ this._updateItemPosition(fixedItem, [fixedPosition.x, fixedPosition.y]);
4072
+ }
4073
+
4074
+ for (var i = 0; i < this.items.length; i++) {
4075
+ var item = this.items[i],
4076
+ position = this._getItemPosition(item);
4077
+
4078
+ // The fixed item keeps its exact position
4079
+ if (fixedItem && item == fixedItem) {
4080
+ continue;
4081
+ }
4082
+
4083
+ var x = this._findLeftMostPositionForItem(item),
4084
+ newPosition = this.findPositionForItem(
4085
+ item, {x: x, y: 0}, position.y);
4086
+
4087
+ this._updateItemPosition(item, newPosition);
4088
+ }
4089
+ },
4090
+
4091
+ _findLeftMostPositionForItem: function(item) {
4092
+ /**
4093
+ * When pulling items to the left, we need to find the leftmost position for
4094
+ * an item, with two considerations in mind:
4095
+ * - preserving its current row
4096
+ * - preserving the previous horizontal order between items
4097
+ */
4098
+
4099
+ var tail = 0,
4100
+ position = this._getItemPosition(item);
4101
+
4102
+ for (var i = 0; i < this.grid.length; i++) {
4103
+ for (var j = position.y; j < position.y + position.h; j++) {
4104
+ var otherItem = this.grid[i][j];
4105
+
4106
+ if (!otherItem) {
4107
+ continue;
4108
+ }
4109
+
4110
+ var otherPosition = this._getItemPosition(otherItem);
4111
+
4112
+ if (this.items.indexOf(otherItem) < this.items.indexOf(item)) {
4113
+ tail = otherPosition.x + otherPosition.w;
4114
+ }
4115
+ }
4116
+ }
4117
+
4118
+ return tail;
4119
+ },
4120
+
4121
+ _getItemByAttribute: function(key, value) {
4122
+ for (var i = 0; i < this.items.length; i++) {
4123
+ if (this.items[i][key] === value) {
4124
+ return this.items[i];
4125
+ }
4126
+ }
4127
+ return null;
4128
+ },
4129
+
4130
+ _padNumber: function(nr, prefix) {
4131
+ // Currently works for 2-digit numbers (<100)
4132
+ return nr >= 10 ? nr : prefix + nr;
4133
+ },
4134
+
4135
+ _getItemPosition: function(item) {
4136
+ /**
4137
+ * If the direction is vertical we need to rotate the grid 90 deg to the
4138
+ * left. Thus, we simulate the fact that items are being pulled to the top.
4139
+ *
4140
+ * Since the items have widths and heights, if we apply the classic
4141
+ * counter-clockwise 90 deg rotation
4142
+ *
4143
+ * [0 -1]
4144
+ * [1 0]
4145
+ *
4146
+ * then the top left point of an item will become the bottom left point of
4147
+ * the rotated item. To adjust for this, we need to subtract from the y
4148
+ * position the height of the original item - the width of the rotated item.
4149
+ *
4150
+ * However, if we do this then we'll reverse some actions: resizing the
4151
+ * width of an item will stretch the item to the left instead of to the
4152
+ * right; resizing an item that doesn't fit into the grid will push the
4153
+ * items around it instead of going on a new row, etc.
4154
+ *
4155
+ * We found it better to do a vertical flip of the grid after rotating it.
4156
+ * This restores the direction of the actions and greatly simplifies the
4157
+ * transformations.
4158
+ */
4159
+
4160
+ if (this._options.direction === 'horizontal') {
4161
+ return item;
4162
+ } else {
4163
+ return {
4164
+ x: item.y,
4165
+ y: item.x,
4166
+ w: item.h,
4167
+ h: item.w
4168
+ };
4169
+ }
4170
+ },
4171
+
4172
+ _setItemPosition: function(item, position) {
4173
+ /**
4174
+ * See _getItemPosition.
4175
+ */
4176
+
4177
+ if (this._options.direction === 'horizontal') {
4178
+ item.x = position[0];
4179
+ item.y = position[1];
4180
+ } else {
4181
+ // We're supposed to subtract the rotated item's height which is actually
4182
+ // the non-rotated item's width.
4183
+ item.x = position[1];
4184
+ item.y = position[0];
4185
+ }
4186
+ }
4187
+ };
4188
+
4189
+ var GridCol = function(lanes) {
4190
+ for (var i = 0; i < lanes; i++) {
4191
+ this.push(null);
4192
+ }
4193
+ };
4194
+
4195
+ // Extend the Array prototype
4196
+ GridCol.prototype = [];
4197
+
4198
+ // This module will have direct access to the GridList class
4199
+ return GridList;
4200
+
4201
+ }));
4202
+ } (gridList$2));
4203
+ return gridList$2.exports;
4204
+ }
4205
+
4206
+ var gridListExports = requireGridList();
4200
4207
  var gridList = /*@__PURE__*/getDefaultExportFromCjs(gridListExports);
4201
4208
 
4202
4209
  var _GridList = /*#__PURE__*/_mergeNamespaces({