diff --git a/JsTestDriver.jar b/JsTestDriver.jar deleted file mode 100644 index f3183ed..0000000 Binary files a/JsTestDriver.jar and /dev/null differ diff --git a/jsTestDriver.conf b/jsTestDriver.conf deleted file mode 100644 index dc4d090..0000000 --- a/jsTestDriver.conf +++ /dev/null @@ -1,8 +0,0 @@ -server: http://localhost:4224 - -load: - - src/FTColumnflow.js - - test/css/*.css - - test/*.js - -serve: diff --git a/test/BaselineGridTest.js b/test/BaselineGridTest.js deleted file mode 100644 index bdbee9f..0000000 --- a/test/BaselineGridTest.js +++ /dev/null @@ -1,290 +0,0 @@ -/** - * FTColumnflow BaselineGrid test suite - * - * @copyright The Financial Times Limited [All Rights Reserved] -*/ - - -function createCf(config) { - cf = new FTColumnflow('targetid', 'viewportid', config || { - columnGap : 25, - columnCount : 3 - }); - target = document.getElementById('targetid'); - - return cf; -} - -TestCase('BaselineGrid', { - - setUp : function() { - document.body.innerHTML = '
'; - document.body.className = 'baselinegrid'; - }, - - tearDown : function() { - - var styles = document.getElementsByTagName('style'); - for (var i = 0, len = styles.length; i < len; i++) { - if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); - } - }, - - testItShouldRemoveTopMarginOnFirstElement : function() { - - createCf().flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - var p = column.querySelector('p'); - - assertEquals(0, p.offsetTop); - assertEquals('0px', window.getComputedStyle(p).getPropertyValue('margin-top')); - }, - - testItShouldReduceColumnHeightToNearestMultipleOfLineheight : function() { - - document.body.classList.add('lineheight17'); - - createCf().flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(595, column.offsetHeight); - }, - - testItShouldReduceColumnHeightToNearestMultipleOfLineheight : function() { - - document.body.classList.add('lineheight17'); - - createCf().flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(595, column.offsetHeight); - }, - - testItShouldCalculateCorrectGridHeightWhenLineheightIsInEms : function() { - - document.body.classList.add('lineheight-in-ems'); - - createCf({ - columnGap : 20, - columnCount : 2, - pagePadding : 50, - pageArrangement : 'vertical', - }).flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(493, column.offsetHeight); - }, - - testItShouldCalculateCorrectGridHeightWhenLineheightIsInPercent : function() { - - document.body.classList.add('lineheight-in-percent'); - - createCf({ - columnGap : 20, - columnCount : 2, - pagePadding : 50, - pageArrangement : 'vertical', - }).flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(493, column.offsetHeight); - }, - - testItShouldCalculateCorrectGridHeightWhenLineheightIsInherit : function() { - - document.body.classList.add('lineheight-inherit'); - - createCf({ - columnGap : 20, - columnCount : 2, - pagePadding : 50, - pageArrangement : 'vertical', - }).flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(493, column.offsetHeight); - }, - - testItShouldCalculateCorrectGridHeightWhenLineheightIsMultiplier : function() { - - document.body.classList.add('lineheight-multiplier'); - - createCf({ - columnGap : 20, - columnCount : 2, - pagePadding : 50, - pageArrangement : 'vertical', - }).flow('

flowedContent

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(493, column.offsetHeight); - }, - - testItShouldCalculateCorrectGridHeightWhenLineheightIsNormal : function() { - - document.body.classList.add('lineheight-normal'); - - createCf().flow('

Test paragraph

 
 
 
 
 
 
 
 
 
 

'); - - var column = target.querySelector('.cf-column-1'); - var span = column.querySelector('.ten-elements'); - - var lineHight = span.offsetHeight / 10; - - assertEquals(0, (column.offsetHeight % lineHight) ); - }, - - testItShouldUseTheMedianLineheightFromASampleOfElements : function() { - - document.body.classList.add('lineheight-variable'); - - createCf().flow('

Test paragraph

Test paragraph

Test paragraph

Test paragraph

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(595, column.offsetHeight); - }, - - testItShouldAddMoreElementsIfThereAreNotEnoughToGetAMedianSample : function() { - - document.body.classList.add('lineheight-variable'); - - createCf().flow('

Test paragraph

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(595, column.offsetHeight); - }, - - testItShouldUseLineHeightIfSpecifiedAndNotCalculateIt : function() { - - document.body.classList.add('lineheight-variable'); - - createCf({ - columnGap : 25, - columnCount : 3, - lineHeight : 19 - }).flow('

Test paragraph

Test paragraph

Test paragraph

Test paragraph

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(589, column.offsetHeight); - }, - - testitShouldNotPadElementsByDefault : function() { - - document.body.classList.add('unpadded-parags'); - - createCf().flow('

Test paragraph

Test paragraph

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - var parags = column.getElementsByTagName('p'); - - assertEquals(53, parags[0].offsetHeight); - assertEquals(53, parags[1].offsetHeight); - assertEquals(53, parags[2].offsetHeight); - - assertEquals(0, parags[0].offsetTop); - assertEquals(73, parags[1].offsetTop); - assertEquals(146, parags[2].offsetTop); - }, - - testitShouldPadElementsWhenConfigured : function() { - - document.body.classList.add('unpadded-parags'); - - createCf({ - standardiseLineHeight : true, - }).flow('

Test paragraph

Test paragraph

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - var parags = column.getElementsByTagName('p'); - - assertEquals(60, parags[0].offsetHeight); - assertEquals(60, parags[1].offsetHeight); - assertEquals(60, parags[2].offsetHeight); - - assertEquals(0, parags[0].offsetTop); - assertEquals(80, parags[1].offsetTop); - assertEquals(160, parags[2].offsetTop); - }, - - testitShouldPadElementsIgnoringPlainTextNodes : function() { - - document.body.classList.add('unpadded-parags'); - - createCf({ - standardiseLineHeight : true, - }).flow('

Test paragraph

\n

Test paragraph

\n

Test paragraph

'); - - var column = target.querySelector('.cf-column-1'); - var parags = column.getElementsByTagName('p'); - - assertEquals(60, parags[0].offsetHeight); - assertEquals(60, parags[1].offsetHeight); - assertEquals(60, parags[2].offsetHeight); - - assertEquals(0, parags[0].offsetTop); - assertEquals(80, parags[1].offsetTop); - assertEquals(160, parags[2].offsetTop); - }, - - testRegressionItShouldNotMissOffEndOfLastElement : function() { - - document.body.classList.add('unequal-margin'); - - createCf().flow('

height1140

height40

'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertEquals('-20px', column3.childNodes[0].style.marginTop); - }, - - testRegressionItShouldNotRepeatALine : function() { - - document.body.classList.add('unequal-margin'); - - createCf().flow('

height600

height620

'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertEquals('-600px', column3.childNodes[0].style.marginTop); - }, - - testRegressionItShouldRemoveTopMarginOfFirstParagInAColumn : function() { - - document.body.classList.add('unequal-margin'); - - createCf().flow('

test parag

'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - -//*/ - -}); \ No newline at end of file diff --git a/test/ColumnWrapTest.js b/test/ColumnWrapTest.js deleted file mode 100644 index fdef458..0000000 --- a/test/ColumnWrapTest.js +++ /dev/null @@ -1,980 +0,0 @@ -/** - * FTColumnflow ColumnWrap test suite - * - * @copyright The Financial Times Limited [All Rights Reserved] -*/ - - -var _exactHeightWrap = '
height500
height100
height100
'; -var _wrapToPage2 = '
height600
height600
height600
height100
'; -var _overflowedElement = '
height500
height50
height100
'; - - -var cf, target, viewport; - -function createCf(config) { - cf = new FTColumnflow('targetid', 'viewportid', config || { - columnGap : 25, - columnCount : 3 - }); - target = document.getElementById('targetid'); - viewport = document.getElementById('viewportid'); - - return cf; -} - -TestCase('ColumnWrap', { - - setUp : function() { - document.body.innerHTML = '
'; - document.body.className = 'columnwrap'; - }, - - tearDown : function() { - var styles = document.getElementsByTagName('style'); - for (var i = 0, len = styles.length; i < len; i++) { - if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); - } - }, - - testItShouldAcceptNodeOrStringAsContentParameter : function() { - - createCf(); - - assertNoException(function test() { - cf.flow(document.createElement('p')); - }); - - assertNoException(function test() { - cf.flow('

foo

'); - }); - - assertException(function test() { - cf.flow(new Array); - }, 'FTColumnflowFlowedContentException'); - }, - - testItShouldAcceptNodeOrStringAsFixedParameter : function() { - - createCf(); - - assertNoException(function test() { - cf.flow('', document.createElement('p')); - }); - - assertNoException(function test() { - cf.flow('', '

foo

'); - }); - - assertException(function test() { - cf.flow('', new Array); - }, 'FTColumnflowFixedContentException'); - }, - - testItShouldNotChangeExistingTargetId : function() { - - createCf().flow(); - assertTrue(target instanceof HTMLElement); - }, - - testItShouldAddAnIdToTargetIfNotSet : function() { - - document.body.innerHTML = '
'; - var target = document.querySelector('.targetClass'); - - cf = new FTColumnflow(target, 'viewportid'); - cf.flow(); - - assertMatch(/^cf-target-\d{10}$/, target.id); - }, - - testItShouldCreateAHiddenPreloadArea : function() { - - createCf().flow(); - - var preload = target.querySelector('.cf-preload'); - - assertTrue(preload instanceof HTMLElement); - assertClassName('cf-page', preload); - - assertEquals('hidden', window.getComputedStyle(preload).getPropertyValue('visibility')); - assertEquals('absolute', window.getComputedStyle(preload).getPropertyValue('position')); - }, - - testItShouldCreateAPreloadColumnOfTheCorrectWidth : function() { - - createCf().flow(); - - var preload = target.querySelector('.cf-preload'); - var column = preload.querySelector('.cf-column'); - - assertEquals(1, preload.childNodes.length); - assertTrue(column instanceof HTMLElement); - assertEquals(250, column.clientWidth); - }, - - testItShouldRespectConfigColumnAndClassNamesInPreloadArea : function() { - - createCf({ - pageClass : 'mypage', - columnClass : 'mycol', - }).flow(); - - var preload = target.querySelector('.cf-preload'); - assertClassName('mypage', preload); - - var column = preload.childNodes[0]; - assertClassName('mycol', column); - }, - - testItShouldAddFlowedContentToPreloadArea : function() { - - createCf().flow('

Hello there!

'); - - var preload = target.querySelector('.cf-preload'); - var column = preload.childNodes[0]; - - assertMatch(/^Hello there!<\/p>$/, column.innerHTML); - }, - - testItShouldAddContentFromAnExistingElement : function() { - - var contentContainer = document.createElement('div'); - var flowedContent = document.createElement('p'); - var text = document.createTextNode('Hello there!'); - flowedContent.appendChild(text); - contentContainer.appendChild(flowedContent); - - createCf().flow(contentContainer); - - var preload = target.querySelector('.cf-preload'); - var column = preload.childNodes[0]; - - assertMatch(/^Hello there!<\/p>$/, column.innerHTML); - }, - - testItShouldLeaveOriginalContentUntouched : function() { - - var contentContainer = document.createElement('div'); - contentContainer.id = 'contentContainer'; - var flowedContent = document.createElement('p'); - var text = document.createTextNode('Hello there!'); - flowedContent.appendChild(text); - contentContainer.appendChild(flowedContent); - - document.getElementById('viewportid').appendChild(contentContainer); - - createCf().flow(contentContainer); - - assertEquals('

Hello there!

', document.getElementById('contentContainer').innerHTML); - }, - - testItShouldAddAShortParagraphToPage1Column1 : function() { - - createCf().flow('

Hello there!

'); - - var page = target.querySelector('.cf-page-1'); - assertTrue(page instanceof HTMLElement); - assertClassName('cf-page', page); - - var column = page.querySelector('.cf-column-1'); - assertTrue(column instanceof HTMLElement); - assertClassName('cf-column', column); - - assertMatch(/^Hello there!<\/p>$/, column.innerHTML); - }, - - testItShouldOverwriteTargetContents : function() { - - target.innerHTML = 'OVERWRITE'; - - createCf().flow('

Hello there!

'); - - assertNoMatch(/OVERWRITE/, target.innerHTML); - }, - - testItShouldSetCorrectPageDimensions : function() { - - createCf().flow('

Hello there!

'); - - var page = target.querySelector('.cf-page-1'); - - assertEquals(800, page.clientWidth); - assertEquals(600, page.clientHeight); - }, - - testItShouldRespectConfigColumnAndClassNames : function() { - - createCf({ - pageClass : 'mypage', - columnClass : 'mycol', - }).flow('

Hello there!

'); - - var page = target.querySelector('.mypage-1'); - assertClassName('mypage', page); - - var column = page.querySelector('.mycol-1'); - assertClassName('mycol', column); - }, - - testItShouldHideOverflowOnGeneratedColumns : function() { - - createCf().flow('

Hello there!

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals('hidden', window.getComputedStyle(column).getPropertyValue('overflow')); - }, - - testItShouldSetTheCorrectWidthAndHeightOnTheGeneratedColumn : function() { - - createCf().flow('

Hello there!

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(250, column.clientWidth); - assertEquals(600, column.clientHeight); - }, - - testItShouldSetCorrectAbsolutePositioningCss : function() { - - createCf().flow('

Hello there!

'); - - var page = target.querySelector('.cf-page-1'); - var column = target.querySelector('.cf-column-1'); - - assertEquals('relative', window.getComputedStyle(target).getPropertyValue('position')); - assertEquals('absolute', window.getComputedStyle(page).getPropertyValue('position')); - assertEquals('absolute', window.getComputedStyle(column).getPropertyValue('position')); - }, - - testItShouldSetTheCorrectPositionOnColumn1 : function() { - - createCf().flow('

Hello there!

'); - - var column = target.querySelector('.cf-column-1'); - - assertEquals(0, column.offsetTop); - assertEquals(0, column.offsetLeft); - }, - - testItShouldCreateASecondColumnWhenFirstIsFull : function() { - - createCf().flow(_exactHeightWrap); - - var column1 = target.querySelector('.cf-column-1'); - - var column2 = target.querySelector('.cf-column-2'); - assertTrue(column2 instanceof HTMLElement); - - }, - - testItShouldSetCorrectDimensionsAndPositionOnSecondColumn : function() { - - createCf().flow(_exactHeightWrap); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(250, column1.clientWidth); - assertEquals(600, column1.clientHeight); - - assertEquals(250, column2.clientWidth); - assertEquals(0, column2.offsetTop); - assertEquals(275, column2.offsetLeft); - }, - - testItShouldWriteCorrectElementsToColumns : function() { - - createCf().flow(_exactHeightWrap); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(2, column1.childNodes.length); - - assertClassName('height500', column1.childNodes[0]); - assertClassName('height100', column1.childNodes[1]); - - assertEquals(1, column2.childNodes.length); - - assertClassName('height100', column2.childNodes[0]); - }, - - testItShouldFillColumnsAndCreateSecondPage : function() { - - createCf().flow(_wrapToPage2); - - var page1 = target.querySelector('.cf-page-1'); - var page2 = target.querySelector('.cf-page-2'); - - assertEquals(3, page1.childNodes.length); - - assertTrue(page2 instanceof HTMLElement); - assertEquals(1, page2.childNodes.length); - - var page2col1 = page2.querySelector('.cf-column-1'); - - assertEquals(1, page2col1.childNodes.length); - assertClassName('height100', page2col1.childNodes[0]); - }, - - testItShouldDisplayPagesHorizontallyByDefault : function() { - - createCf().flow(_wrapToPage2); - - var page1 = target.querySelector('.cf-page-1'); - var page2 = target.querySelector('.cf-page-2'); - - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('top')); - - assertEquals('800px', window.getComputedStyle(page2).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page2).getPropertyValue('top')); - }, - - testItShouldDisplayPagesVerticallyWhenSpecified : function() { - - createCf({ - columnGap : 25, - columnCount : 3, - pageArrangement : 'vertical', - }).flow(_wrapToPage2); - - var page1 = target.querySelector('.cf-page-1'); - var page2 = target.querySelector('.cf-page-2'); - - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('top')); - - assertEquals('0px', window.getComputedStyle(page2).getPropertyValue('left')); - assertEquals('600px', window.getComputedStyle(page2).getPropertyValue('top')); - }, - - testItShouldAddPagePadding : function() { - - createCf({ - pagePadding : 50, - columnGap : 25, - columnCount : 5, - }).flow(_wrapToPage2 + _wrapToPage2); - - var page1 = target.querySelector('.cf-page-1'); - var page2 = target.querySelector('.cf-page-2'); - - assertEquals(800, page1.clientWidth); - assertEquals(600, page1.clientHeight); - - assertEquals(800, page2.clientWidth); - assertEquals(600, page2.clientHeight); - - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('top')); - - assertEquals('800px', window.getComputedStyle(page2).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page2).getPropertyValue('top')); - - assertEquals(50, page1.querySelector('.cf-column-1').offsetLeft); - assertEquals(120, page1.querySelector('.cf-column-1').offsetWidth); - - assertEquals(195, page1.querySelector('.cf-column-2').offsetLeft); - assertEquals(630, page1.querySelector('.cf-column-5').offsetLeft); - - assertEquals(50, page2.querySelector('.cf-column-1').offsetLeft); - }, - - testItShouldAddVerticalPagePadding : function() { - - createCf({ - pagePadding : 50, - columnGap : 25, - columnCount : 5, - pageArrangement : 'vertical', - }).flow(_wrapToPage2 + _wrapToPage2); - - var page1 = target.querySelector('.cf-page-1'); - var page2 = target.querySelector('.cf-page-2'); - - assertEquals(800, page1.clientWidth); - assertEquals(600, page1.clientHeight); - - assertEquals(800, page2.clientWidth); - assertEquals(600, page2.clientHeight); - - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('left')); - assertEquals('0px', window.getComputedStyle(page1).getPropertyValue('top')); - - assertEquals('0px', window.getComputedStyle(page2).getPropertyValue('left')); - assertEquals('600px', window.getComputedStyle(page2).getPropertyValue('top')); - - assertEquals(0, page1.querySelector('.cf-column-1').offsetLeft); - assertEquals(50, page1.querySelector('.cf-column-1').offsetTop); - assertEquals(140, page1.querySelector('.cf-column-1').offsetWidth); - assertEquals(500, page1.querySelector('.cf-column-1').offsetHeight); - - assertEquals(50, page2.querySelector('.cf-column-1').offsetTop); - }, - - testItShouldRepeatAnOverflowedElementOnTheNextColumn : function() { - - createCf().flow(_overflowedElement); - - var column1 = target.querySelector('.cf-column-1'); - - assertClassName('height100', column1.childNodes[column1.childNodes.length - 1]); - - var column2 = target.querySelector('.cf-column-2'); - assertTrue(column2 instanceof HTMLElement); - - assertEquals(1, column2.childNodes.length); - assertClassName('height100', column2.childNodes[0]); - - assertEquals(column1.childNodes[2].innerHTML, column2.childNodes[0].innerHTML); - }, - - testItShouldSetNegativeTopMarginOnRemainderOfOverflowedElement : function() { - - createCf().flow(_overflowedElement); - - var column2 = target.querySelector('.cf-column-2'); - var element = column2.childNodes[0]; - - assertEquals('-50px', window.getComputedStyle(element).getPropertyValue('margin-top')); - }, - - testItShouldCorrectlyWrapALargeElementOverManyColumns : function() { - - createCf().flow('
height300
height1000
'); - - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals('-300px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); - assertEquals('-900px', window.getComputedStyle(column3.childNodes[0]).getPropertyValue('margin-top')); - }, - - testItShouldCorrectlyWrapAHugeElementOverManyColumns : function() { - - createCf().flow('
height3000
'); - - var page2 = target.querySelector('.cf-page-2'); - var p2col2 = page2.querySelector('.cf-column-2'); - - assertEquals('-2400px', window.getComputedStyle(p2col2.childNodes[0]).getPropertyValue('margin-top')); - assertNull(page2.querySelector('.cf-column-3')); - }, - - testItShouldWrapPlainTextInParagraphTags : function() { - - createCf().flow('plain text'); - - var column = target.querySelector('.cf-column-1'); - - assertMatch(/^plain text<\/p>$/, column.innerHTML); - }, - - testItShouldIgnoreEmptyTextNodes : function() { - - createCf().flow('\n

parag 1

\n

parag 2

\n'); - - var column = target.querySelector('.cf-column-1'); - - assertMatch(/^parag 1<\/p>parag 2<\/p>$/, column.innerHTML); - }, - - testItShouldNotCarryParagraphBottomMarginsOverToNextColumn : function() { - - createCf().flow('
simulated-parags
simulated-parags
simulated-parags
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(2, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - var element = column2.childNodes[0]; - assertEquals('0px', element.style.marginTop); - }, - - testItShouldNotWrapAnElementWithNowrapClass : function() { - - createCf().flow('
height500
height200 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals('1 elem in col 1', 1, column1.childNodes.length); - assertEquals('1 elem in col 2', 1, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertClassName('nowrap', element); - assertEquals('0px', element.style.marginTop); - }, - - testItShouldNotMoveAnElementWithNowrapClassWhichFitsInAColumn : function() { - - createCf().flow('
height500
height100 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(2, column1.childNodes.length); - assertNull(column2); - }, - - testItShouldCorrectlyPositionSuccessiveNowrapElements : function() { - - createCf().flow('
height500
height500 nowrap
height500 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertEquals('0px', column2.childNodes[0].style.marginTop); - assertEquals('0px', column3.childNodes[0].style.marginTop); - }, - - testItShouldCropATallNowrapElement : function() { - - createCf().flow('
height1000 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertNull(column2); - }, - - testItShouldMoveThenCropATallNowrapElement : function() { - - createCf().flow('
height500
height1000 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - assertNull(column3); - - var element = column2.childNodes[0]; - - assertClassName('nowrap', element); - assertEquals('0px', element.style.marginTop); - }, - - testItShouldNotWrapAnElementWhichMatchesNoWrapOnTags : function() { - - createCf({ - columnGap : 25, - columnCount : 3, - noWrapOnTags : ['section'], - }).flow('
height500
height200 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals('1 elem in col 1', 1, column1.childNodes.length); - assertEquals('1 elem in col 2', 1, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertTagName('section', element); - assertEquals('0px', element.style.marginTop); - }, - - testItShouldIgnoreCaseOfNoWrapOnTags : function() { - - createCf({ - columnGap : 25, - columnCount : 3, - noWrapOnTags : ['SECTION'], - }).flow('
height500
height200 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals('1 elem in col 1', 1, column1.childNodes.length); - assertEquals('1 elem in col 2', 1, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertTagName('section', element); - assertEquals('0px', element.style.marginTop); - }, - - testItShouldNotWrapAnElementWithKeepwithnextClass : function() { - - createCf().flow('
height500
height200 keepwithnext
height100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertClassName('keepwithnext', element); - assertEquals('0px', element.style.marginTop); - }, - - testItShouldWrapAKeepwithnextElementWhenItsTheFinalElement : function() { - - createCf().flow('
height500
height200 keepwithnext
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(2, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertClassName('keepwithnext', element); - assertEquals('-100px', element.style.marginTop); - }, - - testItShouldMoveThenCropATallKeepwithnextElement : function() { - - createCf().flow('
height500
height1000 keepwithnext
height100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertClassName('keepwithnext', column2.childNodes[0]); - assertEquals('0px', column2.childNodes[0].style.marginTop); - - assertClassName('height100', column3.childNodes[0]); - assertEquals('0px', column3.childNodes[0].style.marginTop); - }, - - testItShouldCropATallKeepwithnextElement : function() { - - createCf().flow('
height1000 keepwithnext
height100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - assertClassName('height100', column2.childNodes[0]); - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testItShouldMoveAKeepwithnextElementToJoinFollowingPlainTextElement : function() { - - createCf().flow('
height500
height100 keepwithnext
height100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - - assertClassName('keepwithnext', column2.childNodes[0]); - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testItShouldIgnoreKeepwithnextClassOnFinalElement : function() { - - createCf().flow('
height400
height100 keepwithnext
'); - - var column1 = target.querySelector('.cf-column-1'); - - assertEquals(2, column1.childNodes.length); - assertNull(target.querySelector('.cf-column-2')); - }, - - testItShouldCorrectlyHandleAnElementWithBothKeepwithnextAndNowrapClasses : function() { - - createCf().flow('
height500
height200 keepwithnext
height100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testNowrapShouldNotAffectFollowingColumns : function() { - - createCf().flow('
height500
height200 nowrap
height500
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertEquals('-400px', column3.childNodes[0].style.marginTop); - }, - - testKeepwithnextShouldNotAffectFollowingColumns : function() { - - createCf().flow('
height500
height100 keepwithnext
height500
height500
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertEquals('0px', column2.childNodes[0].style.marginTop); - assertEquals('0px', column3.childNodes[0].style.marginTop); - }, - - testItShouldCorrectlyPositionANowrapFollowingAKeepwithnext : function() { - - createCf().flow('
height400
height100 keepwithnext
height200 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - assertNull(target.querySelector('.cf-column-3')); - - assertClassName('keepwithnext', column2.childNodes[0]); - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testItShouldObeyKeepwithnextWhenNextElementHasNowrapClassAndOverflows : function() { - - createCf().flow('
height400
height100 keepwithnext
height200 nowrap
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - - var element = column2.childNodes[0]; - - assertClassName('keepwithnext', element); - assertEquals('0px', element.style.marginTop); - }, - - testRegression1ItShouldUpdateColumnHeightAfterAnElementIsCropped : function() { - - createCf().flow('
700 keepwithnext
300
300
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - assertNull(target.querySelector('.cf-column-3')); - }, - - testRegression2MissingLastElement : function() { - - createCf().flow('
700
200 keepwithnext
100
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(3, column2.childNodes.length); - assertNull(target.querySelector('.cf-column-3')); - - assertClassName('height700', column2.childNodes[0]); - assertEquals('-600px', column2.childNodes[0].style.marginTop); - }, - - testRegression5LargeSpaceAdded : function() { - - createCf().flow('
700
200 nowrap keepwithnext
500
'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - var column3 = target.querySelector('.cf-column-3'); - - assertEquals(1, column1.childNodes.length); - assertEquals(3, column2.childNodes.length); - assertEquals(1, column3.childNodes.length); - - assertClassName('height500', column3.childNodes[0]); - assertEquals('-300px', column3.childNodes[0].style.marginTop); - }, - - testRegression7ItShouldNotGetIntoAnEndlessLoop : function() { - - // With the loop-protection removed, this test should cause an endless loop if the bug is not fixed. - - createCf().flow('
1: 600 keepwithnext
2: 700
'); - - }, - - testRegression10TheLastElementShouldNotBeCropped : function() { - - createCf().flow('
5: 500 keepwithnext
7: 200 keepwithnext
'); - - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(2, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - assertEquals('-100px', column2.childNodes[0].style.marginTop); - }, - - testRegression10SecondElementShouldBeInColumn2 : function() { - - createCf().flow('
2: 300 keepwithnext
3: 400 keepwithnext
4: 200
'); - - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(2, column2.childNodes.length); - - assertClassName('height400', column2.childNodes[0]); - assertClassName('keepwithnext', column2.childNodes[0]); - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testRegressionItShouldCorrectlyPlaceSuccessiveFullheightElements : function() { - - createCf().flow('

height600

height600

'); - - var column1 = target.querySelector('.cf-column-1'); - var column2 = target.querySelector('.cf-column-2'); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - assertNull(target.querySelector('.cf-column-3')); - assertEquals('0px', column2.childNodes[0].style.marginTop); - }, - - testItShouldCorrectlyReportSinglePageCount : function() { - - createCf({ - columnCount : 1 - }).flow('
height300
'); - - assertEquals(1, cf.pageCount); - }, - - testItShouldCorrectlyReportLargerPageCount : function() { - - createCf({ - columnCount : 1 - }).flow('
height3000
'); - - assertEquals(5, cf.pageCount); - }, - - testItShouldAddExplicitWidthAndHeightToTarget : function() { - - createCf().flow('
height300
'); - - assertEquals('800px', target.style.width); - assertEquals('800px', window.getComputedStyle(target).getPropertyValue('width')); - assertEquals('600px', window.getComputedStyle(target).getPropertyValue('height')); - }, - - testItShouldCorrectlyReportLayoutDimensions : function() { - - createCf({ - columnGap : 20, - columnCount : 4, - pagePadding : 50 - }).flow('
height300
'); - - var dimesions = cf.layoutDimensions; - - assertEquals(700, dimesions.pageInnerWidth); - assertEquals(600, dimesions.pageInnerHeight); - assertEquals(0, dimesions.colDefaultTop); - assertEquals(50, dimesions.colDefaultLeft); - assertEquals(4, dimesions.columnCount); - assertEquals(160, dimesions.columnWidth); - assertEquals(20, dimesions.columnGap); - }, - - - -/* - testItShouldSetExplicitHeightOnImagesWithSpecifiedAspectRatio : function() { - - createCf().flow('
height300
height300
'); - - var page = target.querySelector('.cf-page-1'); - var column1 = page.querySelector('.cf-column-1'); - var column2 = page.querySelector('.cf-column-2'); - var img = column1.querySelector('img'); - var div2 = column2.querySelector('div'); - - assertEquals("200px", img.style.width); - assertEquals("100px", img.style.height); - assertEquals(200, parseInt(window.getComputedStyle(img).getPropertyValue('width'))); - assertEquals(100, parseInt(window.getComputedStyle(img).getPropertyValue('height'))); - - assertEquals('-200px', div2.style.marginTop); - }, - */ - - -//*/ - - -/* - - testItShouldObeyAllHistoricalKeepwithnextElementsWhichFitInNextColumn : function() { - - createCf().flow('
1 height100 keepwithnext
2 height100 plaintext
3 height100 keepwithnext
4 height100 keepwithnext
5 height100 keepwithnext
6 height100 keepwithnext
7 height100 plaintext
'); - }, - - -testItShouldMoveLastInAStringOfKeepwithnextElementIntoNextColumn - -testItShouldSplitALongStreamOfKeepwithnextElementsWhenAColumnIsFull - -testItShouldObeyAllHistoricalKeepwithnextElementsUntilStartOfColumn - - - - - -/* - -Regression 4 - The two 100 keepwithnext should be in col 1. - -
100
100
200 nowrap
100 nowrap keepwithnext
100 nowrap keepwithnext
500 keepwithnext
200
300
- -*/ - - -// Consider some 'typographical measure' logic - reduce the number of columns per page if the measure is too small (because the font size is too large) -// We should remove any padding on the viewport, and any padding or margin on the articles. -// Run Arrhythmia("body").validateRhythm(); (https://github.com/mattbaker/Arrhythmia) to check vertical rhythm after I've added padding functionality. -// Add 'near-parag-14' or similar class to images, and attempt to get them onto the same page. If an inline image overflows the bottom of a column, there are two options: 1) leave whitespace and place image at top of next col. 2) start the paragraph of text, and place image at top of next col, continuing parag afterwards. -// Allow column-spans for inline images. This is a future feature request. -// Consider a breakafter class, or similar, to always break after this element. -// Shouldn't most tags (img, headings, etc.) be nowrap by default? Perhaps have a default list of tags which are NOT nowrap, and allow it to be overridden. - - -// */ - -}); \ No newline at end of file diff --git a/test/ReflowTest.js b/test/ReflowTest.js deleted file mode 100644 index 293c821..0000000 --- a/test/ReflowTest.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * FTColumnflow Reflow test suite - * - * @copyright The Financial Times Limited [All Rights Reserved] -*/ - - -function createCf(config) { - cf = new FTColumnflow('targetid', 'viewportid', config || { - columnGap : 25, - columnCount : 3 - }); - target = document.getElementById('targetid'); - viewport = document.getElementById('viewportid'); - - return cf; -} - - -TestCase('Reflow', { - - setUp : function() { - document.body.innerHTML = '
'; - document.body.className = 'reflow'; - }, - - tearDown : function() { - - var styles = document.getElementsByTagName('style'); - for (var i = 0, len = styles.length; i < len; i++) { - if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); - } - }, - - testItShouldRewriteCssBlockAndNotAddItAgain : function() { - - var lengthBefore = document.getElementsByTagName('style').length; - - createCf().flow('
height600
'); - - var lengthAfter = document.getElementsByTagName('style').length; - - cf.flow(); - - assertEquals(lengthAfter, document.getElementsByTagName('style').length); - }, - -/* - testItShouldReflow : function() { - - // page is 800 x 600, columns are 350 x 600 - createCf({ - columnGap : 100, - columnCount : 2, - }).flow('
height3000
'); - - // Change viewport dimensions - viewport.style.width = "600px"; - viewport.style.height = "500px"; - - // page is 600 x 500, columns are 250 x 500 - cf.reflow(); - - assertEquals(1, target.querySelectorAll('.cf-page-1').length); - - var page = target.querySelector('.cf-page-1'); - - assertTrue(page instanceof HTMLElement); - assertEquals(600, page.clientWidth); - assertEquals(500, page.clientHeight); - - var column1 = page.querySelector('.cf-column-1'); - var column2 = page.querySelector('.cf-column-2'); - - assertEquals(250, column1.clientWidth); - assertEquals(500, column1.clientHeight); - - assertEquals(1, column1.childNodes.length); - assertEquals(1, column2.childNodes.length); - - assertEquals('-500px', column2.childNodes[0].style.marginTop); - }, - */ - - testItShouldReflowUsingNewConfig : function() { - - createCf({ - columnGap : 100, - columnCount : 2, - }).flow('
height3000
'); - - var column1 = target.querySelector('.cf-page-1 .cf-column-1'); - - assertEquals(350, column1.clientWidth); - assertEquals(600, column1.clientHeight); - assertEquals(2, target.querySelectorAll('.cf-page-1 .cf-column').length); - assertEquals(1, column1.childNodes.length); - assertClassName('height3000', column1.childNodes[0]); - - cf.reflow({ - columnGap : 25, - columnCount : 3, - }); - - var column1 = target.querySelector('.cf-page-1 .cf-column-1'); - - assertEquals(250, column1.clientWidth); - assertEquals(600, column1.clientHeight); - assertEquals(3, target.querySelectorAll('.cf-page-1 .cf-column').length); - assertEquals(1, column1.childNodes.length); - }, - - testItShouldRemoveStylesAndDomNodesOnDestroy : function() { - - var stylesBefore = document.querySelectorAll('style').length; - - createCf().flow('
height3000
'); - - assertNotUndefined(target); - assertNotEquals('', target.innerHTML); - assertEquals((stylesBefore + 1), document.querySelectorAll('style').length); - - cf.destroy(); - - assertNull(document.getElementById('targetid')); - assertEquals(stylesBefore, document.querySelectorAll('style').length); - }, - - -/* - - -// NB - height sanitizing routine should not round up every time the line-height is changed! Need to work with the original, untouched elements and padding each time, and round up without modifying them somehow. - -//*/ - -}); \ No newline at end of file diff --git a/test/baselinegrid-test.js b/test/baselinegrid-test.js new file mode 100644 index 0000000..b43b561 --- /dev/null +++ b/test/baselinegrid-test.js @@ -0,0 +1,276 @@ +/** + * FTColumnflow BaselineGrid test suite + * + * @copyright The Financial Times Limited [All Rights Reserved] +*/ + + +buster.testCase('BaselineGrid', { + setUp : function(done) { + document.body.innerHTML = '
'; + addStylesheets(['all.css', 'baselinegrid.css'], done); + }, + + tearDown : function() { + removeStyleSheets(); + document.body.className = ''; + }, + + 'ShouldRemoveTopMarginOnFirstElement' : function() { + + createCf().flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + var p = column.querySelector('p'); + + assert.match(p.offsetTop, 0); + assert.match(cssProp(p, 'margin-top'), '0px'); + }, + + 'ShouldReduceColumnHeightToNearestMultipleOfLineheight' : function() { + + document.body.className = 'lineheight17'; + + createCf().flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 595); + }, + + 'ShouldReduceColumnHeightToNearestMultipleOfLineheight' : function() { + + document.body.className = 'lineheight17'; + + createCf().flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 595); + }, + + 'ShouldCalculateCorrectGridHeightWhenLineheightIsInEms' : function() { + + document.body.className = 'lineheight-in-ems'; + + createCf({ + columnGap : 20, + columnCount : 2, + pagePadding : 50, + pageArrangement : 'vertical', + }).flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 493); + }, + + 'ShouldCalculateCorrectGridHeightWhenLineheightIsInPercent' : function() { + + document.body.className = 'lineheight-in-percent'; + + createCf({ + columnGap : 20, + columnCount : 2, + pagePadding : 50, + pageArrangement : 'vertical', + }).flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 493); + }, + + 'ShouldCalculateCorrectGridHeightWhenLineheightIsInherit' : function() { + + document.body.className = 'lineheight-inherit'; + + createCf({ + columnGap : 20, + columnCount : 2, + pagePadding : 50, + pageArrangement : 'vertical', + }).flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 493); + }, + + 'ShouldCalculateCorrectGridHeightWhenLineheightIsMultiplier' : function() { + + document.body.className = 'lineheight-multiplier'; + + createCf({ + columnGap : 20, + columnCount : 2, + pagePadding : 50, + pageArrangement : 'vertical', + }).flow('

flowedContent

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 493); + }, + + 'ShouldCalculateCorrectGridHeightWhenLineheightIsNormal' : function() { + + document.body.className = 'lineheight-normal'; + + createCf().flow('

Test paragraph

 
 
 
 
 
 
 
 
 
 

'); + + var column = target.querySelector('.cf-column-1'); + var span = column.querySelector('.ten-elements'); + + var lineHight = span.offsetHeight / 10; + + assert.match((column.offsetHeight % lineHight) , 0); + }, + + 'ShouldUseTheMedianLineheightFromASampleOfElements' : function() { + + document.body.className = 'lineheight-variable'; + + createCf().flow('

Test paragraph

Test paragraph

Test paragraph

Test paragraph

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 595); + }, + + 'ShouldAddMoreElementsIfThereAreNotEnoughToGetAMedianSample' : function() { + + document.body.className = 'lineheight-variable'; + + createCf().flow('

Test paragraph

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 595); + }, + + 'ShouldUseLineHeightIfSpecifiedAndNotCalculateIt' : function() { + + document.body.className = 'lineheight-variable'; + + createCf({ + columnGap : 25, + columnCount : 3, + lineHeight : 19 + }).flow('

Test paragraph

Test paragraph

Test paragraph

Test paragraph

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetHeight, 589); + }, + + 'ShouldNotPadElementsByDefault' : function() { + + document.body.className = 'unpadded-parags'; + + createCf().flow('

Test paragraph

Test paragraph

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + var parags = column.getElementsByTagName('p'); + + assert.match(parags[0].offsetHeight, 53); + assert.match(parags[1].offsetHeight, 53); + assert.match(parags[2].offsetHeight, 53); + + assert.match(parags[0].offsetTop, 0); + assert.match(parags[1].offsetTop, 73); + assert.match(parags[2].offsetTop, 146); + }, + + 'ShouldPadElementsWhenConfigured' : function() { + + document.body.className = 'unpadded-parags'; + + createCf({ + standardiseLineHeight : true, + }).flow('

Test paragraph

Test paragraph

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + var parags = column.getElementsByTagName('p'); + + assert.match(parags[0].offsetHeight, 60); + assert.match(parags[1].offsetHeight, 60); + assert.match(parags[2].offsetHeight, 60); + + assert.match(parags[0].offsetTop, 0); + assert.match(parags[1].offsetTop, 80); + assert.match(parags[2].offsetTop, 160); + }, + + 'ShouldPadElementsIgnoringPlainTextNodes' : function() { + + document.body.className = 'unpadded-parags'; + + createCf({ + standardiseLineHeight : true, + }).flow('

Test paragraph

\n

Test paragraph

\n

Test paragraph

'); + + var column = target.querySelector('.cf-column-1'); + var parags = column.getElementsByTagName('p'); + + assert.match(parags[0].offsetHeight, 60); + assert.match(parags[1].offsetHeight, 60); + assert.match(parags[2].offsetHeight, 60); + + assert.match(parags[0].offsetTop, 0); + assert.match(parags[1].offsetTop, 80); + assert.match(parags[2].offsetTop, 160); + }, + + 'RegressionItShouldNotMissOffEndOfLastElement' : function() { + + document.body.className = 'unequal-margin'; + + createCf().flow('

height1140

height40

'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + assert.match(column3.childNodes.length, 1); + + assert.match(column3.childNodes[0].style.marginTop, '-20px'); + }, + + 'RegressionItShouldNotRepeatALine' : function() { + + document.body.className = 'unequal-margin'; + + createCf().flow('

height600

height620

'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + assert.match(column3.childNodes.length, 1); + + assert.match(column3.childNodes[0].style.marginTop, '-600px'); + }, + + 'RegressionItShouldRemoveTopMarginOfFirstParagInAColumn' : function() { + + document.body.className = 'unequal-margin'; + + createCf().flow('

test parag

'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + +//*/ + +}); \ No newline at end of file diff --git a/test/buster.js b/test/buster.js new file mode 100644 index 0000000..5de6342 --- /dev/null +++ b/test/buster.js @@ -0,0 +1,58 @@ +var config = module.exports; + + +config["My tests"] = { + rootPath: "../", + environment: "browser", // or "node" + sources: [ + "src/FTColumnflow.js", + ], + tests: [ + "test/*-test.js" + ], + testHelpers: [ + "test/helpers/*.js" + ], + resources: [ + { + path: "/", + content: '\n' + + '\n' + + ' \n' + + ' Custom Buster.JS test bed\n' + + ' \n' + + ' \n' + + ' \n' + + '' + }, + { + path: '/all.css', + file: 'test/css/AllTests.css', + }, + { + path: '/config.css', + file: 'test/css/ConfigTest.css', + }, + { + path: '/columnwrap.css', + file: 'test/css/ColumnWrapTest.css', + }, + { + path: '/baselinegrid.css', + file: 'test/css/BaselineGridTest.css', + }, + { + path: '/fixedelements.css', + file: 'test/css/FixedElementsTest.css', + }, + { + path: '/reflow.css', + file: 'test/css/ReflowTest.css', + } + ] +} + +// Add more configuration groups as needed + + + diff --git a/test/columnwrap-test.js b/test/columnwrap-test.js new file mode 100644 index 0000000..5bfae48 --- /dev/null +++ b/test/columnwrap-test.js @@ -0,0 +1,950 @@ +/** + * FTColumnflow ColumnWrap test suite + * + * @copyright The Financial Times Limited [All Rights Reserved] +*/ + +"use strict"; + +var _exactHeightWrap = '
height500
height100
height100
'; +var _wrapToPage2 = '
height600
height600
height600
height100
'; +var _overflowedElement = '
height500
height50
height100
'; + + + + + +buster.testCase('ColumnWrap', { + + setUp : function(done) { + document.body.innerHTML = '
'; + addStylesheets(['all.css', 'columnwrap.css'], done); + }, + + tearDown : function() { + removeStyleSheets(); + document.body.className = ''; + }, + + 'ShouldAcceptNodeOrStringAsContentParameter' : function() { + + createCf(); + + refute.exception(function test() { + cf.flow(document.createElement('p')); + }); + + refute.exception(function test() { + cf.flow('

foo

'); + }); + + assert.exception(function test() { + cf.flow(new Array); + }, 'FTColumnflowFlowedContentException'); + }, + + 'ShouldAcceptNodeOrStringAsFixedParameter' : function() { + + createCf(); + + refute.exception(function test() { + cf.flow('', document.createElement('p')); + }); + + refute.exception(function test() { + cf.flow('', '

foo

'); + }); + + assert.exception(function test() { + cf.flow('', new Array); + }, 'FTColumnflowFixedContentException'); + }, + + 'ShouldNotChangeExistingTargetId' : function() { + + createCf().flow(); + assert(target instanceof HTMLElement); + }, + + 'ShouldAddAnIdToTargetIfNotSet' : function() { + + document.body.innerHTML = '
'; + var target = document.querySelector('.targetClass'); + + new FTColumnflow(target, 'viewportid').flow(); + + assert.match(target.id, /^cf-target-\d{10}$/); + }, + + 'ShouldCreateAHiddenPreloadArea' : function() { + + createCf().flow(); + + var preload = target.querySelector('.cf-preload'); + + assert(preload instanceof HTMLElement); + assert.className(preload, 'cf-page'); + + assert.match(cssProp(preload, 'visibility'), 'hidden'); + assert.match(cssProp(preload, 'position'), 'absolute'); + }, + + 'ShouldCreateAPreloadColumnOfTheCorrectWidth' : function() { + + createCf().flow(); + + var preload = target.querySelector('.cf-preload'); + var column = preload.querySelector('.cf-column'); + + assert.match(preload.childNodes.length, 1); + assert(column instanceof HTMLElement); + assert.match(column.clientWidth, 250); + }, + + 'ShouldRespectConfigColumnAndClassNamesInPreloadArea' : function() { + + createCf({ + pageClass : 'mypage', + columnClass : 'mycol', + }).flow(); + + var preload = target.querySelector('.cf-preload'); + assert.className(preload, 'mypage'); + + var column = preload.childNodes[0]; + assert.className(column, 'mycol'); + }, + + 'ShouldAddFlowedContentToPreloadArea' : function() { + + createCf().flow('

Hello there!

'); + + var preload = target.querySelector('.cf-preload'); + var column = preload.childNodes[0]; + + assert.match(column.innerHTML, /^Hello there!<\/p>$/); + }, + + 'ShouldAddContentFromAnExistingElement' : function() { + + var contentContainer = document.createElement('div'); + var flowedContent = document.createElement('p'); + var text = document.createTextNode('Hello there!'); + flowedContent.appendChild(text); + contentContainer.appendChild(flowedContent); + + createCf().flow(contentContainer); + + var preload = target.querySelector('.cf-preload'); + var column = preload.childNodes[0]; + + assert.match(column.innerHTML, /^Hello there!<\/p>$/); + }, + + 'ShouldLeaveOriginalContentUntouched' : function() { + + var contentContainer = document.createElement('div'); + contentContainer.id = 'contentContainer'; + var flowedContent = document.createElement('p'); + var text = document.createTextNode('Hello there!'); + flowedContent.appendChild(text); + contentContainer.appendChild(flowedContent); + + document.getElementById('viewportid').appendChild(contentContainer); + + createCf().flow(contentContainer); + + assert.match(document.getElementById('contentContainer').innerHTML, '

Hello there!

'); + }, + + 'ShouldAddAShortParagraphToPage1Column1' : function() { + + createCf().flow('

Hello there!

'); + + var page = target.querySelector('.cf-page-1'); + assert(page instanceof HTMLElement); + assert.className(page, 'cf-page'); + + var column = page.querySelector('.cf-column-1'); + assert(column instanceof HTMLElement); + assert.className(column, 'cf-column'); + + assert.match(column.innerHTML, /^Hello there!<\/p>$/); + }, + + 'ShouldOverwriteTargetContents' : function() { + + target.innerHTML = 'OVERWRITE'; + + createCf().flow('

Hello there!

'); + + refute.match(target.innerHTML, /OVERWRITE/); + }, + + 'ShouldSetCorrectPageDimensions' : function() { + + createCf().flow('

Hello there!

'); + + var page = target.querySelector('.cf-page-1'); + + assert.match(page.clientWidth, 800); + assert.match(page.clientHeight, 600); + }, + + 'ShouldRespectConfigColumnAndClassNames' : function() { + + createCf({ + pageClass : 'mypage', + columnClass : 'mycol', + }).flow('

Hello there!

'); + + var page = target.querySelector('.mypage-1'); + assert.className(page, 'mypage'); + + var column = page.querySelector('.mycol-1'); + assert.className(column, 'mycol'); + }, + + 'ShouldHideOverflowOnGeneratedColumns' : function() { + + createCf().flow('

Hello there!

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(cssProp(column, 'overflow'), 'hidden'); + }, + + 'ShouldSetTheCorrectWidthAndHeightOnTheGeneratedColumn' : function() { + + createCf().flow('

Hello there!

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.clientWidth, 250); + assert.match(column.clientHeight, 600); + }, + + 'ShouldSetCorrectAbsolutePositioningCss' : function() { + + createCf().flow('

Hello there!

'); + + var page = target.querySelector('.cf-page-1'); + var column = target.querySelector('.cf-column-1'); + + assert.match(cssProp(target, 'position'), 'relative'); + assert.match(cssProp(page, 'position'), 'absolute'); + assert.match(cssProp(column, 'position'), 'absolute'); + }, + + 'ShouldSetTheCorrectPositionOnColumn1' : function() { + + createCf().flow('

Hello there!

'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.offsetTop, 0); + assert.match(column.offsetLeft, 0); + }, + + 'ShouldCreateASecondColumnWhenFirstIsFull' : function() { + + createCf().flow(_exactHeightWrap); + + var column1 = target.querySelector('.cf-column-1'); + + var column2 = target.querySelector('.cf-column-2'); + assert(column2 instanceof HTMLElement); + + }, + + 'ShouldSetCorrectDimensionsAndPositionOnSecondColumn' : function() { + + createCf().flow(_exactHeightWrap); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.clientWidth, 250); + assert.match(column1.clientHeight, 600); + + assert.match(column2.clientWidth, 250); + assert.match(column2.offsetTop, 0); + assert.match(column2.offsetLeft, 275); + }, + + 'ShouldWriteCorrectElementsToColumns' : function() { + + createCf().flow(_exactHeightWrap); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 2); + + assert.className(column1.childNodes[0], 'height500'); + assert.className(column1.childNodes[1], 'height100'); + + assert.match(column2.childNodes.length, 1); + + assert.className(column2.childNodes[0], 'height100'); + }, + + 'ShouldFillColumnsAndCreateSecondPage' : function() { + + createCf().flow(_wrapToPage2); + + var page1 = target.querySelector('.cf-page-1'); + var page2 = target.querySelector('.cf-page-2'); + + assert.match(page1.childNodes.length, 3); + + assert(page2 instanceof HTMLElement); + assert.match(page2.childNodes.length, 1); + + var page2col1 = page2.querySelector('.cf-column-1'); + + assert.match(page2col1.childNodes.length, 1); + assert.className(page2col1.childNodes[0], 'height100'); + }, + + 'ShouldDisplayPagesHorizontallyByDefault' : function() { + + createCf().flow(_wrapToPage2); + + var page1 = target.querySelector('.cf-page-1'); + var page2 = target.querySelector('.cf-page-2'); + + assert.match(cssProp(page1, 'left'), '0px'); + assert.match(cssProp(page1, 'top'), '0px'); + + assert.match(cssProp(page2, 'left'), '800px'); + assert.match(cssProp(page2, 'top'), '0px'); + }, + + 'ShouldDisplayPagesVerticallyWhenSpecified' : function() { + + createCf({ + columnGap : 25, + columnCount : 3, + pageArrangement : 'vertical', + }).flow(_wrapToPage2); + + var page1 = target.querySelector('.cf-page-1'); + var page2 = target.querySelector('.cf-page-2'); + + assert.match(cssProp(page1, 'left'), '0px'); + assert.match(cssProp(page1, 'top'), '0px'); + + assert.match(cssProp(page2, 'left'), '0px'); + assert.match(cssProp(page2, 'top'), '600px'); + }, + + 'ShouldAddPagePadding' : function() { + + createCf({ + pagePadding : 50, + columnGap : 25, + columnCount : 5, + }).flow(_wrapToPage2 + _wrapToPage2); + + var page1 = target.querySelector('.cf-page-1'); + var page2 = target.querySelector('.cf-page-2'); + + assert.match(page1.clientWidth, 800); + assert.match(page1.clientHeight, 600); + + assert.match(page2.clientWidth, 800); + assert.match(page2.clientHeight, 600); + + assert.match(cssProp(page1, 'left'), '0px'); + assert.match(cssProp(page1, 'top'), '0px'); + + assert.match(cssProp(page2, 'left'), '800px'); + assert.match(cssProp(page2, 'top'), '0px'); + + assert.match(page1.querySelector('.cf-column-1').offsetLeft, 50); + assert.match(page1.querySelector('.cf-column-1').offsetWidth, 120); + + assert.match(page1.querySelector('.cf-column-2').offsetLeft, 195); + assert.match(page1.querySelector('.cf-column-5').offsetLeft, 630); + + assert.match(page2.querySelector('.cf-column-1').offsetLeft, 50); + }, + + 'ShouldAddVerticalPagePadding' : function() { + + createCf({ + pagePadding : 50, + columnGap : 25, + columnCount : 5, + pageArrangement : 'vertical', + }).flow(_wrapToPage2 + _wrapToPage2); + + var page1 = target.querySelector('.cf-page-1'); + var page2 = target.querySelector('.cf-page-2'); + + assert.match(page1.clientWidth, 800); + assert.match(page1.clientHeight, 600); + + assert.match(page2.clientWidth, 800); + assert.match(page2.clientHeight, 600); + + assert.match(cssProp(page1, 'left'), '0px'); + assert.match(cssProp(page1, 'top'), '0px'); + + assert.match(cssProp(page2, 'left'), '0px'); + assert.match(cssProp(page2, 'top'), '600px'); + + assert.match(page1.querySelector('.cf-column-1').offsetLeft, 0); + assert.match(page1.querySelector('.cf-column-1').offsetTop, 50); + assert.match(page1.querySelector('.cf-column-1').offsetWidth, 140); + assert.match(page1.querySelector('.cf-column-1').offsetHeight, 500); + + assert.match(page2.querySelector('.cf-column-1').offsetTop, 50); + }, + + 'ShouldRepeatAnOverflowedElementOnTheNextColumn' : function() { + + createCf().flow(_overflowedElement); + + var column1 = target.querySelector('.cf-column-1'); + + assert.className(column1.childNodes[column1.childNodes.length - 1], 'height100'); + + var column2 = target.querySelector('.cf-column-2'); + assert(column2 instanceof HTMLElement); + + assert.match(column2.childNodes.length, 1); + assert.className(column2.childNodes[0], 'height100'); + + assert.match(column2.childNodes[0].innerHTML, column1.childNodes[2].innerHTML); + }, + + 'ShouldSetNegativeTopMarginOnRemainderOfOverflowedElement' : function() { + + createCf().flow(_overflowedElement); + + var column2 = target.querySelector('.cf-column-2'); + var element = column2.childNodes[0]; + + assert.match(cssProp(element, 'margin-top'), '-50px'); + }, + + 'ShouldCorrectlyWrapALargeElementOverManyColumns' : function() { + + createCf().flow('
height300
height1000
'); + + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '-300px'); + assert.match(cssProp(column3.childNodes[0], 'margin-top'), '-900px'); + }, + + 'ShouldCorrectlyWrapAHugeElementOverManyColumns' : function() { + + createCf().flow('
height3000
'); + + var page2 = target.querySelector('.cf-page-2'); + var p2col2 = page2.querySelector('.cf-column-2'); + + assert.match(cssProp(p2col2.childNodes[0], 'margin-top'), '-2400px'); + assert.isNull(page2.querySelector('.cf-column-3')); + }, + + 'ShouldWrapPlainTextInParagraphTags' : function() { + + createCf().flow('plain text'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.innerHTML, /^plain text<\/p>$/); + }, + + 'ShouldIgnoreEmptyTextNodes' : function() { + + createCf().flow('\n

parag 1

\n

parag 2

\n'); + + var column = target.querySelector('.cf-column-1'); + + assert.match(column.innerHTML, /^parag 1<\/p>parag 2<\/p>$/); + }, + + 'ShouldNotCarryParagraphBottomMarginsOverToNextColumn' : function() { + + createCf().flow('
simulated-parags
simulated-parags
simulated-parags
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 2); + assert.match(column2.childNodes.length, 1); + + var element = column2.childNodes[0]; + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldNotWrapAnElementWithNowrapClass' : function() { + + createCf().flow('
height500
height200 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + var element = column2.childNodes[0]; + + assert.className(element, 'nowrap'); + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldNotMoveAnElementWithNowrapClassWhichFitsInAColumn' : function() { + + createCf().flow('
height500
height100 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 2); + assert.isNull(column2); + }, + + 'ShouldCorrectlyPositionSuccessiveNowrapElements' : function() { + + createCf().flow('
height500
height500 nowrap
height500 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + assert.match(column3.childNodes.length, 1); + + assert.match(column2.childNodes[0].style.marginTop, '0px'); + assert.match(column3.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldCropATallNowrapElement' : function() { + + createCf().flow('
height1000 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.isNull(column2); + }, + + 'ShouldMoveThenCropATallNowrapElement' : function() { + + createCf().flow('
height500
height1000 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + assert.isNull(column3); + + var element = column2.childNodes[0]; + + assert.className(element, 'nowrap'); + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldNotWrapAnElementWhichMatchesNoWrapOnTags' : function() { + + createCf({ + columnGap : 25, + columnCount : 3, + noWrapOnTags : ['section'], + }).flow('
height500
height200 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + var element = column2.childNodes[0]; + + assert.tagName(element, 'section'); + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldIgnoreCaseOfNoWrapOnTags' : function() { + + createCf({ + columnGap : 25, + columnCount : 3, + noWrapOnTags : ['SECTION'], + }).flow('
height500
height200 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + var element = column2.childNodes[0]; + + assert.tagName(element, 'section'); + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldNotWrapAnElementWithKeepwithnextClass' : function() { + + createCf().flow('
height500
height200 keepwithnext
height100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + + var element = column2.childNodes[0]; + + assert.className(element, 'keepwithnext'); + assert.match(element.style.marginTop, '0px'); + }, + + 'ShouldWrapAKeepwithnextElementWhenItsTheFinalElement' : function() { + + createCf().flow('
height500
height200 keepwithnext
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 2); + assert.match(column2.childNodes.length, 1); + + var element = column2.childNodes[0]; + + assert.className(element, 'keepwithnext'); + assert.match(element.style.marginTop, '-100px'); + }, + + 'ShouldMoveThenCropATallKeepwithnextElement' : function() { + + createCf().flow('
height500
height1000 keepwithnext
height100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + assert.match(column3.childNodes.length, 1); + + assert.className(column2.childNodes[0], 'keepwithnext'); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + + assert.className(column3.childNodes[0], 'height100'); + assert.match(column3.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldCropATallKeepwithnextElement' : function() { + + createCf().flow('
height1000 keepwithnext
height100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + assert.className(column2.childNodes[0], 'height100'); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldMoveAKeepwithnextElementToJoinFollowingPlainTextElement' : function() { + + createCf().flow('
height500
height100 keepwithnext
height100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + + assert.className(column2.childNodes[0], 'keepwithnext'); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldIgnoreKeepwithnextClassOnFinalElement' : function() { + + createCf().flow('
height400
height100 keepwithnext
'); + + var column1 = target.querySelector('.cf-column-1'); + + assert.match(column1.childNodes.length, 2); + assert.isNull(target.querySelector('.cf-column-2')); + }, + + 'ShouldCorrectlyHandleAnElementWithBothKeepwithnextAndNowrapClasses' : function() { + + createCf().flow('
height500
height200 keepwithnext
height100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'NowrapShouldNotAffectFollowingColumns' : function() { + + createCf().flow('
height500
height200 nowrap
height500
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + assert.match(column3.childNodes.length, 1); + + assert.match(column3.childNodes[0].style.marginTop, '-400px'); + }, + + 'KeepwithnextShouldNotAffectFollowingColumns' : function() { + + createCf().flow('
height500
height100 keepwithnext
height500
height500
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + assert.match(column3.childNodes.length, 1); + + assert.match(column2.childNodes[0].style.marginTop, '0px'); + assert.match(column3.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldCorrectlyPositionANowrapFollowingAKeepwithnext' : function() { + + createCf().flow('
height400
height100 keepwithnext
height200 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + assert.isNull(target.querySelector('.cf-column-3')); + + assert.className(column2.childNodes[0], 'keepwithnext'); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldObeyKeepwithnextWhenNextElementHasNowrapClassAndOverflows' : function() { + + createCf().flow('
height400
height100 keepwithnext
height200 nowrap
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + + var element = column2.childNodes[0]; + + assert.className(element, 'keepwithnext'); + assert.match(element.style.marginTop, '0px'); + }, + + 'Regression1ItShouldUpdateColumnHeightAfterAnElementIsCropped' : function() { + + createCf().flow('
700 keepwithnext
300
300
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + assert.isNull(target.querySelector('.cf-column-3')); + }, + + 'Regression2MissingLastElement' : function() { + + createCf().flow('
700
200 keepwithnext
100
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 3); + assert.isNull(target.querySelector('.cf-column-3')); + + assert.className(column2.childNodes[0], 'height700'); + assert.match(column2.childNodes[0].style.marginTop, '-600px'); + }, + + 'Regression5LargeSpaceAdded' : function() { + + createCf().flow('
700
200 nowrap keepwithnext
500
'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + var column3 = target.querySelector('.cf-column-3'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 3); + assert.match(column3.childNodes.length, 1); + + assert.className(column3.childNodes[0], 'height500'); + assert.match(column3.childNodes[0].style.marginTop, '-300px'); + }, + + 'Regression7ItShouldNotGetIntoAnEndlessLoop' : function() { + + // With the loop-protection removed, this test should cause an endless loop if the bug is not fixed. + + createCf().flow('
1: 600 keepwithnext
2: 700
'); + assert(true); + + }, + + 'Regression10TheLastElementShouldNotBeCropped' : function() { + + createCf().flow('
5: 500 keepwithnext
7: 200 keepwithnext
'); + + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 2); + assert.match(column2.childNodes.length, 1); + + assert.match(column2.childNodes[0].style.marginTop, '-100px'); + }, + + 'Regression10SecondElementShouldBeInColumn2' : function() { + + createCf().flow('
2: 300 keepwithnext
3: 400 keepwithnext
4: 200
'); + + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 2); + + assert.className(column2.childNodes[0], 'height400'); + assert.className(column2.childNodes[0], 'keepwithnext'); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'RegressionItShouldCorrectlyPlaceSuccessiveFullheightElements' : function() { + + createCf().flow('

height600

height600

'); + + var column1 = target.querySelector('.cf-column-1'); + var column2 = target.querySelector('.cf-column-2'); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + assert.isNull(target.querySelector('.cf-column-3')); + assert.match(column2.childNodes[0].style.marginTop, '0px'); + }, + + 'ShouldCorrectlyReportSinglePageCount' : function() { + + createCf({ + columnCount : 1 + }).flow('
height300
'); + + assert.match(cf.pageCount, 1); + }, + + 'ShouldCorrectlyReportLargerPageCount' : function() { + + createCf({ + columnCount : 1 + }).flow('
height3000
'); + + assert.match(cf.pageCount, 5); + }, + + 'ShouldAddExplicitWidthAndHeightToTarget' : function() { + + createCf().flow('
height300
'); + + assert.match(target.style.width, '800px'); + assert.match(cssProp(target, 'width'), '800px'); + assert.match(cssProp(target, 'height'), '600px'); + }, + + 'ShouldCorrectlyReportLayoutDimensions' : function() { + + createCf({ + columnGap : 20, + columnCount : 4, + pagePadding : 50 + }).flow('
height300
'); + + var dimesions = cf.layoutDimensions; + + assert.match(dimesions.pageInnerWidth, 700); + assert.match(dimesions.pageInnerHeight, 600); + assert.match(dimesions.colDefaultTop, 0); + assert.match(dimesions.colDefaultLeft, 50); + assert.match(dimesions.columnCount, 4); + assert.match(dimesions.columnWidth, 160); + assert.match(dimesions.columnGap, 20); + }, + + '//ShouldSetExplicitHeightOnImagesWithSpecifiedAspectRatio' : function() { + + createCf().flow('
height300
height300
'); + + var page = target.querySelector('.cf-page-1'); + var column1 = page.querySelector('.cf-column-1'); + var column2 = page.querySelector('.cf-column-2'); + var img = column1.querySelector('img'); + var div2 = column2.querySelector('div'); + + assert.match(img.style.width, "200px"); + assert.match(img.style.height, "100px"); + assert.match(parseInt(cssProp(img, 'width')), 200); + assert.match(parseInt(cssProp(img, 'height')), 100); + + assert.match(div2.style.marginTop, '-200px'); + }, + + '//ShouldObeyAllHistoricalKeepwithnextElementsWhichFitInNextColumn' : function() { + + createCf().flow('
1 height100 keepwithnext
2 height100 plaintext
3 height100 keepwithnext
4 height100 keepwithnext
5 height100 keepwithnext
6 height100 keepwithnext
7 height100 plaintext
'); + }, + + '//ShouldMoveLastInAStringOfKeepwithnextElementIntoNextColumn' : function() {}, + + '//ShouldSplitALongStreamOfKeepwithnextElementsWhenAColumnIsFull' : function() {}, + + '//ShouldObeyAllHistoricalKeepwithnextElementsUntilStartOfColumn' : function() {}, + + +//*/ + + + + // Regression 4 - The two 100 keepwithnext should be in col 1. + //
100
100
200 nowrap
100 nowrap keepwithnext
100 nowrap keepwithnext
500 keepwithnext
200
300
+ + // Consider some 'typographical measure' logic - reduce the number of columns per page if the measure is too small (because the font size is too large) + // We should remove any padding on the viewport, and any padding or margin on the articles. + // Run Arrhythmia("body").validateRhythm(); (https://github.com/mattbaker/Arrhythmia) to check vertical rhythm after I've added padding functionality. + // Add 'near-parag-14' or similar class to images, and attempt to get them onto the same page. If an inline image overflows the bottom of a column, there are two options: 1) leave whitespace and place image at top of next col. 2) start the paragraph of text, and place image at top of next col, continuing parag afterwards. + // Allow column-spans for inline images. This is a future feature request. + // Consider a breakafter class, or similar, to always break after this element. + // Shouldn't most tags (img, headings, etc.) be nowrap by default? Perhaps have a default list of tags which are NOT nowrap, and allow it to be overridden. + +}); \ No newline at end of file diff --git a/test/ConfigTest.js b/test/config-test.js similarity index 56% rename from test/ConfigTest.js rename to test/config-test.js index b3d554a..6799365 100644 --- a/test/ConfigTest.js +++ b/test/config-test.js @@ -4,124 +4,125 @@ * @copyright The Financial Times Limited [All Rights Reserved] */ +"use strict"; -TestCase('Config', { +buster.testCase('Config', { - setUp : function() { + setUp : function(done) { document.body.innerHTML = '
'; - document.body.className = 'config'; + addStylesheets(['all.css', 'config.css'], done); }, tearDown : function() { - - var styles = document.getElementsByTagName('style'); - for (var i = 0, len = styles.length; i < len; i++) { - if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); - } + removeStyleSheets(); + document.body.className = ''; }, + "InstantiateWithNoParamsThrowsException" : function() { - testInstantiateWithNoParamsThrowsException : function() { - - assertException(function test() { + assert.exception(function test() { new FTColumnflow(); }, 'FTColumnflowParameterException'); }, - testExceptionThrownOnInvalidFirstParam : function() { + "ThrowExceptionOnInvalidFirstParam" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow(1, 'test'); }, 'FTColumnflowParameterException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow(new Array, 'test'); }, 'FTColumnflowParameterException'); }, - testExceptionThrownOnInvalidSecondParam : function() { + "ThrowExceptionOnInvalidSecondParam" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 1); }, 'FTColumnflowParameterException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', new Array); }, 'FTColumnflowParameterException'); }, - testStringTargetMustExist : function() { + "StringTargetMustExist" : function() { - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid'); }); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('missingid', 'viewportid'); }, 'FTColumnflowSelectorException'); }, - testStringViewportMustExist : function() { + "StringViewportMustExist" : function() { - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid'); }); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'missingid'); }, 'FTColumnflowSelectorException'); }, - testTargetElementAcceptedAsFirstParam : function() { + "TargetElementAcceptedAsFirstParam" : function() { - new FTColumnflow(document.getElementById('targetid'), 'viewportid'); + refute.exception(function test() { + new FTColumnflow(document.getElementById('targetid'), 'viewportid'); + }); }, - testViewportElementAcceptedAsSecondParam : function() { + "ViewportElementAcceptedAsSecondParam" : function() { - new FTColumnflow('targetid', document.getElementById('viewportid')); + refute.exception(function test() { + new FTColumnflow('targetid', document.getElementById('viewportid')); + }); }, - testTargetMustBeAChildOfViewport : function() { + "TargetMustBeAChildOfViewport" : function() { - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid'); }); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('viewportid', 'targetid'); }, 'FTColumnflowInheritanceException'); }, - testItShouldUseDefaultValueForColumnCount : function() { + "ShouldUseDefaultValueForColumnCount" : function() { var cf = new FTColumnflow('targetid', 'viewportid'); - assertEquals(1, cf.layoutDimensions.columnCount); + assert.equals(1, cf.layoutDimensions.columnCount); }, - testItShouldUseViewportWidthForColumnWidthByDefault : function() { + "ShouldUseViewportWidthForColumnWidthByDefault" : function() { var cf = new FTColumnflow('targetid', 'viewportid'); - assertEquals(800, cf.layoutDimensions.columnWidth); + assert.equals(800, cf.layoutDimensions.columnWidth); }, - testItShouldUse1emByDefaultForColumnGap : function() { + "ShouldUse1emByDefaultForColumnGap" : function() { - document.body.classList.add('columnGaptest'); + document.body.className = 'columnGaptest'; var cf = new FTColumnflow('targetid', 'viewportid'); - assertEquals(12, cf.layoutDimensions.columnGap); + assert.equals(12, cf.layoutDimensions.columnGap); }, - testItShouldThrowExceptionOnInvalidConfigParameter : function() { + "ShouldThrowExceptionOnInvalidConfigParameter" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'invalid' : 'abc' }); @@ -129,56 +130,56 @@ TestCase('Config', { }, - testItShouldThrowExceptionOnInvalidColumnDimensionType : function() { + "ShouldThrowExceptionOnInvalidColumnDimensionType" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 'abc' }); }, 'FTColumnflowColumnDimensionException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnCount' : 'abc' }); }, 'FTColumnflowColumnDimensionException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnWidth' : 'abc' }); }, 'FTColumnflowColumnDimensionException'); }, - testItShouldThrowExceptionOnNegativeColumnDimensionValue : function() { + "ShouldThrowExceptionOnNegativeColumnDimensionValue" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnGap' : -20 }); }, 'FTColumnflowColumnDimensionException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnCount' : -20 }); }, 'FTColumnflowColumnDimensionException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnWidth' : -20 }); }, 'FTColumnflowColumnDimensionException'); }, - testItShouldRespectSpecifiedColumnGap : function() { + "ShouldRespectSpecifiedColumnGap" : function() { - document.body.classList.add('columnGaptest'); + document.body.className = 'columnGaptest'; var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 20 }); - assertEquals(20, cf.layoutDimensions.columnGap); + assert.equals(20, cf.layoutDimensions.columnGap); }, @@ -188,23 +189,23 @@ TestCase('Config', { // N := column-count // W := max(0, (available-width - ((N - 1) * column-gap)) / N) // exit - testItShouldCalculateColumnWidthWhenCountIsSet : function() { + "ShouldCalculateColumnWidthWhenCountIsSet" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 25, 'columnCount' : 5, }); - assertEquals(140, cf.layoutDimensions.columnWidth); + assert.equals(140, cf.layoutDimensions.columnWidth); }, - testItShouldUseWholeWidthWhenOnlyOneColumn : function() { + "ShouldUseWholeWidthWhenOnlyOneColumn" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnCount' : 1, }); - assertEquals(800, cf.layoutDimensions.columnWidth); + assert.equals(800, cf.layoutDimensions.columnWidth); }, @@ -212,35 +213,35 @@ TestCase('Config', { // N := max(1, floor((available-width + column-gap) / (column-width + column-gap))) // W := ((available-width + column-gap) / N) - column-gap // exit - testItShouldUseViewportWidthWhenColumnWidthIsTooLarge : function() { + "ShouldUseViewportWidthWhenColumnWidthIsTooLarge" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnWidth' : 900, }); - assertEquals(800, cf.layoutDimensions.columnWidth); - assertEquals(1, cf.layoutDimensions.columnCount); + assert.equals(800, cf.layoutDimensions.columnWidth); + assert.equals(1, cf.layoutDimensions.columnCount); }, - testItShouldUseSpecifiedWidthWhenItFitsExactly : function() { + "ShouldUseSpecifiedWidthWhenItFitsExactly" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 25, 'columnWidth' : 140, }); - assertEquals(5, cf.layoutDimensions.columnCount); + assert.equals(5, cf.layoutDimensions.columnCount); }, - testItShouldWidenSmallColumnsToFit : function() { + "ShouldWidenSmallColumnsToFit" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 25, 'columnWidth' : 130, }); - assertEquals(140, cf.layoutDimensions.columnWidth); - assertEquals(5, cf.layoutDimensions.columnCount); + assert.equals(140, cf.layoutDimensions.columnWidth); + assert.equals(5, cf.layoutDimensions.columnCount); }, @@ -248,7 +249,7 @@ TestCase('Config', { // N := min(column-count, floor((available-width + column-gap) / (column-width + column-gap))) // W := ((available-width + column-gap) / N) - column-gap // exit - testItShouldReduceCountIfThereIsNoSpace : function() { + "ShouldReduceCountIfThereIsNoSpace" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 25, @@ -256,11 +257,11 @@ TestCase('Config', { 'columnCount' : 6, }); - assertEquals(140, cf.layoutDimensions.columnWidth); - assertEquals(5, cf.layoutDimensions.columnCount); + assert.equals(140, cf.layoutDimensions.columnWidth); + assert.equals(5, cf.layoutDimensions.columnCount); }, - testItShouldTreatCountAsMaximumWhenWidthIsAlsoDefined : function() { + "ShouldTreatCountAsMaximumWhenWidthIsAlsoDefined" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'columnGap' : 25, @@ -268,20 +269,20 @@ TestCase('Config', { 'columnCount' : 3, }); - assertEquals(250, cf.layoutDimensions.columnWidth); - assertEquals(3, cf.layoutDimensions.columnCount); + assert.equals(250, cf.layoutDimensions.columnWidth); + assert.equals(3, cf.layoutDimensions.columnCount); }, - testItShouldThrowExceptionOnInvalidClassNames : function() { + "ShouldThrowExceptionOnInvalidClassNames" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pageClass' : 20 }); }, 'FTColumnflowClassnameException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnClass' : new Array() }); @@ -289,92 +290,92 @@ TestCase('Config', { }, - testItShouldNormaliseClassNamesAndProvideGetter : function() { + "ShouldNormaliseClassNamesAndProvideGetter" : function() { var cf = new FTColumnflow('targetid', 'viewportid', { 'pageClass' : 'class with spaces', 'columnClass' : 'class&with*illegal@chars' }); - assertEquals('class-with-spaces', cf.pageClass); - assertEquals('class-with-illegal-chars', cf.columnClass); + assert.equals('class-with-spaces', cf.pageClass); + assert.equals('class-with-illegal-chars', cf.columnClass); }, - testItShouldThrowAnExceptionOnInvalidPageArrangementValue : function() { + "ShouldThrowAnExceptionOnInvalidPageArrangementValue" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pageArrangement' : 20 }); }, 'FTColumnflowArrangementException'); - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pageArrangement' : 'invalid' }); }, 'FTColumnflowArrangementException'); - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pageArrangement' : 'vertical' }); }); - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pageArrangement' : 'horizontal' }); }); }, - testItShouldThrowExceptionOnInvalidMarginType : function() { + "ShouldThrowExceptionOnInvalidMarginType" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pagePadding' : 'invalid' }); }, 'FTColumnflowPaddingException'); - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'pagePadding' : 50 }); }); }, - testitShouldThrowExceptionIfViewportHasNoWidthOrHeight : function() { + "ShouldThrowExceptionIfViewportHasNoWidthOrHeight" : function() { document.body.innerHTML = '
'; - assertException(function test() { + assert.exception(function test() { new FTColumnflow('unstyled-targetid', 'unstyled-viewportid'); }, 'FTColumnflowViewportException'); }, - testItShouldThrowExceptionOnInvalidStandardiseLineHeightType : function() { + "ShouldThrowExceptionOnInvalidStandardiseLineHeightType" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'standardiseLineHeight' : 'invalid' }); }, 'FTColumnflowStandardiseLineheightException'); - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'standardiseLineHeight' : true }); }); }, - testItShouldThrowExceptionOnInvalidMinColumnHeight : function() { + "ShouldThrowExceptionOnInvalidMinColumnHeight" : function() { - assertException(function test() { + assert.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnFragmentMinHeight' : 'invalid' }); }, 'FTColumnflowColumnDimensionException'); - assertNoException(function test() { + refute.exception(function test() { new FTColumnflow('targetid', 'viewportid', { 'columnFragmentMinHeight' : 20 }); diff --git a/test/css/BaselineGridTest.css b/test/css/BaselineGridTest.css index 526075a..393543b 100644 --- a/test/css/BaselineGridTest.css +++ b/test/css/BaselineGridTest.css @@ -1,60 +1,60 @@ -.baselinegrid p { +p { margin: 20px 0; line-height: 20px; background-color: rgba(0, 0, 0, 0.1); background-image: -webkit-repeating-linear-gradient(red 0px, red 1px, transparent 1px, transparent 20px); } -.baselinegrid img { width: 100%; height: auto; } +img { width: 100%; height: auto; } /* Odd heights */ -.baselinegrid .height1140 { height: 1140px; } -.baselinegrid .height40 { height: 40px; } -.baselinegrid .height620 { height: 620px; } -.baselinegrid .height580 { height: 580px; } +.height1140 { height: 1140px; } +.height40 { height: 40px; } +.height620 { height: 620px; } +.height580 { height: 580px; } /* 17px grid */ -.baselinegrid.lineheight17 p { +.lineheight17 p { margin: 17px 0; line-height: 17px; } -.baselinegrid.lineheight-in-ems p { +.lineheight-in-ems p { margin: 17px 0; font-size: 10px; line-height: 1.7em; } -.baselinegrid.lineheight-in-percent p { +.lineheight-in-percent p { margin: 17px 0; font-size: 10px; line-height: 170%; } -.baselinegrid.lineheight-multiplier p { +.lineheight-multiplier p { margin: 17px 0; font-size: 10px; line-height: 1.7; } -.baselinegrid.lineheight-inherit .cf-column { +.lineheight-inherit .cf-column { line-height: 17px; } -.baselinegrid.lineheight-inherit p { +.lineheight-inherit p { margin: 17px 0; font-size: 10px; line-height: inherit; } -.baselinegrid.lineheight-normal p { +.lineheight-normal p { margin: 17px 0; font-size: 10px; line-height: normal; @@ -63,25 +63,25 @@ /* Variable lineheight, median 17px grid */ -.baselinegrid.lineheight-variable p { +.lineheight-variable p { margin: 17px 0; line-height: 17px; } -.baselinegrid.lineheight-variable p:first-of-type { +.lineheight-variable p:first-of-type { line-height: 23px; } /* Paragraphs do not conform to 20px grid */ -.baselinegrid.unpadded-parags p { +.unpadded-parags p { height: 53px; } /* Paragraphs have 40px top margin and 20px bottom */ -.baselinegrid.unequal-margin p { +.unequal-margin p { margin: 40px 0 20px; } diff --git a/test/css/ColumnWrapTest.css b/test/css/ColumnWrapTest.css index 382a49b..ed1cd2a 100644 --- a/test/css/ColumnWrapTest.css +++ b/test/css/ColumnWrapTest.css @@ -1,14 +1,14 @@ -.columnwrap div { +div { line-height: 20px; } -.columnwrap .cf-column p { +.cf-column p { margin: 20px 0; line-height: 20px; } -.columnwrap .simulated-parags { +.simulated-parags { height: 290px; margin-bottom: 20px; } @@ -17,27 +17,27 @@ /* Colours */ -.columnwrap .cf-page { +.cf-page { outline: 1px solid white; } -.columnwrap #viewportid { +#viewportid { background-color: gray; } -.columnwrap .cf-column p { +.cf-column p { background-color: rgba(0, 0, 0, 0.1); outline: 1px solid white; color: white; background-image: -webkit-repeating-linear-gradient(red 0px, red 1px, transparent 1px, transparent 20px); } -.columnwrap .cf-column div { +.cf-column div { outline: 1px solid white; color: white; background-image: -webkit-repeating-linear-gradient(red 0px, red 1px, transparent 1px, transparent 100px); } -.columnwrap .simulated-parags { +.simulated-parags { background-color: #700; } diff --git a/test/css/ConfigTest.css b/test/css/ConfigTest.css index 75797c3..8d62be8 100644 --- a/test/css/ConfigTest.css +++ b/test/css/ConfigTest.css @@ -1,10 +1,3 @@ -.config #viewportid { background-color: gray; margin: 5px; } - - -.config .cf-page { outline: 1px solid white; margin-bottom: 20px; } - - - .columnGaptest { font-size: 10px; } .columnGaptest #viewportid { font-size: 1.2em; } diff --git a/test/css/FixedElementsTest.css b/test/css/FixedElementsTest.css index 7cfe215..38486d0 100644 --- a/test/css/FixedElementsTest.css +++ b/test/css/FixedElementsTest.css @@ -1,64 +1,64 @@ -.fixedelements .fixed { +.fixed { height: 200px; width: 250px; } -.fixedelements .fixed100 { +.fixed100 { height: 100px; } -.fixedelements .fixed205 { +.fixed205 { height: 205px; } -.fixedelements .fixed500 { +.fixed500 { height: 500px; } -.fixedelements .fixed600 { +.fixed600 { height: 600px; } -.fixedelements p, .fixedelements div, .fixedelements .cf-column { +p, div, .cf-column { line-height: 20px; } -.fixedelements p { +p { margin: 20px 0; } -.fixedelements .fixed.col-span-1, .fixedelements .fixed.col-span-1-left { +.fixed.col-span-1, .fixed.col-span-1-left { width: 250px; } -.fixedelements .fixed.col-span-2, .fixedelements .fixed.col-span-2-left { +.fixed.col-span-2, .fixed.col-span-2-left { width: 525px; } -.fixedelements .fixed.col-span-3, .fixedelements .fixed.col-span-3-left { +.fixed.col-span-3, .fixed.col-span-3-left { width: 800px; } -.fixedelements .shift-up { +.shift-up { margin-top: -20px; } -.fixedelements .auto-width { +.auto-width { width: auto; } -.fixedelements #width-50 { +#width-50 { width: 50px !important; } /* Colours */ -.fixedelements .cf-column p, .fixedelements .cf-column div { +.cf-column p, .cf-column div { background-color: rgba(0, 0, 0, 0.1); background-image: -webkit-repeating-linear-gradient(red 0px, red 1px, transparent 1px, transparent 20px); } -.fixedelements .cf-page { +.cf-page { outline: 1px solid white; } diff --git a/test/css/ReflowTest.css b/test/css/ReflowTest.css index 62ce54f..ae3d4eb 100644 --- a/test/css/ReflowTest.css +++ b/test/css/ReflowTest.css @@ -1,3 +1,3 @@ -.reflow p, .reflow div, .reflow .cf-column { +p, div, .cf-column { line-height: 20px; } diff --git a/test/FixedElementsTest.js b/test/fixedelements-test.js similarity index 55% rename from test/FixedElementsTest.js rename to test/fixedelements-test.js index f30b6a4..7100aa6 100644 --- a/test/FixedElementsTest.js +++ b/test/fixedelements-test.js @@ -4,90 +4,75 @@ * @copyright The Financial Times Limited [All Rights Reserved] */ -var cf, target, viewport; +buster.testCase('FixedElements', { -function createCf(config) { - cf = new FTColumnflow('targetid', 'viewportid', config || { - columnGap : 25, - columnCount : 3 - }); - target = document.getElementById('targetid'); - - return cf; -} - -TestCase('FixedElements', { - - setUp : function() { + setUp : function(done) { document.body.innerHTML = '
'; - document.body.className = 'fixedelements'; + addStylesheets(['all.css', 'fixedelements.css'], done); }, tearDown : function() { - - var styles = document.getElementsByTagName('style'); - for (var i = 0, len = styles.length; i < len; i++) { - if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); - } + removeStyleSheets(); + document.body.className = ''; }, - testItShouldCreateAHiddenPreloadArea : function() { + 'ShouldCreateAHiddenPreloadArea' : function() { createCf().flow(); var preload = target.querySelector('.cf-preload-fixed'); - assertTrue(preload instanceof HTMLElement); - assertEquals('hidden', window.getComputedStyle(preload).getPropertyValue('visibility')); - assertEquals('absolute', window.getComputedStyle(preload).getPropertyValue('position')); + assert(preload instanceof HTMLElement); + assert.match(cssProp(preload, 'visibility'), 'hidden'); + assert.match(cssProp(preload, 'position'), 'absolute'); }, - testItShouldAddFlowedContentToPreloadArea : function() { + 'ShouldAddFlowedContentToPreloadArea' : function() { createCf().flow('', '
fixedContent
'); var preload = target.querySelector('.cf-preload-fixed'); - assertMatch(/^fixedContent<\/div>$/, preload.innerHTML); + assert.match(preload.innerHTML, /^fixedContent<\/div>$/); }, - testAFixedElementShouldBePlacedOnPage1 : function() { + 'AFixedElementShouldBePlacedOnPage1' : function() { createCf().flow('

flowedContent

', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals(2, page.childNodes.length); - assertTrue(fixed instanceof HTMLElement); - assertEquals('fixedContent', fixed.innerHTML); + assert.match(page.childNodes.length, 2); + assert(fixed instanceof HTMLElement); + assert.match(fixed.innerHTML, 'fixedContent'); }, - testTextNodesShouldBeIgnored : function() { + 'TextNodesShouldBeIgnored' : function() { createCf().flow('

flowedContent

', '\n
fixedContent
\n'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals(2, page.childNodes.length); - assertTrue(fixed instanceof HTMLElement); - assertEquals('fixedContent', fixed.innerHTML); + assert.match(page.childNodes.length, 2); + assert(fixed instanceof HTMLElement); + assert.match(fixed.innerHTML, 'fixedContent'); }, - testAFixedElementShouldBePlacedAbsoluteTopLeftByDefault : function() { + 'AFixedElementShouldBePlacedAbsoluteTopLeftByDefault' : function() { createCf().flow('

flowedContent

', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals('absolute', window.getComputedStyle(fixed).getPropertyValue('position')); - assertEquals(0, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(cssProp(fixed, 'position'), 'absolute'); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 0); }, - testAFixedElementShouldRespectPagePadding : function() { + 'AFixedElementShouldRespectPagePadding' : function() { createCf({ columnGap : 25, @@ -98,12 +83,12 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals('absolute', window.getComputedStyle(fixed).getPropertyValue('position')); - assertEquals(0, fixed.offsetTop); - assertEquals(50, fixed.offsetLeft); + assert.match(cssProp(fixed, 'position'), 'absolute'); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 50); }, - testAFixedElementShouldRespectPagePaddingInVerticalArrangement : function() { + 'AFixedElementShouldRespectPagePaddingInVerticalArrangement' : function() { createCf({ columnGap : 25, @@ -115,23 +100,23 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals('absolute', window.getComputedStyle(fixed).getPropertyValue('position')); - assertEquals(50, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(cssProp(fixed, 'position'), 'absolute'); + assert.match(fixed.offsetTop, 50); + assert.match(fixed.offsetLeft, 0); }, - testItShouldShortenTheAffectedColumnAndPlaceItLower : function() { + 'ShouldShortenTheAffectedColumnAndPlaceItLower' : function() { createCf().flow('

flowedContent

', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var column = page.querySelector('.cf-column'); - assertEquals(220, column.offsetTop); - assertEquals(380, column.offsetHeight); + assert.match(column.offsetTop, 220); + assert.match(column.offsetHeight, 380); }, - testItShouldReduceTheAvailableSpaceInAColumn : function() { + 'ShouldReduceTheAvailableSpaceInAColumn' : function() { createCf().flow('
height600
', '
fixedContent
'); @@ -139,13 +124,13 @@ TestCase('FixedElements', { var column1 = page.querySelector('.cf-column-1'); var column2 = page.querySelector('.cf-column-2'); - assertTrue(column2 instanceof HTMLElement); + assert(column2 instanceof HTMLElement); var element = column2.childNodes[0]; - assertEquals('-380px', window.getComputedStyle(element).getPropertyValue('margin-top')); + assert.match(cssProp(element, 'margin-top'), '-380px'); }, - testItShouldShortenMultipleColumnsWhenTheElementSpans : function() { + 'ShouldShortenMultipleColumnsWhenTheElementSpans' : function() { createCf().flow('
height600
height600
', '
fixedContent
'); @@ -154,29 +139,29 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(220, column1.offsetTop); - assertEquals(380, column1.offsetHeight); + assert.match(column1.offsetTop, 220); + assert.match(column1.offsetHeight, 380); - assertEquals(220, column2.offsetTop); - assertEquals(380, column2.offsetHeight); + assert.match(column2.offsetTop, 220); + assert.match(column2.offsetHeight, 380); - assertEquals(0, column3.offsetTop); - assertEquals(600, column3.offsetHeight); + assert.match(column3.offsetTop, 0); + assert.match(column3.offsetHeight, 600); var element = column3.childNodes[0]; - assertEquals('-160px', window.getComputedStyle(element).getPropertyValue('margin-top')); + assert.match(cssProp(element, 'margin-top'), '-160px'); }, - testItShouldReduceASpanValueIfTooLarge : function() { + 'ShouldReduceASpanValueIfTooLarge' : function() { createCf().flow('
height600
height600
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); - assertEquals(3, page.querySelectorAll('.cf-column').length); + assert.match(page.querySelectorAll('.cf-column').length, 3); }, - testItShouldSpanAllColumns : function() { + 'ShouldSpanAllColumns' : function() { createCf().flow('
height1000
', '
fixedContent
'); @@ -185,22 +170,22 @@ TestCase('FixedElements', { var column3 = page.querySelector('.cf-column-3'); var element = column3.childNodes[0]; - assertEquals('800px', window.getComputedStyle(fixed).getPropertyValue('width')); - assertEquals('-760px', window.getComputedStyle(element).getPropertyValue('margin-top')); + assert.match(cssProp(fixed, 'width'), '800px'); + assert.match(cssProp(element, 'margin-top'), '-760px'); }, - testItShouldRoundUpTheHeightOfEachFixedElement : function() { + 'ShouldRoundUpTheHeightOfEachFixedElement' : function() { createCf().flow('

flowedContent

', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var column = page.querySelector('.cf-column'); - assertEquals(360, column.offsetHeight); - assertEquals(240, column.offsetTop); + assert.match(column.offsetHeight, 360); + assert.match(column.offsetTop, 240); }, - testItShouldPlaceSecondFixedElementUnderneathFirstWithAGap : function() { + 'ShouldPlaceSecondFixedElementUnderneathFirstWithAGap' : function() { createCf().flow('
height600
', '
fixedContent
fixedContent
'); @@ -211,20 +196,20 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed1.offsetTop); - assertEquals(220, fixed2.offsetTop); + assert.match(fixed1.offsetTop, 0); + assert.match(fixed2.offsetTop, 220); - assertEquals(440, column1.offsetTop); - assertEquals(160, column1.offsetHeight); + assert.match(column1.offsetTop, 440); + assert.match(column1.offsetHeight, 160); - assertEquals(220, column2.offsetTop); - assertEquals(380, column2.offsetHeight); + assert.match(column2.offsetTop, 220); + assert.match(column2.offsetHeight, 380); - assertEquals('-160px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); - assertEquals('-540px', window.getComputedStyle(column3.childNodes[0]).getPropertyValue('margin-top')); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '-160px'); + assert.match(cssProp(column3.childNodes[0], 'margin-top'), '-540px'); }, - testItShouldRespectSpecifiedPageAttachment : function() { + 'ShouldRespectSpecifiedPageAttachment' : function() { createCf().flow('
height600
height600
height600
height600
', '
fixedContent
'); @@ -235,14 +220,14 @@ TestCase('FixedElements', { var p2col1 = page2.querySelector('.cf-column-1'); - assertTrue(fixed instanceof HTMLElement); - assertEquals(0, fixed.offsetTop); + assert(fixed instanceof HTMLElement); + assert.match(fixed.offsetTop, 0); - assertEquals(220, p2col1.offsetTop); - assertEquals(380, p2col1.offsetHeight); + assert.match(p2col1.offsetTop, 220); + assert.match(p2col1.offsetHeight, 380); }, - testItShouldAnchorToTopRight : function() { + 'ShouldAnchorToTopRight' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -250,14 +235,14 @@ TestCase('FixedElements', { var fixed = page.querySelector('.fixed'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(550, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 550); - assertEquals(220, column3.offsetTop); - assertEquals('0px', window.getComputedStyle(column3.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column3.offsetTop, 220); + assert.match(cssProp(column3.childNodes[0], 'margin-top'), '0px'); }, - testItShouldAnchorToTopRightAndSpanLeft : function() { + 'ShouldAnchorToTopRightAndSpanLeft' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -267,14 +252,14 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 275); - assertEquals(220, column2.offsetTop); - assertEquals(220, column3.offsetTop); + assert.match(column2.offsetTop, 220); + assert.match(column3.offsetTop, 220); }, - testItShouldShiftAcrossToLeftToFit : function() { + 'ShouldShiftAcrossToLeftToFit' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -285,15 +270,15 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 275); - assertEquals(0, column1.offsetTop); - assertEquals(220, column2.offsetTop); - assertEquals(220, column3.offsetTop); + assert.match(column1.offsetTop, 0); + assert.match(column2.offsetTop, 220); + assert.match(column3.offsetTop, 220); }, - testItShouldShiftAcrossToLeftToFit : function() { + 'ShouldShiftAcrossToLeftToFit' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -304,15 +289,15 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 0); - assertEquals(220, column1.offsetTop); - assertEquals(220, column2.offsetTop); - assertEquals(0, column3.offsetTop); + assert.match(column1.offsetTop, 220); + assert.match(column2.offsetTop, 220); + assert.match(column3.offsetTop, 0); }, - testItShouldReduceImpossibleSpanToLeft : function() { + 'ShouldReduceImpossibleSpanToLeft' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -323,15 +308,15 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 0); - assertEquals(220, column1.offsetTop); - assertEquals(220, column2.offsetTop); - assertEquals(220, column3.offsetTop); + assert.match(column1.offsetTop, 220); + assert.match(column2.offsetTop, 220); + assert.match(column3.offsetTop, 220); }, - testItShouldAnchorToBottomRightAndSpanLeft : function() { + 'ShouldAnchorToBottomRightAndSpanLeft' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -341,17 +326,17 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(395, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 395); + assert.match(fixed.offsetLeft, 275); - assertEquals(0, column2.offsetTop); - assertEquals(360, column2.offsetHeight); + assert.match(column2.offsetTop, 0); + assert.match(column2.offsetHeight, 360); - assertEquals(0, column3.offsetTop); - assertEquals(360, column3.offsetHeight); + assert.match(column3.offsetTop, 0); + assert.match(column3.offsetHeight, 360); }, - testItShouldAnchorToBottomRightAndStack : function() { + 'ShouldAnchorToBottomRightAndStack' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
fixedContent
'); @@ -362,20 +347,20 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(400, fixed1.offsetTop); - assertEquals(275, fixed1.offsetLeft); + assert.match(fixed1.offsetTop, 400); + assert.match(fixed1.offsetLeft, 275); - assertEquals(180, fixed2.offsetTop); - assertEquals(550, fixed2.offsetLeft); + assert.match(fixed2.offsetTop, 180); + assert.match(fixed2.offsetLeft, 550); - assertEquals(0, column2.offsetTop); - assertEquals(380, column2.offsetHeight); + assert.match(column2.offsetTop, 0); + assert.match(column2.offsetHeight, 380); - assertEquals(0, column3.offsetTop); - assertEquals(160, column3.offsetHeight); + assert.match(column3.offsetTop, 0); + assert.match(column3.offsetHeight, 160); }, - testItShouldAnchorToColumn2 : function() { + 'ShouldAnchorToColumn2' : function() { createCf({ columnGap : 25, @@ -388,22 +373,22 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(165, fixed.offsetLeft); - assertEquals(305, fixed.offsetWidth); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 165); + assert.match(fixed.offsetWidth, 305); - assertEquals(0, column1.offsetTop); - assertEquals(600, column1.offsetHeight); + assert.match(column1.offsetTop, 0); + assert.match(column1.offsetHeight, 600); - assertEquals(220, column2.offsetTop); - assertEquals(380, column2.offsetHeight); + assert.match(column2.offsetTop, 220); + assert.match(column2.offsetHeight, 380); - assertEquals(220, column3.offsetTop); - assertEquals(380, column3.offsetHeight); + assert.match(column3.offsetTop, 220); + assert.match(column3.offsetHeight, 380); }, /* - testItShouldAnchorToSpecifiedColumn : function() { + 'ShouldAnchorToSpecifiedColumn' : function() { createCf().flow('
height600
height600
height600
', '
fixedContent
'); @@ -413,15 +398,15 @@ TestCase('FixedElements', { var column2 = page.querySelector('.cf-column-2'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 275); - assertEquals(220, column2.offsetTop); - assertEquals(220, column3.offsetTop); + assert.match(column2.offsetTop, 220); + assert.match(column3.offsetTop, 220); }, */ - testAFixedElementAtTheBottomShouldRespectPagePadding : function() { + 'AFixedElementAtTheBottomShouldRespectPagePadding' : function() { createCf({ columnGap : 25, @@ -433,10 +418,10 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals(350, fixed.offsetTop); + assert.match(fixed.offsetTop, 350); }, - testItShouldOverlapElementsRatherThanOmitThem : function() { + 'ShouldOverlapElementsRatherThanOmitThem' : function() { createCf().flow('
height100
', '
fixedContent
fixedContent
fixedContent
fixedContent
'); @@ -447,13 +432,13 @@ TestCase('FixedElements', { var fixed3 = page.querySelector('.fixed-3'); var fixed4 = page.querySelector('.fixed-4'); - assertEquals(0, fixed1.offsetTop); - assertEquals(220, fixed2.offsetTop); - assertEquals(400, fixed3.offsetTop); - assertEquals(400, fixed4.offsetTop); + assert.match(fixed1.offsetTop, 0); + assert.match(fixed2.offsetTop, 220); + assert.match(fixed3.offsetTop, 400); + assert.match(fixed4.offsetTop, 400); }, - testItShouldOverlapBottomElementsToo : function() { + 'ShouldOverlapBottomElementsToo' : function() { createCf().flow('
height100
', '
fixedContent
fixedContent
fixedContent
fixedContent
'); @@ -464,27 +449,27 @@ TestCase('FixedElements', { var fixed3 = page.querySelector('.fixed-3'); var fixed4 = page.querySelector('.fixed-4'); - assertEquals(400, fixed1.offsetTop); - assertEquals(180, fixed2.offsetTop); - assertEquals(0, fixed3.offsetTop); - assertEquals(0, fixed4.offsetTop); + assert.match(fixed1.offsetTop, 400); + assert.match(fixed2.offsetTop, 180); + assert.match(fixed3.offsetTop, 0); + assert.match(fixed4.offsetTop, 0); }, - testItShouldNotPrintAColumnWhenFixedElementsHaveFilledTheSpace : function() { + 'ShouldNotPrintAColumnWhenFixedElementsHaveFilledTheSpace' : function() { createCf().flow('
height100
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var column2 = page.querySelector('.cf-column-2'); - assertNull(page.querySelector('.cf-column-1')); + assert.isNull(page.querySelector('.cf-column-1')); - assertEquals(0, column2.offsetTop); - assertEquals(275, column2.offsetLeft); - assertEquals(1, column2.childNodes.length); + assert.match(column2.offsetTop, 0); + assert.match(column2.offsetLeft, 275); + assert.match(column2.childNodes.length, 1); }, - testItShouldNotPrintAnyColumnsOnPage1WhenFixedElementsHaveFilledTheSpace : function() { + 'ShouldNotPrintAnyColumnsOnPage1WhenFixedElementsHaveFilledTheSpace' : function() { createCf().flow('
height100
', '
fixedContent
'); @@ -494,108 +479,108 @@ TestCase('FixedElements', { var fixed = page1.querySelector('.fixed600'); var column = page2.querySelector('.cf-column-1'); - assertTrue(fixed instanceof HTMLElement); - assertEquals(0, page1.querySelectorAll('.cf-column').length); + assert(fixed instanceof HTMLElement); + assert.match(page1.querySelectorAll('.cf-column').length, 0); - assertEquals(0, column.offsetTop); - assertEquals(0, column.offsetLeft); - assertEquals(1, column.childNodes.length); + assert.match(column.offsetTop, 0); + assert.match(column.offsetLeft, 0); + assert.match(column.childNodes.length, 1); }, - testItShouldVerticallyCenterAFixedElement : function() { + 'ShouldVerticallyCenterAFixedElement' : function() { createCf().flow('
height200
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed'); - assertEquals(200, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(fixed.offsetTop, 200); + assert.match(fixed.offsetLeft, 0); var columns = page.querySelectorAll('.cf-column-1'); - assertEquals(2, columns.length); + assert.match(columns.length, 2); var topCol1 = columns[0]; var bottomCol1 = columns[1]; - assertEquals(0, topCol1.offsetLeft); - assertEquals(0, topCol1.offsetTop); - assertEquals(180, topCol1.offsetHeight); + assert.match(topCol1.offsetLeft, 0); + assert.match(topCol1.offsetTop, 0); + assert.match(topCol1.offsetHeight, 180); - assertEquals(0, bottomCol1.offsetLeft); - assertEquals(420, bottomCol1.offsetTop); - assertEquals(180, bottomCol1.offsetHeight); + assert.match(bottomCol1.offsetLeft, 0); + assert.match(bottomCol1.offsetTop, 420); + assert.match(bottomCol1.offsetHeight, 180); - assertEquals('-180px', window.getComputedStyle(bottomCol1.childNodes[0]).getPropertyValue('margin-top')); + assert.match(cssProp(bottomCol1.childNodes[0], 'margin-top'), '-180px'); }, - testItShouldCorrectlyHandleATallVerticallyCenteredElement : function() { + 'ShouldCorrectlyHandleATallVerticallyCenteredElement' : function() { createCf().flow('
height200
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed600'); - assertEquals(0, fixed.offsetTop); - assertEquals(0, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 0); - assertNull(page.querySelector('.cf-column-1')); + assert.isNull(page.querySelector('.cf-column-1')); var column2 = page.querySelector('.cf-column-2'); - assertEquals(0, column2.offsetTop); - assertEquals('0px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column2.offsetTop, 0); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '0px'); }, - testItShouldCorrectlyHandleATallVerticallyCenteredElementInCol2 : function() { + 'ShouldCorrectlyHandleATallVerticallyCenteredElementInCol2' : function() { createCf().flow('
height1000
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed600'); - assertNull(target.querySelector('.cf-page-2')); + assert.isNull(target.querySelector('.cf-page-2')); - assertEquals(0, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 275); - assertNull(page.querySelector('.cf-column-2')); + assert.isNull(page.querySelector('.cf-column-2')); var column1 = page.querySelector('.cf-column-1'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, column1.offsetTop); - assertEquals('0px', window.getComputedStyle(column1.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column1.offsetTop, 0); + assert.match(cssProp(column1.childNodes[0], 'margin-top'), '0px'); - assertEquals(0, column3.offsetTop); - assertEquals('-600px', window.getComputedStyle(column3.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column3.offsetTop, 0); + assert.match(cssProp(column3.childNodes[0], 'margin-top'), '-600px'); }, - testItShouldCorrectlyHandleATallVerticallyCenteredElementInCol2 : function() { + 'ShouldCorrectlyHandleATallVerticallyCenteredElementInCol2' : function() { createCf().flow('
height1000
', '
fixedContent
'); var page = target.querySelector('.cf-page-1'); var fixed = page.querySelector('.fixed600'); - assertNull(target.querySelector('.cf-page-2')); + assert.isNull(target.querySelector('.cf-page-2')); - assertEquals(0, fixed.offsetTop); - assertEquals(275, fixed.offsetLeft); + assert.match(fixed.offsetTop, 0); + assert.match(fixed.offsetLeft, 275); - assertNull(page.querySelector('.cf-column-2')); + assert.isNull(page.querySelector('.cf-column-2')); var column1 = page.querySelector('.cf-column-1'); var column3 = page.querySelector('.cf-column-3'); - assertEquals(0, column1.offsetTop); - assertEquals('0px', window.getComputedStyle(column1.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column1.offsetTop, 0); + assert.match(cssProp(column1.childNodes[0], 'margin-top'), '0px'); - assertEquals(0, column3.offsetTop); - assertEquals('-600px', window.getComputedStyle(column3.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column3.offsetTop, 0); + assert.match(cssProp(column3.childNodes[0], 'margin-top'), '-600px'); }, - testItShouldHandleANormalAndACenteredElementInTheSameColumn : function() { + 'ShouldHandleANormalAndACenteredElementInTheSameColumn' : function() { createCf().flow('
height600
', '
fixedContent
fixedContent
'); @@ -604,26 +589,26 @@ TestCase('FixedElements', { var fixedTop = page.querySelector('.anchor-top-left'); var fixedMid = page.querySelector('.anchor-middle-left'); - assertNull(target.querySelector('.cf-page-2')); + assert.isNull(target.querySelector('.cf-page-2')); - assertEquals(0, fixedTop.offsetTop); - assertEquals(250, fixedMid.offsetTop); + assert.match(fixedTop.offsetTop, 0); + assert.match(fixedMid.offsetTop, 250); var column1s = page.querySelectorAll('.cf-column-1'); - assertEquals(2, column1s.length); + assert.match(column1s.length, 2); - assertEquals(120, column1s[0].offsetTop); - assertEquals(100, column1s[0].offsetHeight); + assert.match(column1s[0].offsetTop, 120); + assert.match(column1s[0].offsetHeight, 100); - assertEquals(380, column1s[1].offsetTop); - assertEquals(220, column1s[1].offsetHeight); - assertEquals('-100px', window.getComputedStyle(column1s[1].childNodes[0]).getPropertyValue('margin-top')); + assert.match(column1s[1].offsetTop, 380); + assert.match(column1s[1].offsetHeight, 220); + assert.match(cssProp(column1s[1].childNodes[0], 'margin-top'), '-100px'); var column2 = page.querySelector('.cf-column-2'); - assertEquals('-320px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '-320px'); }, - testItShouldHandleANormalAndACenteredElementInTheSameColumnButSwapped : function() { + 'ShouldHandleANormalAndACenteredElementInTheSameColumnButSwapped' : function() { createCf().flow('
height600
', '
fixedContent
fixedContent
'); @@ -632,26 +617,26 @@ TestCase('FixedElements', { var fixedTop = page.querySelector('.anchor-top-left'); var fixedMid = page.querySelector('.anchor-middle-left'); - assertNull(target.querySelector('.cf-page-2')); + assert.isNull(target.querySelector('.cf-page-2')); - assertEquals(0, fixedTop.offsetTop); - assertEquals(250, fixedMid.offsetTop); + assert.match(fixedTop.offsetTop, 0); + assert.match(fixedMid.offsetTop, 250); var column1s = page.querySelectorAll('.cf-column-1'); - assertEquals(2, column1s.length); + assert.match(column1s.length, 2); - assertEquals(120, column1s[0].offsetTop); - assertEquals(100, column1s[0].offsetHeight); + assert.match(column1s[0].offsetTop, 120); + assert.match(column1s[0].offsetHeight, 100); - assertEquals(380, column1s[1].offsetTop); - assertEquals(220, column1s[1].offsetHeight); - assertEquals('-100px', window.getComputedStyle(column1s[1].childNodes[0]).getPropertyValue('margin-top')); + assert.match(column1s[1].offsetTop, 380); + assert.match(column1s[1].offsetHeight, 220); + assert.match(cssProp(column1s[1].childNodes[0], 'margin-top'), '-100px'); var column2 = page.querySelector('.cf-column-2'); - assertEquals('-320px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '-320px'); }, - testItShouldAllowABottomAlignedElementUnderneathACenteredElement : function() { + 'ShouldAllowABottomAlignedElementUnderneathACenteredElement' : function() { createCf().flow('
height600
', '
fixedContent
fixedContent
'); @@ -660,22 +645,22 @@ TestCase('FixedElements', { var fixedBot = page.querySelector('.anchor-bottom-left'); var fixedMid = page.querySelector('.anchor-middle-left'); - assertNull(target.querySelector('.cf-page-2')); + assert.isNull(target.querySelector('.cf-page-2')); - assertEquals(500, fixedBot.offsetTop); - assertEquals(250, fixedMid.offsetTop); + assert.match(fixedBot.offsetTop, 500); + assert.match(fixedMid.offsetTop, 250); var column1 = page.querySelectorAll('.cf-column-1'); - assertEquals(2, column1.length); + assert.match(column1.length, 2); - assertEquals(0, column1[0].offsetTop); - assertEquals(220, column1[0].offsetHeight); + assert.match(column1[0].offsetTop, 0); + assert.match(column1[0].offsetHeight, 220); - assertEquals(380, column1[1].offsetTop); - assertEquals(100, column1[1].offsetHeight); + assert.match(column1[1].offsetTop, 380); + assert.match(column1[1].offsetHeight, 100); }, - testItShouldHandleACollisionBetweenCenteredElements : function() { + 'ShouldHandleACollisionBetweenCenteredElements' : function() { createCf().flow('
height600
', '
fixedContent
fixedContent
'); @@ -683,23 +668,23 @@ TestCase('FixedElements', { var fixed1 = page.querySelector('.fixed100'); var fixed2 = page.querySelector('.fixed'); - assertEquals(250, fixed1.offsetTop); - assertEquals(200, fixed2.offsetTop); + assert.match(fixed1.offsetTop, 250); + assert.match(fixed2.offsetTop, 200); var column1 = page.querySelectorAll('.cf-column-1'); - assertEquals(2, column1.length); + assert.match(column1.length, 2); - assertEquals(0, column1[0].offsetTop); - assertEquals(180, column1[0].offsetHeight); + assert.match(column1[0].offsetTop, 0); + assert.match(column1[0].offsetHeight, 180); - assertEquals(420, column1[1].offsetTop); - assertEquals(180, column1[1].offsetHeight); + assert.match(column1[1].offsetTop, 420); + assert.match(column1[1].offsetHeight, 180); var column2 = page.querySelector('.cf-column-2'); - assertEquals('-360px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '-360px'); }, - testItShouldHonourTheMinimumColumnHeight : function() { + 'ShouldHonourTheMinimumColumnHeight' : function() { createCf({ columnGap : 25, @@ -709,15 +694,15 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); - assertNull(page.querySelector('.cf-column-1')); + assert.isNull(page.querySelector('.cf-column-1')); var column2 = page.querySelector('.cf-column-2'); - assertEquals(0, column2.offsetTop); - assertEquals(600, column2.offsetHeight); - assertEquals('0px', window.getComputedStyle(column2.childNodes[0]).getPropertyValue('margin-top')); + assert.match(column2.offsetTop, 0); + assert.match(column2.offsetHeight, 600); + assert.match(cssProp(column2.childNodes[0], 'margin-top'), '0px'); }, - testRegressionPageClassShouldNotResultInEmptyPages : function() { + 'RegressionPageClassShouldNotResultInEmptyPages' : function() { createCf({ columnGap : 25, @@ -729,11 +714,11 @@ TestCase('FixedElements', { var page2 = target.querySelector('.cf-page-2'); var column = page1.querySelector('.cf-column-1'); - assertTrue(column instanceof HTMLElement); - assertNull(page2.querySelector('.cf-column-1')); + assert(column instanceof HTMLElement); + assert.isNull(page2.querySelector('.cf-column-1')); }, - testItShouldCorrectlyFlowContentWhenColspan1IsFollowedByColspan2 : function() { + 'ShouldCorrectlyFlowContentWhenColspan1IsFollowedByColspan2' : function() { createCf({ columnGap : 25, @@ -744,33 +729,33 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var column1 = page.querySelector('.cf-column-1'); - assertEquals(440, column1.offsetTop); - assertEquals(160, column1.offsetHeight); + assert.match(column1.offsetTop, 440); + assert.match(column1.offsetHeight, 160); var column2s = page.querySelectorAll('.cf-column-2'); - assertEquals(2, column2s.length); + assert.match(column2s.length, 2); - assertEquals(0, column2s[0].offsetTop); - assertEquals(200, column2s[0].offsetHeight); + assert.match(column2s[0].offsetTop, 0); + assert.match(column2s[0].offsetHeight, 200); - assertEquals(440, column2s[1].offsetTop); - assertEquals(160, column2s[1].offsetHeight); + assert.match(column2s[1].offsetTop, 440); + assert.match(column2s[1].offsetHeight, 160); }, - testItShouldAllowFixedElementsToBeShiftedVertically : function() { + 'ShouldAllowFixedElementsToBeShiftedVertically' : function() { createCf().flow('
height300
', '
1
'); var page = target.querySelector('.cf-page-1'); var column1 = page.querySelector('.cf-column-1'); - assertEquals(200, column1.offsetTop); - assertEquals(400, column1.offsetHeight); + assert.match(column1.offsetTop, 200); + assert.match(column1.offsetHeight, 400); }, - testItShouldSetExplicitWidthOnFixedElementsWithAutoWidth : function() { + 'ShouldSetExplicitWidthOnFixedElementsWithAutoWidth' : function() { createCf().flow('
height300
', '
1
'); @@ -778,12 +763,12 @@ TestCase('FixedElements', { var column1 = page.querySelector('.cf-column-1'); var fixed = page.querySelector('.fixed'); - assertEquals("250px", fixed.style.width); - assertEquals(250, parseInt(window.getComputedStyle(fixed).getPropertyValue('width'))); + assert.match(fixed.style.width, "250px"); + assert.match(parseInt(cssProp(fixed, 'width')), 250); }, - testItShouldSetExplicitWidthOnFixedElementsOverTwoColumns : function() { + 'ShouldSetExplicitWidthOnFixedElementsOverTwoColumns' : function() { createCf().flow('
height300
', '
1
'); @@ -791,12 +776,12 @@ TestCase('FixedElements', { var column1 = page.querySelector('.cf-column-1'); var fixed = page.querySelector('.fixed'); - assertEquals("525px", fixed.style.width); - assertEquals(525, parseInt(window.getComputedStyle(fixed).getPropertyValue('width'))); + assert.match(fixed.style.width, "525px"); + assert.match(parseInt(cssProp(fixed, 'width')), 525); }, - testItShouldRespectAFloatValueForMinFixedPadding : function() { + 'ShouldRespectAFloatValueForMinFixedPadding' : function() { // 205px, minimum gap 20px, next element starts at 240px createCf().flow('

flowedContent

', '
fixedContent
'); @@ -804,8 +789,8 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var column = page.querySelector('.cf-column'); - assertEquals(240, column.offsetTop); - assertEquals(360, column.offsetHeight); + assert.match(column.offsetTop, 240); + assert.match(column.offsetHeight, 360); // 205px, minimum gap 10px, next element starts at 220px @@ -818,8 +803,8 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var column = page.querySelector('.cf-column'); - assertEquals(220, column.offsetTop); - assertEquals(380, column.offsetHeight); + assert.match(column.offsetTop, 220); + assert.match(column.offsetHeight, 380); // 200px, minimum gap 30px, next element starts at 240px @@ -832,12 +817,11 @@ TestCase('FixedElements', { var page = target.querySelector('.cf-page-1'); var column = page.querySelector('.cf-column'); - assertEquals(240, column.offsetTop); - assertEquals(360, column.offsetHeight); + assert.match(column.offsetTop, 240); + assert.match(column.offsetHeight, 360); }, -/* - testItShouldSetExplicitHeightOnImagesWithSpecifiedAspectRatio : function() { + '//ShouldSetExplicitHeightOnImagesWithSpecifiedAspectRatio' : function() { createCf().flow('
height300
', '
'); @@ -846,12 +830,11 @@ TestCase('FixedElements', { var fixed = page.querySelector('.fixed'); var img = fixed.querySelector('img'); - assertEquals("200px", img.style.width); - assertEquals("100px", img.style.height); - assertEquals(200, parseInt(window.getComputedStyle(img).getPropertyValue('width'))); - assertEquals(100, parseInt(window.getComputedStyle(img).getPropertyValue('height'))); + assert.match(img.style.width, "200px"); + assert.match(img.style.height, "100px"); + assert.match(parseInt(cssProp(img, 'width')), 200); + assert.match(parseInt(cssProp(img, 'height')), 100); }, - */ diff --git a/test/helpers/helpers.js b/test/helpers/helpers.js new file mode 100644 index 0000000..c16ea9b --- /dev/null +++ b/test/helpers/helpers.js @@ -0,0 +1,16 @@ +var cf, target, viewport; + +function createCf(config) { + cf = new FTColumnflow('targetid', 'viewportid', config || { + columnGap : 25, + columnCount : 3 + }); + target = document.getElementById('targetid'); + viewport = document.getElementById('viewportid'); + + return cf; +} + +function cssProp(element, property) { + return window.getComputedStyle(element, null).getPropertyValue(property); +} diff --git a/test/helpers/stylesheets.js b/test/helpers/stylesheets.js new file mode 100644 index 0000000..5e4f277 --- /dev/null +++ b/test/helpers/stylesheets.js @@ -0,0 +1,161 @@ +function addStylesheets(urls, callback) { + + var url = urls.shift(), + + _loaded = function(success, element) { + if (success) { + if ((url = urls.shift())) { + loadStyleSheet(url, _loaded); + } else { + callback(); + } + } else { + console.error('Failed to load stylesheet', url, arguments); + } + } + + loadStyleSheet(url, _loaded); +} + + +function removeStyleSheets() { + var styles = document.getElementsByTagName('style'); + for (var i = 0, len = styles.length; i < len; i++) { + if (styles[i] && styles[i].nodeType == 1) styles[i].parentNode.removeChild(styles[i]); + } +} + + + + + + +/* http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof */ + +( function( GLOBAL, WIN ) { + var ERROR_TIMEOUT = 15000, // How long to wait (in milliseconds) before realising the style sheet has failed to load + HEAD = WIN.document.getElementsByTagName( 'head' )[0], // a reference to the document.head for inserting link nodes into + ID_PREFIX = 'stylesheet-', + READYSTATE_INTERVAL = 10, // How often to check (in milliseconds) whether the style sheet has loaded successfully + callbacks = {}, count = 0, cssRules, loaded = {}, queue = {}, sheet; + + function loadStyleSheet( path, fn, scope ) { + addCallback( path, fn, scope ); // add the callback for this stylesheet + if ( queue[path] ) return GLOBAL; // if the style sheet is already queued the we just need to wait + if ( loaded[path] && inDoc( loaded[path].id ) ) { // if the style sheet is already in the document then just fire the last callback that was added + fireStyleSheetLoaded( path, true, loaded[path] ); + return GLOBAL; + } + + var el = createStyleSheet( path ), id, + interval_id = setTimeout( partial( onError, path ), ERROR_TIMEOUT ), // start counting down to FAIL! + timeout_id = setInterval( partial( checkStyleSheetLoaded, path ), READYSTATE_INTERVAL ); // start checking if the style sheet is loaded + + queue[path] = { el : el, interval : interval_id, path : path, timeout : timeout_id }; // add the style sheet to the queue of loading style sheets + + if ( 'onload' in el ) el.onload = partial( _handleOnLoad, path ); + if ( 'onreadystatechange' in el ) el.onreadystatechange = partial( _handleReadyState, path ); + + id = setTimeout( function() { // pop out of current stack to prevent browser lock + clearTimeout( id ); id = null; + HEAD.appendChild( el ); // insert the link node into the DOM, this will actually start the browser trying to load the style sheet + }, 1 ); + + return GLOBAL; + } + + function _handleOnLoad( path ) { + var o = queue[path]; + return this[sheet][cssRules].length ? onLoad( o ) : onError( path ); + } + + function _handleReadyState( path ) { + if ( this.readyState == 'complete' || this.readyState == 'loaded' ) _handleOnLoad.call( this, path ); + } + + function addCallback( path, fn, scope ) { + if ( !isFunc( fn ) ) return; + callbacks[path] || ( callbacks[path] = [] ); // create a callback array for this path if one doesn't exist already + callbacks[path].push( { fn : fn, scope : scope } ); // add the callback function and (optional) scope to the array + } + + function checkStyleSheetLoaded( path ) { // checking to see if the stylesheet is loaded + var o = queue[path], el; + if ( !o ) return false; // fixes an issue with MSIE that calls this again after the style sheet has been removed from the queue + el = o.el; + try { el[sheet] && el[sheet][cssRules].length && onLoad( o ); } // this is where we check that the stylesheet has loaded successfully and if so fire the onLoad function + catch( e ) { return false; } + } + + function clear( o ) { // when the style sheet has loaded or has failed to load we want to: + delete queue[o.path]; // delete it from the queue of loading style sheets + clearInterval( o.interval ); // stop checking it has loaded + clearTimeout( o.timeout ); // clear the fail timeout (for efficiency) + var el = o.el; + if ( 'onload' in el ) el.onload = null; + if ( 'onreadystatechange' in el ) el.onreadystatechange = null; + } + + function createStyleSheet( path ) { // pretty self explanatory + var el = document.createElement( 'link' ); + el.id = ID_PREFIX + ( ++count ); + el.setAttribute( 'href', path ); + el.setAttribute( 'rel', 'stylesheet' ); + el.setAttribute( 'type', 'text/css' ); + + if ( !sheet ) { // only assign these once + cssRules = 'cssRules'; sheet = 'sheet'; + if ( !( sheet in el ) ) { // MSIE uses non-standard property names + cssRules = 'rules'; + sheet = 'styleSheet'; + } + } + + return el; + } + + function fireStyleSheetLoaded( path, success, el ) { + var cbs = callbacks[path], o; + if ( !cbs ) return; +// we shift all the callbacks off to clear the callbacks queue for this specific style sheet to prevent them been called again + while ( o = cbs.shift() ) fireCallback( o.fn, o.scope, success, el ); + } + + function fireCallback( fn, scope, success, el ) { fn.call( scope || WIN, success, el ); } + + function inDoc( id ) { return !!WIN.document.getElementById( id ); } // checks whether a style sheet is still in the document, if not we can load it again + + function isFunc( fn ) { return typeof fn == 'function'; } + + function onError( path ) { + var o = queue[path], el = o.el; + clear( o ); + HEAD.removeChild( el ); // since the style sheet failed to load, let's remove it from the DOM + fireStyleSheetLoaded( path, false, el ); + } + + function onLoad( o ) { + var el = o.el, path = o.path; + clear( o ); + loaded[path] = el; + fireStyleSheetLoaded( path, true , el ); + } + + function partial() { + var slice = Array.prototype.slice, + args = slice.call( arguments ), + fn = args.shift(); + return !args.length ? fn : function() { + return fn.apply( this, args.concat( slice.call( arguments ) ) ); + } + } + + GLOBAL.loadStyleSheet = loadStyleSheet; + +} )( this /* <- a reference to your global namespace object, will assign the loadStyleSheet method there. + e.g. pass your "$" object to be able to call $.loadStyleSheet(); + alternatively, leave as "this" to use as window.loadStyleSheet(); */, + this /* <- a reference to the current window object */ ); + + + diff --git a/test/reflow-test.js b/test/reflow-test.js new file mode 100644 index 0000000..2b6d565 --- /dev/null +++ b/test/reflow-test.js @@ -0,0 +1,120 @@ +/** + * FTColumnflow Reflow test suite + * + * @copyright The Financial Times Limited [All Rights Reserved] +*/ + + +buster.testCase('Reflow', { + + setUp : function(done) { + document.body.innerHTML = '
'; + addStylesheets(['all.css', 'reflow.css'], done); + }, + + tearDown : function() { + removeStyleSheets(); + document.body.className = ''; + }, + + 'ShouldRewriteCssBlockAndNotAddItAgain' : function() { + + var lengthBefore = document.getElementsByTagName('style').length; + + createCf().flow('
height600
'); + + var lengthAfter = document.getElementsByTagName('style').length; + + cf.flow(); + + assert.match(document.getElementsByTagName('style').length, lengthAfter); + }, + + '//ShouldReflow' : function() { + + // page is 800 x 600, columns are 350 x 600 + createCf({ + columnGap : 100, + columnCount : 2, + }).flow('
height3000
'); + + // Change viewport dimensions + viewport.style.width = "600px"; + viewport.style.height = "500px"; + + // page is 600 x 500, columns are 250 x 500 + cf.reflow(); + + assert.match(target.querySelectorAll('.cf-page-1').length, 1); + + var page = target.querySelector('.cf-page-1'); + + assertTrue(page instanceof HTMLElement); + assert.match(page.clientWidth, 600); + assert.match(page.clientHeight, 500); + + var column1 = page.querySelector('.cf-column-1'); + var column2 = page.querySelector('.cf-column-2'); + + assert.match(column1.clientWidth, 250); + assert.match(column1.clientHeight, 500); + + assert.match(column1.childNodes.length, 1); + assert.match(column2.childNodes.length, 1); + + assert.match(column2.childNodes[0].style.marginTop, '-500px'); + }, + + 'ShouldReflowUsingNewConfig' : function() { + + createCf({ + columnGap : 100, + columnCount : 2, + }).flow('
height3000
'); + + var column1 = target.querySelector('.cf-page-1 .cf-column-1'); + + assert.match(column1.clientWidth, 350); + assert.match(column1.clientHeight, 600); + assert.match(target.querySelectorAll('.cf-page-1 .cf-column').length, 2); + assert.match(column1.childNodes.length, 1); + assert.className(column1.childNodes[0], 'height3000'); + + cf.reflow({ + columnGap : 25, + columnCount : 3, + }); + + var column1 = target.querySelector('.cf-page-1 .cf-column-1'); + + assert.match(column1.clientWidth, 250); + assert.match(column1.clientHeight, 600); + assert.match(target.querySelectorAll('.cf-page-1 .cf-column').length, 3); + assert.match(column1.childNodes.length, 1); + }, + + 'ShouldRemoveStylesAndDomNodesOnDestroy' : function() { + + var stylesBefore = document.querySelectorAll('style').length; + + createCf().flow('
height3000
'); + + assert.defined(target); + refute.equals(target.innerHTML, ''); + assert.match(document.querySelectorAll('style').length, (stylesBefore + 1)); + + cf.destroy(); + + assert.isNull(document.getElementById('targetid')); + assert.match(document.querySelectorAll('style').length, stylesBefore); + }, + + +/* + + +// NB - height sanitizing routine should not round up every time the line-height is changed! Need to work with the original, untouched elements and padding each time, and round up without modifying them somehow. + +//*/ + +}); \ No newline at end of file