// ======================================================================== // SC Miscellaneous Utils Tests - documentOffset // ======================================================================== /*global module test htmlbody ok equals same */ var pane, view1, view2, view3, view4; module("SC.offset", { setup: function() { htmlbody(''); var viewportEl; SC.RunLoop.begin(); // Even though a full SC app doesn't really allow the viewport to be scaled or scrolled by default (thus // the offset by viewport will always equal offset by document), we simulate an app that uses a // scrollable viewport to test the validity of the functions. if (SC.browser.mobileSafari) { viewportEl = $("[name='viewport']")[0]; viewportEl.setAttribute('content','initial-scale=0.9, minimum-scale=0.5, maximum-scale=1.2, user-scalable=yes, width=device-height'); } pane = SC.MainPane.create({ childViews: [ SC.View.extend({ classNames: 'upper'.w(), layout: { top: 20, left: 20, width: 100, height: 100 }, childViews: [ SC.View.extend({ classNames: 'upper-inner'.w(), layout: { top: 10, left: 10, width: 20, height: 20 } })] }), SC.View.extend({ classNames: 'lower'.w(), layout: { top: 1200, left: 20, width: 100, height: 100 }, childViews: [ SC.View.extend({ classNames: 'lower-inner'.w(), layout: { top: 10, left: 10, width: 20, height: 20 } })] })] // Useful for debugging in iOS // /** Allow default touch events */ // touchStart: function(touch) { // if (SC.browser.mobileSafari) touch.allowDefault(); // }, // // touchesDragged: function(evt, touches) { // if (SC.browser.mobileSafari) evt.allowDefault(); // }, // // touchEnd: function(touch) { // if (SC.browser.mobileSafari) touch.allowDefault(); // } }); pane.append(); SC.RunLoop.end(); view1 = pane.childViews[0]; view2 = pane.childViews[1]; view3 = view1.childViews[0]; view4 = view2.childViews[0]; }, teardown: function() { // Useful for debugging in iOS // if (!SC.browser.mobileSafari) { pane.remove(); pane = view1 = view2 = view3 = view4 = null; // } clearHtmlbody(); } }); function checkDocumentOffset(element, top, left) { var docOffset = SC.offset(element, 'document'); equals(docOffset.top, top, '%@ document offset top'.fmt(element[0].className)); equals(docOffset.left, left, '%@ document offset left'.fmt(element[0].className)); } function checkViewportOffset(element, top, left) { var viewOffset = SC.offset(element, 'viewport'); equals(viewOffset.top, top, '%@ viewport offset top'.fmt(element[0].className)); equals(viewOffset.left, left, '%@ viewport offset left'.fmt(element[0].className)); } function checkParentOffset(element, top, left) { var parentOffset = SC.offset(element, 'parent'); equals(parentOffset.top, top, '%@ parent offset top'.fmt(element[0].className)); equals(parentOffset.left, left, '%@ parent offset left'.fmt(element[0].className)); } test("Regular views", function() { var element; element = view1.$(); checkDocumentOffset(element, 20, 20); checkViewportOffset(element, 20, 20); checkParentOffset(element, 20, 20); element = view3.$(); checkDocumentOffset(element, 30, 30); checkViewportOffset(element, 30, 30); checkParentOffset(element, 10, 10); }); test("A regular view not visible within the visual viewport", function() { var element; element = view2.$(); checkDocumentOffset(element, 1200, 20); checkViewportOffset(element, 1200, 20); checkParentOffset(element, 1200, 20); element = view4.$(); checkDocumentOffset(element, 1210, 30); checkViewportOffset(element, 1210, 30); checkParentOffset(element, 10, 10); }); function testPosition4(element1, element2, element3, element4) { checkDocumentOffset(element1, 20, 20); checkViewportOffset(element1, -80, -80); checkParentOffset(element1, 20, 20); checkDocumentOffset(element3, 30, 30); checkViewportOffset(element3, -70, -70); checkParentOffset(element3, 10, 10); checkDocumentOffset(element2, 1200, 20); checkViewportOffset(element2, 1100, -80); checkParentOffset(element2, 1200, 20); checkDocumentOffset(element4, 1210, 30); checkViewportOffset(element4, 1110, -70); checkParentOffset(element4, 10, 10); window.start(); // continue the tests } function testPosition3(element1, element2, element3, element4) { checkDocumentOffset(element1, 20, 20); checkViewportOffset(element1, -80, 10); checkParentOffset(element1, 20, 20); checkDocumentOffset(element3, 30, 30); checkViewportOffset(element3, -70, 20); checkParentOffset(element3, 10, 10); checkDocumentOffset(element2, 1200, 20); checkViewportOffset(element2, 1100, 10); checkParentOffset(element2, 1200, 20); checkDocumentOffset(element4, 1210, 30); checkViewportOffset(element4, 1110, 20); checkParentOffset(element4, 10, 10); window.start(); } function testPosition2(element1, element2, element3, element4) { checkDocumentOffset(element1, 20, 20); checkViewportOffset(element1, 10, 10); checkParentOffset(element1, 20, 20); checkDocumentOffset(element3, 30, 30); checkViewportOffset(element3, 20, 20); checkParentOffset(element3, 10, 10); checkDocumentOffset(element2, 1200, 20); checkViewportOffset(element2, 1190, 10); checkParentOffset(element2, 1200, 20); checkDocumentOffset(element4, 1210, 30); checkViewportOffset(element4, 1200, 20); checkParentOffset(element4, 10, 10); window.start(); } function testPosition1(element1, element2, element3, element4) { // For some reason, the scroll jumps back to 0,0 if we don't set it here window.scrollTo(0, 10); checkDocumentOffset(element1, 20, 20); checkViewportOffset(element1, 10, 20); checkParentOffset(element1, 20, 20); checkDocumentOffset(element3, 30, 30); checkViewportOffset(element3, 20, 30); checkParentOffset(element3, 10, 10); checkDocumentOffset(element2, 1200, 20); checkViewportOffset(element2, 1190, 20); checkParentOffset(element2, 1200, 20); checkDocumentOffset(element4, 1210, 30); checkViewportOffset(element4, 1200, 30); checkParentOffset(element4, 10, 10); window.start(); } test("A regular view with window scroll offset top:10", function() { var element1 = view1.$(), element2 = view2.$(), element3 = view3.$(), element4 = view4.$(); window.stop(); window.scrollTo(0, 10); SC.RunLoop.begin(); SC.Timer.schedule({ target: this, action: function() { return testPosition1(element1, element2, element3, element4); }, interval: 200 }); SC.RunLoop.end(); }); test("A regular view with window scroll offset top:10, left: 10", function() { var element1 = view1.$(), element2 = view2.$(), element3 = view3.$(), element4 = view4.$(); window.stop(); window.scrollTo(10, 10); SC.RunLoop.begin(); SC.Timer.schedule({ target: this, action: function() { return testPosition2(element1, element2, element3, element4); }, interval: 200 }); SC.RunLoop.end(); }); test("A regular view with window scroll offset top:100, left: 10", function() { var element1 = view1.$(), element2 = view2.$(), element3 = view3.$(), element4 = view4.$(); window.stop(); window.scrollTo(10, 100); SC.RunLoop.begin(); SC.Timer.schedule({ target: this, action: function() { return testPosition3(element1, element2, element3, element4); }, interval: 200 }); SC.RunLoop.end(); }); test("A regular view with window scroll offset top:100, left: 100", function() { var element1 = view1.$(), element2 = view2.$(), element3 = view3.$(), element4 = view4.$(); window.stop(); window.scrollTo(100, 100); SC.RunLoop.begin(); SC.Timer.schedule({ target: this, action: function() { return testPosition4(element1, element2, element3, element4); }, interval: 200 }); SC.RunLoop.end(); });