From 2d48e189319933a0a52437a847641231101faf3a Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Wed, 9 Dec 2015 16:22:41 +0100 Subject: [PATCH 1/4] refactor(rtlSupport): removed depencency of container position on flowProperty --- src/ui-layout.js | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index f4ff7b3..c0cf836 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -67,7 +67,6 @@ angular.module('ui.layout', []) var debounceEvent; function draw() { - var position = ctrl.sizeProperties.flowProperty; var dividerSize = parseInt(opts.dividerSize); var elementSize = $element[0][ctrl.sizeProperties.offsetSize]; @@ -82,8 +81,8 @@ 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 difference = ctrl.movingSplitbar.position - lastPos; + var newPosition = ctrl.movingSplitbar.position - difference; // Keep the bar in the window (no left/top 100%) newPosition = Math.min(elementSize-dividerSize, newPosition); @@ -103,16 +102,16 @@ angular.module('ui.layout', []) newPosition = afterContainer.afterMaxValue; // resize the before container - beforeContainer.size = newPosition - beforeContainer[position]; + beforeContainer.size = newPosition - beforeContainer.position; // store the current value to preserve this size during onResize beforeContainer.uncollapsedSize = beforeContainer.size; // update after container position - var oldAfterContainerPosition = afterContainer[position]; - afterContainer[position] = newPosition + dividerSize; + var oldAfterContainerPosition = afterContainer.position; + afterContainer.position = newPosition + dividerSize; //update after container size if the position has changed - if(afterContainer[position] != oldAfterContainerPosition) { + if(afterContainer.position != oldAfterContainerPosition) { afterContainer.size = (nextSplitbarIndex !== null) ? (oldAfterContainerPosition + afterContainer.size) - (newPosition + dividerSize) : elementSize - (newPosition + dividerSize); @@ -121,7 +120,7 @@ angular.module('ui.layout', []) } // move the splitbar - ctrl.movingSplitbar[position] = newPosition; + ctrl.movingSplitbar.position = newPosition; // broadcast an event that resize happened (debounced to 50ms) if(debounceEvent) $timeout.cancel(debounceEvent); @@ -201,8 +200,8 @@ angular.module('ui.layout', []) var index = ctrl.containers.indexOf(container); var setValues = function(container) { - var start = container[ctrl.sizeProperties.flowProperty]; - var end = container[ctrl.sizeProperties.flowProperty] + container.size; + var start = container.position; + var end = container.position + container.size; container.beforeMinValue = angular.isNumber(container.minSize) ? start + container.minSize : start; container.beforeMaxValue = angular.isNumber(container.maxSize) ? start + container.maxSize : null; @@ -317,7 +316,7 @@ angular.module('ui.layout', []) remainder = availableSize - autoSize * numOfAutoContainers; for(i=0; i < ctrl.containers.length; i++) { c = ctrl.containers[i]; - c[ctrl.sizeProperties.flowProperty] = usedSpace; + c.position = usedSpace; c.maxSize = opts.maxSizes[i]; c.minSize = opts.minSizes[i]; @@ -458,18 +457,18 @@ angular.module('ui.layout', []) c.size = 0; - if(nextSplitbar) nextSplitbar[ctrl.sizeProperties.flowProperty] -= c.uncollapsedSize; + if(nextSplitbar) nextSplitbar.position -= c.uncollapsedSize; if(nextContainer) { - nextContainer[ctrl.sizeProperties.flowProperty] -= c.uncollapsedSize; + nextContainer.position -= c.uncollapsedSize; nextContainer.uncollapsedSize += c.uncollapsedSize; } } else { c.size = c.uncollapsedSize; - if(nextSplitbar) nextSplitbar[ctrl.sizeProperties.flowProperty] += c.uncollapsedSize; + if(nextSplitbar) nextSplitbar.position += c.uncollapsedSize; if(nextContainer) { - nextContainer[ctrl.sizeProperties.flowProperty] += c.uncollapsedSize; + nextContainer.position += c.uncollapsedSize; nextContainer.uncollapsedSize -= c.uncollapsedSize; } } @@ -493,7 +492,6 @@ angular.module('ui.layout', []) var prevContainer = ctrl.containers[index-2]; var isLastContainer = index === (ctrl.containers.length - 1); var endDiff; - var flowProperty = ctrl.sizeProperties.flowProperty; var sizeProperty = ctrl.sizeProperties.sizeProperty; ctrl.bounds = $element[0].getBoundingClientRect(); @@ -517,10 +515,10 @@ angular.module('ui.layout', []) // adds additional space so the splitbar moves to the very end of the container // to offset the lost space when converting from percents to pixels - endDiff = (isLastContainer) ? ctrl.bounds[sizeProperty] - c[flowProperty] - c.uncollapsedSize : 0; + endDiff = (isLastContainer) ? ctrl.bounds[sizeProperty] - c.position - c.uncollapsedSize : 0; if(prevSplitbar) { - prevSplitbar[flowProperty] += (c.uncollapsedSize + endDiff); + prevSplitbar.position += (c.uncollapsedSize + endDiff); } if(prevContainer) { prevContainer.size += (c.uncollapsedSize + endDiff); @@ -531,10 +529,10 @@ angular.module('ui.layout', []) // adds additional space so the splitbar moves back to the proper position // to offset the additional space added when collapsing - endDiff = (isLastContainer) ? ctrl.bounds[sizeProperty] - c[flowProperty] - c.uncollapsedSize : 0; + endDiff = (isLastContainer) ? ctrl.bounds[sizeProperty] - c.position - c.uncollapsedSize : 0; if(prevSplitbar) { - prevSplitbar[flowProperty] -= (c.uncollapsedSize + endDiff); + prevSplitbar.position -= (c.uncollapsedSize + endDiff); } if(prevContainer) { prevContainer.size -= (c.uncollapsedSize + endDiff); @@ -849,7 +847,7 @@ angular.module('ui.layout', []) element.css(ctrl.sizeProperties.sizeProperty, newValue + 'px'); }); - scope.$watch('splitbar.' + ctrl.sizeProperties.flowProperty, function(newValue) { + scope.$watch('splitbar.position', function(newValue) { element.css(ctrl.sizeProperties.flowProperty, newValue + 'px'); }); @@ -938,7 +936,7 @@ angular.module('ui.layout', []) } }); - scope.$watch('container.' + ctrl.sizeProperties.flowProperty, function(newValue) { + scope.$watch('container.position', function(newValue) { element.css(ctrl.sizeProperties.flowProperty, newValue + 'px'); }); @@ -1094,8 +1092,7 @@ angular.module('ui.layout', []) // Splitbar container function SplitbarContainer() { this.size = 10; - this.left = 0; - this.top = 0; + this.position = 0; this.element = null; } From 14b1425d9fc27ab89cb2e226044efcb2749a20e7 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Wed, 9 Dec 2015 16:23:13 +0100 Subject: [PATCH 2/4] feat(rtlSupport): adjusting flowProperty according to ui layout's direction --- src/ui-layout.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ui-layout.js b/src/ui-layout.js index c0cf836..367b2e2 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -39,6 +39,14 @@ angular.module('ui.layout', []) mouseProperty: 'clientX', flowPropertyPosition: 'x' }; + $scope.$watch($window.getComputedStyle($element[0], null).direction, function() { + ctrl.dir = $window.getComputedStyle($element[0], null).direction; + if (ctrl.isUsingColumnFlow) { + ctrl.sizeProperties.flowProperty = ctrl.sizeProperties.offsetPos = (ctrl.dir === 'rtl') ? 'right' : 'left'; + ctrl.calculate(); + } + }); + $element // Force the layout to fill the parent space // fix no height layout... From 53741f81332ed73722f7a94e8807d3aab01d4603 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Wed, 9 Dec 2015 16:28:05 +0100 Subject: [PATCH 3/4] feat(rtlSupport): fixed mouse move calculations for rtl layouts --- src/ui-layout.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index 367b2e2..8430e12 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -150,9 +150,11 @@ angular.module('ui.layout', []) var scrollX = window.pageXOffset || body.scrollLeft; var scrollY = window.pageYOffset || body.scrollTop; var clientRect = rawDomNode.getBoundingClientRect(); - var x = clientRect.left + scrollX; - var y = clientRect.top + scrollY; - return { left: x, top: y }; + if (ctrl.isUsingColumnFlow) { + return clientRect[ctrl.sizeProperties.offsetPos] + scrollX; + } else { + return clientRect[ctrl.sizeProperties.offsetPos] + scrollY; + } } /** @@ -186,7 +188,12 @@ angular.module('ui.layout', []) (mouseEvent.originalEvent ? mouseEvent.originalEvent.targetTouches[0][ctrl.sizeProperties.mouseProperty] : 0) : (mouseEvent.targetTouches ? mouseEvent.targetTouches[0][ctrl.sizeProperties.mouseProperty] : 0)); - lastPos = mousePos - offset($element)[ctrl.sizeProperties.offsetPos]; + if (ctrl.dir === 'rtl' && ctrl.isUsingColumnFlow) { + lastPos = offset($element) - mousePos; + } else { + lastPos = mousePos - offset($element); + } + //Cancel previous rAF call if(animationFrameRequested) { From e71c419e93e4f9b0c47a764121e79e7b71ee679f Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Sat, 20 Feb 2016 09:30:24 +0100 Subject: [PATCH 4/4] test: added tests for rtl direction --- test/layout-scenar.spec.js | 452 +++++++++++---------- test/layout.spec.js | 715 +++++++++++++++++---------------- test/uiLayoutContainer.spec.js | 115 +++--- test/uiLayoutLoaded.spec.js | 107 ++--- 4 files changed, 729 insertions(+), 660 deletions(-) diff --git a/test/layout-scenar.spec.js b/test/layout-scenar.spec.js index a545d67..80e1db5 100644 --- a/test/layout-scenar.spec.js +++ b/test/layout-scenar.spec.js @@ -2,291 +2,307 @@ /* global browserTrigger */ -splitMoveTests('touch', 'touchstart', 'touchmove', 'touchend'); -splitMoveTests('mouse', 'mousedown', 'mousemove', 'mouseup'); +testWithDirection('ltr'); +testWithDirection('rtl'); -// 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, - validTemplate = '
', - defaultDividerSize = 10; +function testWithDirection(dir) { - function createDirective(data, template) { - var elm; + describe(dir.toUpperCase() + ' -', function() { -// scope.data = data || defaultData; + beforeEach(function() { + // set direction: + if (dir !== undefined) { + angular.element(document.body).attr('dir', dir); + } + }); - elm = angular.element(template || validTemplate); - angular.element(document.body).prepend(elm); - compile(elm)(scope); - scope.$digest(); + splitMoveTests('touch', 'touchstart', 'touchmove', 'touchend'); + splitMoveTests('mouse', 'mousedown', 'mousemove', 'mouseup'); - return elm; - } + // 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, + validTemplate = '
', + defaultDividerSize = 10; - beforeEach(function () { + function createDirective(data, template) { + var elm; - module('ui.layout'); + // scope.data = data || defaultData; - inject(function ($rootScope, $compile, _$timeout_) { - scope = $rootScope.$new(); - compile = $compile; - $timeout = _$timeout_; - }); - }); + elm = angular.element(template || validTemplate); + angular.element(document.body).prepend(elm); + compile(elm)(scope); + scope.$digest(); - afterEach(function () { - if (element) element.remove(); - }); + return elm; + } - describe('require', function () { - it('requestAnimationFrame', function () { - expect(window.requestAnimationFrame).toBeDefined(); - }); - it('cancelAnimationFrame', function () { - expect(window.cancelAnimationFrame).toBeDefined(); - }); - }); + beforeEach(function () { - // Spy on the requestAnimationFrame to directly trigger it - beforeEach(function () { - spyOn(window, 'requestAnimationFrame').and.callFake(function (fct) { - fct(); - }); - }); + module('ui.layout'); - afterEach(function () { - if (element) element.remove(); - }); + inject(function ($rootScope, $compile, _$timeout_) { + scope = $rootScope.$new(); + compile = $compile; + $timeout = _$timeout_; + }); + }); - describe('the slider', function () { + afterEach(function () { + if (element) element.remove(); + }); - var element_bb, $splitbar, splitbar_bb, splitbarLeftPos; + describe('require', function () { + it('requestAnimationFrame', function () { + expect(window.requestAnimationFrame).toBeDefined(); + }); + it('cancelAnimationFrame', function () { + expect(window.cancelAnimationFrame).toBeDefined(); + }); + }); - beforeEach(function () { - element = createDirective(); + // Spy on the requestAnimationFrame to directly trigger it + beforeEach(function () { + spyOn(window, 'requestAnimationFrame').and.callFake(function (fct) { + fct(); + }); + }); - element_bb = element[0].getBoundingClientRect(); - $splitbar = _jQuery(element[0]).find('.ui-splitbar'); - splitbar_bb = $splitbar[0].getBoundingClientRect(); + afterEach(function () { + if (element) element.remove(); + }); - splitbarLeftPos = Math.ceil(splitbar_bb.left); - }); + describe('the slider', function () { - it('should do nothing when clicking on it', function () { + var element_bb, $splitbar, splitbar_bb, splitbarLeftPos; - // Click on the splitbar left - browserTrigger($splitbar, startEvent, { x: splitbarLeftPos }); - browserTrigger($splitbar, endEvent); - splitbar_bb = $splitbar[0].getBoundingClientRect(); + beforeEach(function () { + element = createDirective(); - expect(window.requestAnimationFrame).not.toHaveBeenCalled(); - expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos); + element_bb = element[0].getBoundingClientRect(); + $splitbar = _jQuery(element[0]).find('.ui-splitbar'); + splitbar_bb = $splitbar[0].getBoundingClientRect(); - }); + splitbarLeftPos = Math.ceil(splitbar_bb.left); + }); - it('should do nothing when moving around it', function () { + it('should do nothing when clicking on it', function () { - // Click on the splitbar left - browserTrigger($splitbar, moveEvent, { x: splitbarLeftPos }); - browserTrigger($splitbar, moveEvent, { x: element_bb.height / 4 }); - splitbar_bb = $splitbar[0].getBoundingClientRect(); + // Click on the splitbar left + browserTrigger($splitbar, startEvent, { x: splitbarLeftPos }); + browserTrigger($splitbar, endEvent); + splitbar_bb = $splitbar[0].getBoundingClientRect(); - expect(window.requestAnimationFrame).not.toHaveBeenCalled(); - expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos); + expect(window.requestAnimationFrame).not.toHaveBeenCalled(); + expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos); - }); + }); - it('should follow the ' + description, function () { - browserTrigger($splitbar, startEvent, { y: splitbarLeftPos }); - browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4}); - expect(window.requestAnimationFrame).toHaveBeenCalled(); + it('should do nothing when moving around it', function () { - var expextedPos = Math.floor(element_bb.height / 4); - expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expextedPos); + // Click on the splitbar left + browserTrigger($splitbar, moveEvent, { x: splitbarLeftPos }); + browserTrigger($splitbar, moveEvent, { x: element_bb.height / 4 }); + splitbar_bb = $splitbar[0].getBoundingClientRect(); - browserTrigger(document.body, endEvent); - }); + expect(window.requestAnimationFrame).not.toHaveBeenCalled(); + expect(Math.ceil(splitbar_bb.left)).toEqual(splitbarLeftPos); - it('should not follow the ' + description + ' before ' + startEvent, function () { - var expectedPos = Math.floor((element_bb.height - defaultDividerSize) / 2); - expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos); + }); - // Move without clicking on it - browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width }); - browserTrigger($splitbar, endEvent); - expect(window.requestAnimationFrame).not.toHaveBeenCalled(); + it('should follow the ' + description, function () { + browserTrigger($splitbar, startEvent, { y: splitbarLeftPos }); + browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4}); + expect(window.requestAnimationFrame).toHaveBeenCalled(); - expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos); - }); + var expextedPos = Math.floor(element_bb.height / 4); + expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expextedPos); - it('should not follow the ' + description + ' after ' + startEvent, function () { - browserTrigger($splitbar, startEvent, { y: splitbarLeftPos }); - browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4}); - browserTrigger($splitbar, endEvent); - expect(window.requestAnimationFrame).toHaveBeenCalled(); + browserTrigger(document.body, endEvent); + }); - // Move after the end event - browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width }); - browserTrigger($splitbar, endEvent); + it('should not follow the ' + description + ' before ' + startEvent, function () { + var expectedPos = Math.floor((element_bb.height - defaultDividerSize) / 2); + expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos); - 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); - }); + // Move without clicking on it + browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width }); + browserTrigger($splitbar, endEvent); + expect(window.requestAnimationFrame).not.toHaveBeenCalled(); - describe('collapse buttons', function() { - var toggleBeforeButton, toggleAfterButton; + expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(expectedPos); + }); - beforeEach(function() { - toggleBeforeButton = $splitbar.children()[0]; - toggleAfterButton = $splitbar.children()[1]; - }); + it('should not follow the ' + description + ' after ' + startEvent, function () { + browserTrigger($splitbar, startEvent, { y: splitbarLeftPos }); + browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4}); + browserTrigger($splitbar, endEvent); + expect(window.requestAnimationFrame).toHaveBeenCalled(); - it('should exist', function() { - expect(toggleBeforeButton).toBeDefined(); - expect(toggleAfterButton).toBeDefined(); - }); + // Move after the end event + browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width }); + browserTrigger($splitbar, endEvent); - it('should toggle before', function() { - var expectedAutosized = Math.floor((element_bb.height - defaultDividerSize) / 2); + 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); + }); - var $header = element.children().eq(0)[0]; + describe('collapse buttons', function() { + var toggleBeforeButton, toggleAfterButton; - expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); - expect($header.getBoundingClientRect().height).toEqual(expectedAutosized); + beforeEach(function() { + toggleBeforeButton = $splitbar.children()[0]; + toggleAfterButton = $splitbar.children()[1]; + }); - browserTrigger(toggleBeforeButton, 'click'); + it('should exist', function() { + expect(toggleBeforeButton).toBeDefined(); + expect(toggleAfterButton).toBeDefined(); + }); - expect(parseInt($splitbar[0].style.top)).toEqual(0); - expect($header.getBoundingClientRect().height).toEqual(0); - expect(toggleAfterButton.style.display).toBe('none'); + it('should toggle before', function() { + var expectedAutosized = Math.floor((element_bb.height - defaultDividerSize) / 2); - browserTrigger(toggleBeforeButton, 'click'); + var $header = element.children().eq(0)[0]; - expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); - expect($header.getBoundingClientRect().height).toEqual(expectedAutosized); - expect(toggleAfterButton.style.display).toBe('inline'); - }); + expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); + expect($header.getBoundingClientRect().height).toEqual(expectedAutosized); - it('should toggle after', function() { - - var roundedHalf = Math.floor((element_bb.height - defaultDividerSize) / 2), - expectedAutosized = roundedHalf, - expectedLastAutosized = roundedHalf; - - // add remainder to the last element when parent size is odd - if (element_bb.height % 2 === 1) { - expectedLastAutosized += 1; - } - var $footer = element.children().eq(2)[0]; - expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); - expect($footer.getBoundingClientRect().height).toEqual(expectedLastAutosized); - - browserTrigger(toggleAfterButton, 'click'); - expect(parseInt($splitbar[0].style.top)).toEqual(element_bb.height - defaultDividerSize); - expect($footer.getBoundingClientRect().height).toEqual(0); - expect(toggleBeforeButton.style.display).toBe('none'); - - browserTrigger(toggleAfterButton, 'click'); - expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); - expect($footer.getBoundingClientRect().height).toEqual(expectedLastAutosized); - expect(toggleBeforeButton.style.display).toBe('inline'); + browserTrigger(toggleBeforeButton, 'click'); + + expect(parseInt($splitbar[0].style.top)).toEqual(0); + expect($header.getBoundingClientRect().height).toEqual(0); + expect(toggleAfterButton.style.display).toBe('none'); + + browserTrigger(toggleBeforeButton, 'click'); + + expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); + expect($header.getBoundingClientRect().height).toEqual(expectedAutosized); + expect(toggleAfterButton.style.display).toBe('inline'); + }); + + it('should toggle after', function() { + + var roundedHalf = Math.floor((element_bb.height - defaultDividerSize) / 2), + expectedAutosized = roundedHalf, + expectedLastAutosized = roundedHalf; + + // add remainder to the last element when parent size is odd + if (element_bb.height % 2 === 1) { + expectedLastAutosized += 1; + } + var $footer = element.children().eq(2)[0]; + expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); + expect($footer.getBoundingClientRect().height).toEqual(expectedLastAutosized); + + browserTrigger(toggleAfterButton, 'click'); + expect(parseInt($splitbar[0].style.top)).toEqual(element_bb.height - defaultDividerSize); + expect($footer.getBoundingClientRect().height).toEqual(0); + expect(toggleBeforeButton.style.display).toBe('none'); + + browserTrigger(toggleAfterButton, 'click'); + expect(parseInt($splitbar[0].style.top)).toEqual(expectedAutosized); + expect($footer.getBoundingClientRect().height).toEqual(expectedLastAutosized); + expect(toggleBeforeButton.style.display).toBe('inline'); + }); + }); }); - }); - }); - }); -} + }); + } -describe('toggle programmatically', function() { - var scope, $controller, $compile, $timeout; - beforeEach(function () { + describe('toggle programmatically', function() { + var scope, $controller, $compile, $timeout; + beforeEach(function () { - module('ui.layout'); + module('ui.layout'); - inject(function ($rootScope, _$controller_, _$compile_, _$timeout_) { - scope = $rootScope.$new(); - $controller = _$controller_; - $compile = _$compile_; - $timeout = _$timeout_; - }); - }); + inject(function ($rootScope, _$controller_, _$compile_, _$timeout_) { + scope = $rootScope.$new(); + $controller = _$controller_; + $compile = _$compile_; + $timeout = _$timeout_; + }); + }); - function compileDirective(before, after, tpl) { - var template = tpl || '' + - '
' + - '
One
' + - '
Two
' + - '
'; + function compileDirective(before, after, tpl) { + var template = tpl || '' + + '
' + + '
One
' + + '
Two
' + + '
'; - scope.layout = { - beforeContainer: before, - afterContainer: after - }; + scope.layout = { + beforeContainer: before, + afterContainer: after + }; - var elm = angular.element(template); - angular.element(document.body).prepend(elm); - $compile(elm)(scope); - scope.$digest(); + var elm = angular.element(template); + angular.element(document.body).prepend(elm); + $compile(elm)(scope); + scope.$digest(); - return elm; - } + return elm; + } - it('should reset container to uncollapsed state when loaded', function() { - //@see explanation for uiLayoutLoaded - var elm = compileDirective(true, true); + it('should reset container to uncollapsed state when loaded', function() { + //@see explanation for uiLayoutLoaded + var elm = compileDirective(true, true); - var divs = elm.find('div'), - beforeContainer = divs[0], - afterContainer = divs[2]; - expect(beforeContainer.style.width).toEqual('100px'); - expect(afterContainer.style.width).toEqual('200px'); - }); + var divs = elm.find('div'), + beforeContainer = divs[0], + afterContainer = divs[2]; + expect(beforeContainer.style.width).toEqual('100px'); + expect(afterContainer.style.width).toEqual('200px'); + }); - it('should collapse and uncollapse beforeContainer', function() { - var elm = compileDirective(false, false); + it('should collapse and uncollapse beforeContainer', function() { + var elm = compileDirective(false, false); - var divs = elm.find('div'), - beforeContainer = divs[0], - afterContainer = divs[2]; - expect(beforeContainer.style.width).toEqual('100px'); - expect(afterContainer.style.width).toEqual('200px'); + var divs = elm.find('div'), + beforeContainer = divs[0], + afterContainer = divs[2]; + expect(beforeContainer.style.width).toEqual('100px'); + expect(afterContainer.style.width).toEqual('200px'); - scope.layout.beforeContainer = true; - scope.$apply(); - $timeout.flush(); + scope.layout.beforeContainer = true; + scope.$apply(); + $timeout.flush(); - expect(beforeContainer.style.width).toEqual('0px'); + expect(beforeContainer.style.width).toEqual('0px'); - scope.layout.beforeContainer = false; - scope.$apply(); - $timeout.flush(); + scope.layout.beforeContainer = false; + scope.$apply(); + $timeout.flush(); - expect(beforeContainer.style.width).toEqual('100px'); - }); + expect(beforeContainer.style.width).toEqual('100px'); + }); - it('should collapse and uncollapse afterContainer', function() { - var elm = compileDirective(false, false); + it('should collapse and uncollapse afterContainer', function() { + var elm = compileDirective(false, false); - var divs = elm.find('div'), - beforeContainer = divs[0], - afterContainer = divs[2]; - expect(beforeContainer.style.width).toEqual('100px'); - expect(afterContainer.style.width).toEqual('200px'); + var divs = elm.find('div'), + beforeContainer = divs[0], + afterContainer = divs[2]; + expect(beforeContainer.style.width).toEqual('100px'); + expect(afterContainer.style.width).toEqual('200px'); - scope.layout.afterContainer = true; - scope.$apply(); - $timeout.flush(); + scope.layout.afterContainer = true; + scope.$apply(); + $timeout.flush(); - expect(afterContainer.style.width).toEqual('0px'); + expect(afterContainer.style.width).toEqual('0px'); - scope.layout.afterContainer = false; - scope.$apply(); - $timeout.flush(); + scope.layout.afterContainer = false; + scope.$apply(); + $timeout.flush(); - expect(afterContainer.style.width).toEqual('200px'); + expect(afterContainer.style.width).toEqual('200px'); + }); + }); }); -}); +} diff --git a/test/layout.spec.js b/test/layout.spec.js index 100990a..d69a0fa 100644 --- a/test/layout.spec.js +++ b/test/layout.spec.js @@ -1,448 +1,467 @@ 'use strict'; +testWithDirection('ltr'); +testWithDirection('rtl'); -describe('Directive: uiLayout', function () { - var element, scope, compile, - validTemplate = '
', - defaultDividerSize = 10; +function testWithDirection(dir) { - function createDirective(data, template) { - var elm; + describe(dir.toUpperCase() + ' -', function() { -// scope.data = data || defaultData; + var horizontalFlowProperty = (dir === 'rtl') ? 'right' : 'left'; - elm = angular.element(template || validTemplate); - angular.element(document.body).prepend(elm); - compile(elm)(scope); - scope.$digest(); - - return elm; - } - - beforeEach(function() { - jasmine.addMatchers({ - toBeAbout: function() { - return { - compare: function(actual, expected, precision) { - precision = parseInt(precision)|| 1; - actual = parseInt(actual); - expected = parseInt(expected); - - return { - pass: Math.abs(actual - expected) <= precision - }; - } - }; + beforeEach(function() { + // set direction: + if (dir !== undefined) { + angular.element(document.body).attr('dir', dir); } }); - }); - beforeEach(function () { - - module('ui.layout'); - - inject(function ($rootScope, $compile) { - scope = $rootScope.$new(); - compile = $compile; - }); - }); - - afterEach(function () { - if (element) element.remove(); - }); + describe('Directive: uiLayout', function () { + var element, scope, compile, + validTemplate = '
', + defaultDividerSize = 10; - describe('require', function () { - it('requestAnimationFrame', function () { - expect(window.requestAnimationFrame).toBeDefined(); - }); - it('cancelAnimationFrame', function () { - expect(window.cancelAnimationFrame).toBeDefined(); - }); - }); + function createDirective(data, template) { + var elm; - describe('when created', function () { + // scope.data = data || defaultData; - it('should have a "stretch" class', function () { - element = createDirective(); - expect(element).toHaveClass('stretch'); - }); + elm = angular.element(template || validTemplate); + angular.element(document.body).prepend(elm); + compile(elm)(scope); + scope.$digest(); - it('should work as an element', function () { - element = createDirective(null, ''); - expect(element).toHaveClass('stretch'); - }); + return elm; + } - it('should work as an attribute', function () { - element = createDirective(); - expect(element).toHaveClass('stretch'); - }); + beforeEach(function() { + jasmine.addMatchers({ + toBeAbout: function() { + return { + compare: function(actual, expected, precision) { + precision = parseInt(precision)|| 1; + actual = parseInt(actual); + expected = parseInt(expected); + + return { + pass: Math.abs(actual - expected) <= precision + }; + } + }; + } + }); + }); - it('should have a "ui-layout-row" class by default', function () { - element = createDirective(); - expect(element).toHaveClass('ui-layout-row'); - }); + beforeEach(function () { - it('should not add split bar when empty', function () { - element = createDirective(); - expect(element.children().length).toEqual(0); - }); + module('ui.layout'); - it('should add n-1 split bar pour n area', function () { - var children, splitBarElm; - - // Try with 2 elements - element = createDirective(null, '
'); - children = element.children(); - expect(children.length).toEqual(2 + 1); // add one slide - expect(children[0].tagName).toEqual('ARTICLE'); - - splitBarElm = children.eq(1); - expect(splitBarElm[0].tagName).toEqual('DIV'); - expect(splitBarElm).toHaveClass('ui-splitbar'); - - expect(children[2].tagName).toEqual('SECTION'); - - // Try with 4 elements - element.remove(); - var dirHtml = '
'; - element = createDirective(null, dirHtml); - children = element.children(); - expect(children.length).toEqual(4 + 3); // add three slide - - // Raw pluck - function _pluck(col, prop) { - var _r = []; - for (var i = 0; i < col.length; i++) { - _r[i] = col[i][prop]; - } - return _r; - } + inject(function ($rootScope, $compile) { + scope = $rootScope.$new(); + compile = $compile; + }); + }); - expect(_pluck(children, 'tagName')).toEqual(['HEADER', 'DIV', 'ARTICLE', 'DIV', 'SECTION', 'DIV', 'FOOTER']); + afterEach(function () { + if (element) element.remove(); + }); - }); + describe('require', function () { + it('requestAnimationFrame', function () { + expect(window.requestAnimationFrame).toBeDefined(); + }); + it('cancelAnimationFrame', function () { + expect(window.cancelAnimationFrame).toBeDefined(); + }); + }); - }); + describe('when created', function () { + + it('should have a "stretch" class', function () { + element = createDirective(); + expect(element).toHaveClass('stretch'); + }); + + it('should work as an element', function () { + element = createDirective(null, ''); + expect(element).toHaveClass('stretch'); + }); + + it('should work as an attribute', function () { + element = createDirective(); + expect(element).toHaveClass('stretch'); + }); + + it('should have a "ui-layout-row" class by default', function () { + element = createDirective(); + expect(element).toHaveClass('ui-layout-row'); + }); + + it('should not add split bar when empty', function () { + element = createDirective(); + expect(element.children().length).toEqual(0); + }); + + it('should add n-1 split bar pour n area', function () { + var children, splitBarElm; + + // Try with 2 elements + element = createDirective(null, '
'); + children = element.children(); + expect(children.length).toEqual(2 + 1); // add one slide + expect(children[0].tagName).toEqual('ARTICLE'); + + splitBarElm = children.eq(1); + expect(splitBarElm[0].tagName).toEqual('DIV'); + expect(splitBarElm).toHaveClass('ui-splitbar'); + + expect(children[2].tagName).toEqual('SECTION'); + + // Try with 4 elements + element.remove(); + var dirHtml = '
'; + element = createDirective(null, dirHtml); + children = element.children(); + expect(children.length).toEqual(4 + 3); // add three slide + + // Raw pluck + function _pluck(col, prop) { + var _r = []; + for (var i = 0; i < col.length; i++) { + _r[i] = col[i][prop]; + } + return _r; + } - describe('when using size option', function () { + expect(_pluck(children, 'tagName')).toEqual(['HEADER', 'DIV', 'ARTICLE', 'DIV', 'SECTION', 'DIV', 'FOOTER']); - var $header, $footer; - var layoutBounds, headerBounds; + }); - function createSizedDirective(notation) { - element = createDirective(null, '
'); + }); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + describe('when using size option', function () { - return element; - } + var $header, $footer; + var layoutBounds, headerBounds; - function createDataSizedDirective(notation) { - element = createDirective(null, '
'); + function createSizedDirective(notation) { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - return element; - } + return element; + } + function createDataSizedDirective(notation) { + element = createDirective(null, '
'); - function testSizeNotation(notation, actualSize) { - element = createSizedDirective(notation); - test(element, notation, actualSize); - element.remove(); + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - element = createDataSizedDirective(notation); - test(element, notation, actualSize); - element.remove(); - } + return element; + } - function test(element, notation, actualSize) { - layoutBounds = element[0].getBoundingClientRect(); - headerBounds = $header.getBoundingClientRect(); - expect(parseFloat($header.style.top)).toEqual(0); + function testSizeNotation(notation, actualSize) { + element = createSizedDirective(notation); + test(element, notation, actualSize); + element.remove(); - if(notation.indexOf('%') >= 0 && actualSize != null && !isNaN(actualSize)) { - expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (actualSize / 100)); - expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); - } else if(notation.indexOf('px') && actualSize != null && !isNaN(actualSize)) { - expect(parseFloat($header.style.height)).toEqual(actualSize); - expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - actualSize - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual(actualSize + defaultDividerSize); - } + element = createDataSizedDirective(notation); + test(element, notation, actualSize); + element.remove(); + } - } + function test(element, notation, actualSize) { + layoutBounds = element[0].getBoundingClientRect(); + headerBounds = $header.getBoundingClientRect(); - describe('when using dummy input', function () { - var wtfSizes = ['fuu', ' ', 'wtf10', '10wtf', '12', '12ppx', '12px%', '12px %']; - for (var _i = 0, n = wtfSizes.length; _i < n; ++_i) { - (function (notation) { // Use a new scope - it('should handle "' + notation + '" as auto', function () { - testSizeNotation(notation); - }); - })(wtfSizes[_i]); - } - }); + expect(parseFloat($header.style.top)).toEqual(0); - it('should support percent type', function () { - testSizeNotation('10%', 10); - }); + if(notation.indexOf('%') >= 0 && actualSize != null && !isNaN(actualSize)) { + expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (actualSize / 100)); + expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); + } else if(notation.indexOf('px') && actualSize != null && !isNaN(actualSize)) { + expect(parseFloat($header.style.height)).toEqual(actualSize); + expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - actualSize - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual(actualSize + defaultDividerSize); + } - it('should support pixel type', function () { - testSizeNotation('10px', 10); - }); + } - it('should handle useless spaces', function () { - testSizeNotation(' 10%', 10); - testSizeNotation('10% ', 10); - testSizeNotation(' 10% ', 10); - testSizeNotation(' 10 % ', 10); - }); - }); + describe('when using dummy input', function () { + var wtfSizes = ['fuu', ' ', 'wtf10', '10wtf', '12', '12ppx', '12px%', '12px %']; + for (var _i = 0, n = wtfSizes.length; _i < n; ++_i) { + (function (notation) { // Use a new scope + it('should handle "' + notation + '" as auto', function () { + testSizeNotation(notation); + }); + })(wtfSizes[_i]); + } + }); + + it('should support percent type', function () { + testSizeNotation('10%', 10); + }); + + it('should support pixel type', function () { + testSizeNotation('10px', 10); + }); + + it('should handle useless spaces', function () { + testSizeNotation(' 10%', 10); + testSizeNotation('10% ', 10); + testSizeNotation(' 10% ', 10); + testSizeNotation(' 10 % ', 10); + }); + }); - describe('when using the min-size option', function() { - var $header, $footer; - var layoutBounds, headerBounds; + describe('when using the min-size option', function() { + var $header, $footer; + var layoutBounds, headerBounds; - function createSizedDirective(notation) { - element = createDirective(null, '
'); + function createSizedDirective(notation) { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - return element; - } + return element; + } - function createDataSizedDirective(notation) { - element = createDirective(null, '
'); + function createDataSizedDirective(notation) { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - return element; - } + return element; + } - function testSizeNotation(notation, minSize) { - element = createSizedDirective(notation); - test(element, notation, minSize); - element.remove(); + function testSizeNotation(notation, minSize) { + element = createSizedDirective(notation); + test(element, notation, minSize); + element.remove(); - element = createDataSizedDirective(notation); - test(element, notation, minSize); - element.remove(); + element = createDataSizedDirective(notation); + test(element, notation, minSize); + element.remove(); - } + } - function test(element, notation, minSize) { - layoutBounds = element[0].getBoundingClientRect(); - headerBounds = $header.getBoundingClientRect(); + function test(element, notation, minSize) { + layoutBounds = element[0].getBoundingClientRect(); + headerBounds = $header.getBoundingClientRect(); - expect(parseFloat($header.style.top)).toEqual(0); + expect(parseFloat($header.style.top)).toEqual(0); - if(notation.indexOf('%') >= 0 && minSize != null && !isNaN(minSize)) { - expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (minSize / 100)); - expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); - } else if(notation.indexOf('px') && minSize != null && !isNaN(minSize)) { - expect(parseFloat($header.style.height)).toEqual(minSize); - expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - minSize - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual(minSize + defaultDividerSize); - } - } + if(notation.indexOf('%') >= 0 && minSize != null && !isNaN(minSize)) { + expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (minSize / 100)); + expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); + } else if(notation.indexOf('px') && minSize != null && !isNaN(minSize)) { + expect(parseFloat($header.style.height)).toEqual(minSize); + expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - minSize - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual(minSize + defaultDividerSize); + } + } - it('should support percent type', function () { - testSizeNotation('10%', 10); - }); + it('should support percent type', function () { + testSizeNotation('10%', 10); + }); - it('should support pixel type', function () { - testSizeNotation('10px', 10); - }); + it('should support pixel type', function () { + testSizeNotation('10px', 10); + }); - it('should handle useless spaces', function () { - testSizeNotation(' 10%', 10); - testSizeNotation('10% ', 10); - testSizeNotation(' 10% ', 10); - testSizeNotation(' 10 % ', 10); - }); - }); + it('should handle useless spaces', function () { + testSizeNotation(' 10%', 10); + testSizeNotation('10% ', 10); + testSizeNotation(' 10% ', 10); + testSizeNotation(' 10 % ', 10); + }); + }); - describe('when using the max-size option', function() { - var $header, $footer; - var layoutBounds, headerBounds; + describe('when using the max-size option', function() { + var $header, $footer; + var layoutBounds, headerBounds; - function createSizedDirective(notation) { - element = createDirective(null, '
'); + function createSizedDirective(notation) { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - return element; - } + return element; + } - function createDataSizedDirective(notation) { - element = createDirective(null, '
'); + function createDataSizedDirective(notation) { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $footer = element.children().eq(2)[0]; - return element; - } + return element; + } - function testSizeNotation(notation, maxSize) { - element = createSizedDirective(notation); - test(element, notation, maxSize); - element.remove(); + function testSizeNotation(notation, maxSize) { + element = createSizedDirective(notation); + test(element, notation, maxSize); + element.remove(); - element = createDataSizedDirective(notation); - test(element, notation, maxSize); - element.remove(); - } + element = createDataSizedDirective(notation); + test(element, notation, maxSize); + element.remove(); + } - function test(element, notation, maxSize) { - layoutBounds = element[0].getBoundingClientRect(); - headerBounds = $header.getBoundingClientRect(); + function test(element, notation, maxSize) { + layoutBounds = element[0].getBoundingClientRect(); + headerBounds = $header.getBoundingClientRect(); - expect(parseFloat($header.style.top)).toEqual(0); + expect(parseFloat($header.style.top)).toEqual(0); - if(notation.indexOf('%') >= 0 && maxSize != null && !isNaN(maxSize)) { - expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (maxSize / 100)); - expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); - } else if(notation.indexOf('px') && maxSize != null && !isNaN(maxSize)) { - expect(parseFloat($header.style.height)).toEqual(maxSize); - expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - maxSize - defaultDividerSize); - expect(parseFloat($footer.style.top)).toEqual(maxSize + defaultDividerSize); - } + if(notation.indexOf('%') >= 0 && maxSize != null && !isNaN(maxSize)) { + expect(parseFloat($header.style.height)).toBeAbout(layoutBounds.height * (maxSize / 100)); + expect(parseFloat($footer.style.height)).toBeAbout(layoutBounds.height - headerBounds.height - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual((headerBounds.height + defaultDividerSize)); + } else if(notation.indexOf('px') && maxSize != null && !isNaN(maxSize)) { + expect(parseFloat($header.style.height)).toEqual(maxSize); + expect(parseFloat($footer.style.height)).toEqual(layoutBounds.height - maxSize - defaultDividerSize); + expect(parseFloat($footer.style.top)).toEqual(maxSize + defaultDividerSize); + } - } + } - it('should support percent type', function () { - testSizeNotation('10%', 10); - }); + it('should support percent type', function () { + testSizeNotation('10%', 10); + }); - it('should support pixel type', function () { - testSizeNotation('10px', 10); - }); + it('should support pixel type', function () { + testSizeNotation('10px', 10); + }); - it('should handle useless spaces', function () { - testSizeNotation(' 10%', 10); - testSizeNotation('10% ', 10); - testSizeNotation(' 10% ', 10); - testSizeNotation(' 10 % ', 10); - }); - }); + it('should handle useless spaces', function () { + testSizeNotation(' 10%', 10); + testSizeNotation('10% ', 10); + testSizeNotation(' 10% ', 10); + testSizeNotation(' 10 % ', 10); + }); + }); - describe('when using the collapse option', function() { + describe('when using the collapse option', function() { - }); + }); - describe('when using column flow', function () { + describe('when using column flow', function () { - var $header, $sidebar, $footer; - var layoutBounds, headerBounds; + var $header, $sidebar, $footer; + var layoutBounds, headerBounds; - describe('when created', function () { - beforeEach(function () { - element = createDirective(null, '
'); + describe('when created', function () { + beforeEach(function () { + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $sidebar = element.children().eq(1)[0]; - $footer = element.children().eq(2)[0]; + $header = element.children().eq(0)[0]; + $sidebar = element.children().eq(1)[0]; + $footer = element.children().eq(2)[0]; - layoutBounds = element[0].getBoundingClientRect(); - headerBounds = $header.getBoundingClientRect(); - }); + layoutBounds = element[0].getBoundingClientRect(); + headerBounds = $header.getBoundingClientRect(); + }); - it('should have a "ui-layout-column" class', function () { - expect(element).toHaveClass('ui-layout-column'); - }); + it('should have a "ui-layout-column" class', function () { + expect(element).toHaveClass('ui-layout-column'); + }); - it('should initialise with equal width', function () { - var expectedHeaderWidth = Math.floor((layoutBounds.width - defaultDividerSize) / 2), - expectedFooterWidth = expectedHeaderWidth; + it('should initialise with equal width', function () { + var expectedHeaderWidth = Math.floor((layoutBounds.width - defaultDividerSize) / 2), + expectedFooterWidth = expectedHeaderWidth; - if (layoutBounds.width % 2 === 1) { - expectedFooterWidth += 1; // "dangling pixel" added to the last autosized container in a layout - } + if (layoutBounds.width % 2 === 1) { + expectedFooterWidth += 1; // "dangling pixel" added to the last autosized container in a layout + } - expect($header.style.left).toEqual('0px'); - expect($header.style.width).toEqual(expectedHeaderWidth + 'px'); - expect($footer.style.left).toEqual((expectedHeaderWidth + defaultDividerSize) + 'px'); - expect($footer.style.width).toEqual(expectedFooterWidth + 'px'); - }); + expect($header.style[horizontalFlowProperty]).toEqual('0px'); + expect($header.style.width).toEqual(expectedHeaderWidth + 'px'); + expect($footer.style[horizontalFlowProperty]).toEqual((expectedHeaderWidth + defaultDividerSize) + 'px'); + expect($footer.style.width).toEqual(expectedFooterWidth + 'px'); + }); - it('should have a split bar at the middle', function () { - var middle = Math.floor((layoutBounds.width - defaultDividerSize) / 2); - expect($sidebar.style.left).toEqual(middle + 'px'); + it('should have a split bar at the middle', function () { + var middle = Math.floor((layoutBounds.width - defaultDividerSize) / 2); + expect($sidebar.style[horizontalFlowProperty]).toEqual(middle + 'px'); + }); + }); + + it('should initialise a sidebar at 10%', function () { + element = createDirective(null, '
'); + $sidebar = element.children().eq(1)[0]; + var expectedPos = Math.floor(layoutBounds.width * 0.1); + expect($sidebar.style[horizontalFlowProperty]).toBeAbout(expectedPos); + }); }); - }); - it('should initialise a sidebar at 10%', function () { - element = createDirective(null, '
'); - $sidebar = element.children().eq(1)[0]; - var expectedPos = Math.floor(layoutBounds.width * 0.1); - expect($sidebar.style.left).toBeAbout(expectedPos); - }); - }); - - describe('in row flow', function () { + describe('in row flow', function () { - var $header, $sidebar, $footer; - var layoutBounds, headerBounds; + var $header, $sidebar, $footer; + var layoutBounds, headerBounds; - describe('when created', function () { - beforeEach(function () { + describe('when created', function () { + beforeEach(function () { - element = createDirective(null, '
'); + element = createDirective(null, '
'); - $header = element.children().eq(0)[0]; - $sidebar = element.children().eq(1)[0]; - $footer = element.children().eq(1)[0]; + $header = element.children().eq(0)[0]; + $sidebar = element.children().eq(1)[0]; + $footer = element.children().eq(1)[0]; - layoutBounds = element[0].getBoundingClientRect(); - headerBounds = $header.getBoundingClientRect(); + layoutBounds = element[0].getBoundingClientRect(); + headerBounds = $header.getBoundingClientRect(); - }); + }); - it('should have a "ui-layout-row" class by default', function () { - expect(element).toHaveClass('ui-layout-row'); - }); + it('should have a "ui-layout-row" class by default', function () { + expect(element).toHaveClass('ui-layout-row'); + }); - it('should initialise with equal height when parent container height has an even value', function () { - var parentHeightEven = element[0].getBoundingClientRect().height % 2 === 0; - if (parentHeightEven) { - var firstElemHeight = element.children()[0].getBoundingClientRect().height; - for (var i = 0; i < element.children().length; i += 2) { - expect(element.children()[i].getBoundingClientRect().height, 'tagName').toEqual(firstElemHeight); - } - } - }); + it('should initialise with equal height when parent container height has an even value', function () { + var parentHeightEven = element[0].getBoundingClientRect().height % 2 === 0; + if (parentHeightEven) { + var firstElemHeight = element.children()[0].getBoundingClientRect().height; + for (var i = 0; i < element.children().length; i += 2) { + expect(element.children()[i].getBoundingClientRect().height, 'tagName').toEqual(firstElemHeight); + } + } + }); - it('should initialise with last container height larger by 1px when parent container height has an odd value', function () { - var parentHeightOdd = element[0].getBoundingClientRect().height % 2 !== 0; - if (parentHeightOdd) { - var firstElemHeight = element.children()[0].getBoundingClientRect().height; - var lastElementHeight = element.children()[2].getBoundingClientRect().height; - expect(lastElementHeight).toEqual(firstElemHeight + 1); - } - }); + it('should initialise with last container height larger by 1px when parent container height has an odd value', function () { + var parentHeightOdd = element[0].getBoundingClientRect().height % 2 !== 0; + if (parentHeightOdd) { + var firstElemHeight = element.children()[0].getBoundingClientRect().height; + var lastElementHeight = element.children()[2].getBoundingClientRect().height; + expect(lastElementHeight).toEqual(firstElemHeight + 1); + } + }); - it('should have a split bar at the middle', function () { - // not an absolute middle. In case of odd height, last container is larger by 1px (remainder of the rounding down) - var expectedMiddle = Math.floor((layoutBounds.height - defaultDividerSize) / 2); - expect($sidebar.style.top).toEqual(expectedMiddle + 'px'); + it('should have a split bar at the middle', function () { + // not an absolute middle. In case of odd height, last container is larger by 1px (remainder of the rounding down) + var expectedMiddle = Math.floor((layoutBounds.height - defaultDividerSize) / 2); + expect($sidebar.style.top).toEqual(expectedMiddle + 'px'); + }); + }); + + it('should initialise a sidebar at 10%', function () { + element = createDirective(null, '
'); + $sidebar = element.children().eq(1)[0]; + var expectedPos = Math.floor(layoutBounds.height * 0.1); + expect($sidebar.style.top).toBeAbout(expectedPos); + }); }); }); - it('should initialise a sidebar at 10%', function () { - element = createDirective(null, '
'); - $sidebar = element.children().eq(1)[0]; - var expectedPos = Math.floor(layoutBounds.height * 0.1); - expect($sidebar.style.top).toBeAbout(expectedPos); - }); }); -}); + +} diff --git a/test/uiLayoutContainer.spec.js b/test/uiLayoutContainer.spec.js index ade2406..b5d4dd4 100644 --- a/test/uiLayoutContainer.spec.js +++ b/test/uiLayoutContainer.spec.js @@ -1,64 +1,81 @@ 'use strict'; +testWithDirection('ltr'); +testWithDirection('rtl'); -describe('Directive: uiLayoutContainer', function () { - var scope, element, $compile, - template = '' + - '
' + - '
One
' + - '
Two
' + - '
'; +function testWithDirection(dir) { - function createDirective(layout) { - var elm; + describe(dir.toUpperCase() + ' -', function() { - scope.layout = layout; - elm = angular.element(template); - angular.element(document.body).prepend(elm); - $compile(elm)(scope); - scope.$digest(); + beforeEach(function() { + // set direction: + if (dir !== undefined) { + angular.element(document.body).attr('dir', dir); + } + }); - return elm; - } + describe('Directive: uiLayoutContainer', function () { + var scope, element, $compile, + template = '' + + '
' + + '
One
' + + '
Two
' + + '
'; - beforeEach(function () { + function createDirective(layout) { + var elm; - module('ui.layout'); + scope.layout = layout; + elm = angular.element(template); + angular.element(document.body).prepend(elm); + $compile(elm)(scope); + scope.$digest(); - inject(function ($rootScope, _$compile_) { - scope = $rootScope.$new(); - $compile = _$compile_; - }); - }); + return elm; + } - afterEach(function () { - if (element) element.remove(); - }); + beforeEach(function () { + + module('ui.layout'); + + inject(function ($rootScope, _$compile_) { + scope = $rootScope.$new(); + $compile = _$compile_; + }); + }); + afterEach(function () { + if (element) element.remove(); + }); - it('should get initial attribute values', function () { - // this tests values _after_ the layout has been calculated - element = createDirective({ beforeContainer: true, afterContainer: false}); - var divs = element.find('div'), - beforeContainer = divs[0], - afterContainer = divs[2], - bcScope = angular.element(beforeContainer).isolateScope(), - acScope = angular.element(afterContainer).isolateScope(); - - // you would expect true, but see explanation in uiLayoutLoaded - expect(bcScope.container.collapsed).toEqual(false); - expect(bcScope.container.resizable).toEqual(false); - expect(bcScope.container.size).toEqual(100); - expect(bcScope.container.uncollapsedSize).toEqual('100px'); - expect(bcScope.container.minSize).toEqual(50); - expect(bcScope.container.maxSize).toEqual(200); - - expect(acScope.container.collapsed).toEqual(false); - expect(acScope.container.resizable).toEqual(true); - // size has been be calculated, this is tested elsewhere - expect(acScope.container.minSize).toBeNull(); - expect(acScope.container.maxSize).toBeNull(); + + it('should get initial attribute values', function () { + // this tests values _after_ the layout has been calculated + element = createDirective({ beforeContainer: true, afterContainer: false}); + var divs = element.find('div'), + beforeContainer = divs[0], + afterContainer = divs[2], + bcScope = angular.element(beforeContainer).isolateScope(), + acScope = angular.element(afterContainer).isolateScope(); + + // you would expect true, but see explanation in uiLayoutLoaded + expect(bcScope.container.collapsed).toEqual(false); + expect(bcScope.container.resizable).toEqual(false); + expect(bcScope.container.size).toEqual(100); + expect(bcScope.container.uncollapsedSize).toEqual('100px'); + expect(bcScope.container.minSize).toEqual(50); + expect(bcScope.container.maxSize).toEqual(200); + + expect(acScope.container.collapsed).toEqual(false); + expect(acScope.container.resizable).toEqual(true); + // size has been be calculated, this is tested elsewhere + expect(acScope.container.minSize).toBeNull(); + expect(acScope.container.maxSize).toBeNull(); + + }); + + }); }); -}); \ No newline at end of file +} diff --git a/test/uiLayoutLoaded.spec.js b/test/uiLayoutLoaded.spec.js index e474098..c6898fc 100644 --- a/test/uiLayoutLoaded.spec.js +++ b/test/uiLayoutLoaded.spec.js @@ -1,60 +1,77 @@ 'use strict'; +testWithDirection('ltr'); +testWithDirection('rtl'); -describe('Directive: uiLayoutLoaded', function () { - var scope, element, $compile, $timeout, - template = '
'; +function testWithDirection(dir) { - function compileDirective(before, after, tpl) { - var elm; + describe(dir.toUpperCase() + ' -', function() { - elm = angular.element(tpl || template); - angular.element(document.body).prepend(elm); - $compile(elm)(scope); - scope.$digest(); + beforeEach(function() { + // set direction: + if (dir !== undefined) { + angular.element(document.body).attr('dir', dir); + } + }); - return elm; - } + describe('Directive: uiLayoutLoaded', function () { + var scope, element, $compile, $timeout, + template = '
'; - beforeEach(function () { + function compileDirective(before, after, tpl) { + var elm; - module('ui.layout'); + elm = angular.element(tpl || template); + angular.element(document.body).prepend(elm); + $compile(elm)(scope); + scope.$digest(); - inject(function ($rootScope, _$compile_, _$timeout_) { - scope = $rootScope.$new(); - $compile = _$compile_; - $timeout = _$timeout_; - }); - }); + return elm; + } - afterEach(function () { - if (element) element.remove(); - }); + beforeEach(function () { - it('should broadcast ui.layout.loaded and return attribute value', function () { - spyOn(scope, '$broadcast'); - compileDirective(false, false, '
'); - expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded','attrValue'); - }); + module('ui.layout'); - it('should broadcast ui.layout.loaded and return null', function () { - spyOn(scope, '$broadcast'); - compileDirective(false, false, '
'); - $timeout.flush(); - expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded',null); - }); + inject(function ($rootScope, _$compile_, _$timeout_) { + scope = $rootScope.$new(); + $compile = _$compile_; + $timeout = _$timeout_; + }); + }); + + afterEach(function () { + if (element) element.remove(); + }); + + it('should broadcast ui.layout.loaded and return attribute value', function () { + spyOn(scope, '$broadcast'); + compileDirective(false, false, '
'); + expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded','attrValue'); + }); + + it('should broadcast ui.layout.loaded and return null', function () { + spyOn(scope, '$broadcast'); + compileDirective(false, false, '
'); + $timeout.flush(); + expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded',null); + }); + + it('should broadcast ui.layout.loaded after all ui.layout directives have been loaded and return attribute value not an evaluated expression', function () { + spyOn(scope, '$broadcast'); + scope.data = { + someMessage: "dummy" + }; + + var elm = angular.element('
'); + angular.element(document.body).prepend(elm); + $compile(elm)(scope); + scope.$digest(); + expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded','data.someMessage'); + }); + + }); - it('should broadcast ui.layout.loaded after all ui.layout directives have been loaded and return attribute value not an evaluated expression', function () { - spyOn(scope, '$broadcast'); - scope.data = { - someMessage: "dummy" - }; - - var elm = angular.element('
'); - angular.element(document.body).prepend(elm); - $compile(elm)(scope); - scope.$digest(); - expect(scope.$broadcast).toHaveBeenCalledWith('ui.layout.loaded','data.someMessage'); }); -}); \ No newline at end of file +}