diff --git a/src/ui-layout.js b/src/ui-layout.js
index 0a2a5a9..63b913d 100644
--- a/src/ui-layout.js
+++ b/src/ui-layout.js
@@ -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;
@@ -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;
@@ -161,6 +170,26 @@ 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() {
+ ctrl.containers.forEach(function(c, i) {
+ c.storageId = ctrl.id + ':' + i;
+ });
+ }
+
//================================================================================
// Public Controller Functions
//================================================================================
@@ -248,7 +277,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;
@@ -363,6 +392,9 @@ angular.module('ui.layout', [])
container.index = index;
ctrl.containers.splice(index, 0, container);
+ updateContainerStorageIds();
+ loadContainerState(container);
+
ctrl.calculate();
};
@@ -396,6 +428,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!");
@@ -903,7 +936,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);
diff --git a/test/layout-scenar.spec.js b/test/layout-scenar.spec.js
index a545d67..8f33906 100644
--- a/test/layout-scenar.spec.js
+++ b/test/layout-scenar.spec.js
@@ -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 = '
',
defaultDividerSize = 10;
@@ -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 () {
@@ -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();
@@ -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 () {
@@ -95,7 +104,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 follow the ' + description, function () {
@@ -103,8 +112,9 @@ function splitMoveTests(description, startEvent, moveEvent, endEvent) {
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);
});
@@ -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 () {
@@ -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() {
diff --git a/test/uiLayoutContainer.spec.js b/test/uiLayoutContainer.spec.js
index ade2406..5953bd0 100644
--- a/test/uiLayoutContainer.spec.js
+++ b/test/uiLayoutContainer.spec.js
@@ -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();
+
});
});
\ No newline at end of file