Skip to content
This repository has been archived by the owner on Sep 8, 2020. It is now read-only.

Persistent State #164

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 36 additions & 3 deletions src/ui-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ angular.module('ui.layout', [])
var sizePattern = /\d+\s*(px|%)\s*$/i;

Layout.addLayout(ctrl);
if ($attrs.layoutId) {
ctrl.id = $attrs.layoutId;
}

ctrl.containers = [];
ctrl.movingSplitbar = null;
Expand Down Expand Up @@ -83,7 +86,7 @@ angular.module('ui.layout', [])
if(!beforeContainer.collapsed && !afterContainer.collapsed) {
// calculate container positons
var difference = ctrl.movingSplitbar[position] - lastPos;
var newPosition = ctrl.movingSplitbar[position] - difference;
var newPosition = ctrl.movingSplitbar[position] - difference; // TODO: this computation is unnecessary, newPosition === lastPos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open an issue for this instead of // TODO


// Keep the bar in the window (no left/top 100%)
newPosition = Math.min(elementSize-dividerSize, newPosition);
Expand Down Expand Up @@ -120,6 +123,12 @@ angular.module('ui.layout', [])
afterContainer.uncollapsedSize = afterContainer.size;
}

// store the current value in local storage to preserve size also when reloading the window
if($window.localStorage !== undefined) {
$window.localStorage.setItem(beforeContainer.storageId, beforeContainer.uncollapsedSize + 'px');
$window.localStorage.setItem(afterContainer.storageId, afterContainer.uncollapsedSize + 'px');
}

// move the splitbar
ctrl.movingSplitbar[position] = newPosition;

Expand Down Expand Up @@ -161,6 +170,27 @@ angular.module('ui.layout', [])
}
}

function loadContainerState(container) {
// load uncollapsedSize from local storage if available:
container.uncollapsedSize = null;
if($window.localStorage !== undefined) {
container.uncollapsedSize = $window.localStorage.getItem(container.storageId);
}
if(container.uncollapsedSize === null) {
container.uncollapsedSize = container.size;
}
}

/**
* Updates the storage ids of all containers according to the id of this controller and the index of the container.
*/
function updateContainerStorageIds() {
for (var i = 0; i < ctrl.containers.length; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason for a for loop instead of Array.prototype.forEach ?

var c = ctrl.containers[i];
c.storageId = ctrl.id + ':' + i;
}
}

//================================================================================
// Public Controller Functions
//================================================================================
Expand Down Expand Up @@ -248,7 +278,7 @@ angular.module('ui.layout', [])
};

/**
* Sets the default size for each container.
* Sets the default size and position (left, top) for each container.
*/
ctrl.calculate = function() {
var c, i;
Expand Down Expand Up @@ -363,6 +393,9 @@ angular.module('ui.layout', [])
container.index = index;
ctrl.containers.splice(index, 0, container);

updateContainerStorageIds();
loadContainerState(container);

ctrl.calculate();
};

Expand Down Expand Up @@ -396,6 +429,7 @@ angular.module('ui.layout', [])
if(newIndex >= 0) {
ctrl.containers.splice(newIndex, 1);
}
updateContainerStorageIds();
ctrl.calculate();
} else {
console.error("removeContainer for container that did not exist!");
Expand Down Expand Up @@ -903,7 +937,6 @@ angular.module('ui.layout', [])
scope.container.resizable = scope.resizable;
}
scope.container.size = scope.size;
scope.container.uncollapsedSize = scope.size;
scope.container.minSize = scope.minSize;
scope.container.maxSize = scope.maxSize;
ctrl.addContainer(scope.container);
Expand Down
69 changes: 60 additions & 9 deletions test/layout-scenar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ splitMoveTests('mouse', 'mousedown', 'mousemove', 'mouseup');

// Wrapper to abstract over using touch events or mouse events.
function splitMoveTests(description, startEvent, moveEvent, endEvent) {
return describe('Directive: uiLayout with ' + description + ' events', function () {
var element, scope, compile, $timeout,
return describe('Directive: uiLayout with ' + description + ' events', function() {
var element, scope, compile, $timeout, $window,
validTemplate = '<div ui-layout><header ui-layout-container></header><footer ui-layout-container></footer></div>',
defaultDividerSize = 10;

Expand All @@ -29,15 +29,23 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {

module('ui.layout');

inject(function ($rootScope, $compile, _$timeout_) {
inject(function($rootScope, $compile, _$timeout_, _$window_) {
scope = $rootScope.$new();
compile = $compile;
$timeout = _$timeout_;
$window = _$window_;
});
});

beforeEach(function() {
// clear local storage:
if($window.localStorage !== undefined) {
$window.localStorage.clear();
}
});

afterEach(function () {
if (element) element.remove();
if(element) element.remove();
});

describe('require', function () {
Expand All @@ -62,12 +70,13 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {

describe('the slider', function () {

var element_bb, $splitbar, splitbar_bb, splitbarLeftPos;
var element_bb, leftContainer, $splitbar, splitbar_bb, splitbarLeftPos;

beforeEach(function () {
element = createDirective();

element_bb = element[0].getBoundingClientRect();
leftContainer = angular.element(_jQuery(element[0]).find('header')[0]).isolateScope();
$splitbar = _jQuery(element[0]).find('.ui-splitbar');
splitbar_bb = $splitbar[0].getBoundingClientRect();

Expand All @@ -83,7 +92,7 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {

expect(window.requestAnimationFrame).not.toHaveBeenCalled();
expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos);

expect($window.localStorage.getItem(leftContainer.container.storageId)).toBeNull();
});

it('should do nothing when moving around it', function () {
Expand All @@ -95,16 +104,17 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {

expect(window.requestAnimationFrame).not.toHaveBeenCalled();
expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos);

expect($window.localStorage.getItem(leftContainer.container.storageId)).toBeNull();
});

it('should follow the ' + description, function () {
browserTrigger($splitbar, startEvent, { y: splitbarLeftPos });
browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4});
expect(window.requestAnimationFrame).toHaveBeenCalled();

var expextedPos = Math.floor(element_bb.height / 4);
expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expextedPos);
var expectedPos = Math.floor(element_bb.height / 4);
expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos);
expect($window.localStorage.getItem(leftContainer.container.storageId)).toEqual(expectedPos + 'px');

browserTrigger(document.body, endEvent);
});
Expand All @@ -119,6 +129,7 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {
expect(window.requestAnimationFrame).not.toHaveBeenCalled();

expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos);
expect($window.localStorage.getItem(leftContainer.container.storageId)).toBeNull();
});

it('should not follow the ' + description + ' after ' + startEvent, function () {
Expand All @@ -134,6 +145,46 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {
var expectedPos = Math.floor(element_bb.height / 4);
expect(window.requestAnimationFrame.calls.count()).toEqual(1);
expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos);
expect($window.localStorage.getItem(leftContainer.container.storageId)).toEqual(expectedPos + 'px');
});

describe('persistent state', function() {

var leftContainerElement, rightContainerElement, $splitbar, splitbar_bb, splitbarLeftPos;

beforeEach(function() {
leftContainerElement = _jQuery(element[0]).find('header')[0];
rightContainerElement = _jQuery(element[0]).find('footer')[0];
$splitbar = _jQuery(element[0]).find('.ui-splitbar');
splitbar_bb = $splitbar[0].getBoundingClientRect();

splitbarLeftPos = Math.ceil(splitbar_bb.left);
});

it('should initially respect size from attributes', function() {
expect(leftContainerElement.style.width).toEqual('');
expect(rightContainerElement.style.width).toEqual('');
});

it('should save the saved splitbar position', function() {
browserTrigger($splitbar, 'mousedown', { y: splitbarLeftPos });
browserTrigger($splitbar, 'mousemove', { y: 150 });
expect(window.requestAnimationFrame).toHaveBeenCalled();

var expectedPos = Math.floor(150);
expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos);
expect($window.localStorage.getItem(leftContainer.container.storageId)).toEqual(expectedPos + 'px');

browserTrigger(document.body, 'mouseup');

if(element) element.remove();
element = createDirective();

splitbar_bb = $splitbar[0].getBoundingClientRect();
splitbarLeftPos = Math.ceil(splitbar_bb.left);
expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos);
});

});

describe('collapse buttons', function() {
Expand Down
3 changes: 3 additions & 0 deletions test/uiLayoutContainer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ describe('Directive: uiLayoutContainer', function () {
expect(acScope.container.minSize).toBeNull();
expect(acScope.container.maxSize).toBeNull();

// every container has a storageId:
expect(acScope.container.storageId).not.toBeNull();

});

});