From 9bb02a4c41847b9cbe1ab53132a9b281aaa4bc46 Mon Sep 17 00:00:00 2001 From: Adrian Vasiliu Date: Thu, 9 Jan 2014 17:02:07 +0100 Subject: [PATCH 1/2] delite/Scrollable mixin --- Scrollable.js | 227 ++++++++++++++++++ Scrollable/themes/Scrollable_template.less | 5 + Scrollable/themes/blackberry/Scrollable.less | 1 + .../themes/blackberry/Scrollable_css.js | 7 + Scrollable/themes/bootstrap/Scrollable.less | 1 + Scrollable/themes/bootstrap/Scrollable_css.js | 7 + Scrollable/themes/custom/Scrollable.less | 1 + Scrollable/themes/custom/Scrollable_css.js | 7 + Scrollable/themes/holodark/Scrollable.less | 1 + Scrollable/themes/holodark/Scrollable_css.js | 7 + Scrollable/themes/ios/Scrollable.less | 1 + Scrollable/themes/ios/Scrollable_css.js | 7 + Scrollable/themes/windows/Scrollable.less | 1 + Scrollable/themes/windows/Scrollable_css.js | 7 + tests/Scrollable-shared.js | 191 +++++++++++++++ tests/Scrollable.js | 48 ++++ tests/ScrollableTestContainer-markup.js | 48 ++++ tests/ScrollableTestContainer-prog.js | 57 +++++ tests/ScrollableTestContainer.js | 15 ++ tests/unit.js | 5 +- 20 files changed, 643 insertions(+), 1 deletion(-) create mode 100644 Scrollable.js create mode 100644 Scrollable/themes/Scrollable_template.less create mode 100644 Scrollable/themes/blackberry/Scrollable.less create mode 100644 Scrollable/themes/blackberry/Scrollable_css.js create mode 100644 Scrollable/themes/bootstrap/Scrollable.less create mode 100644 Scrollable/themes/bootstrap/Scrollable_css.js create mode 100644 Scrollable/themes/custom/Scrollable.less create mode 100644 Scrollable/themes/custom/Scrollable_css.js create mode 100644 Scrollable/themes/holodark/Scrollable.less create mode 100644 Scrollable/themes/holodark/Scrollable_css.js create mode 100644 Scrollable/themes/ios/Scrollable.less create mode 100644 Scrollable/themes/ios/Scrollable_css.js create mode 100644 Scrollable/themes/windows/Scrollable.less create mode 100644 Scrollable/themes/windows/Scrollable_css.js create mode 100644 tests/Scrollable-shared.js create mode 100644 tests/Scrollable.js create mode 100644 tests/ScrollableTestContainer-markup.js create mode 100644 tests/ScrollableTestContainer-prog.js create mode 100644 tests/ScrollableTestContainer.js diff --git a/Scrollable.js b/Scrollable.js new file mode 100644 index 0000000000..17b3c2d890 --- /dev/null +++ b/Scrollable.js @@ -0,0 +1,227 @@ +define([ + "dcl/dcl", + "dojo/dom", + "dojo/dom-style", + "dojo/dom-class", + "dojo/_base/fx", + "dojo/fx/easing", + "delite/Invalidating", + "delite/themes/load!./Scrollable/themes/{{theme}}/Scrollable_css" +], function (dcl, dom, domStyle, domClass, baseFx, easing, Invalidating) { + + // module: + // delite/Scrollable + + return dcl(Invalidating, { + // summary: + // A mixin which adds scrolling capabilities to a widget. + // description: + // When mixed into a widget, this mixin adds to it scrolling capabilities + // based on the overflow: scroll CSS property. + // By default, the scrolling capabilities are added to the widget + // node itself. The host widget can chose the node thanks to the property + // 'scrollableNode'. + // During interactive or programmatic scrolling, native "scroll" + // events are emitted, and can be listen as follows (here, + // 'scrollWidget' is the widget into which this mixin is mixed): + // | scrollWidget.on("scroll", function () { + // | ... + // | } + // For widgets that customize the 'scrollableNode' property, + // the events should be listen on widget.scrollableNode. + // TODO: improve the doc. + + // TODO: optional styling of the scrollbar for browsers which by default do not provide + // a scroll indicator. + + // scrollDirection: String + // The direction of the interactive scroll. Possible values are: + // "vertical", "horizontal", "both, and "none". The default value is "vertical". + // Note that scrolling programmatically using scrollTo() is + // possible on both horizontal and vertical directions independently + // on the value of scrollDirection. + scrollDirection: "vertical", + + // scrollableNode: [readonly] DomNode + // Designates the descendant node of this widget which is made scrollable. + // The default value is 'null'. If not set, defaults to this widget + // itself ('this'). + // Note that this property can be set only at construction time, as a + // constructor argument or in markup as a property of the widget into + // which this class is mixed. + scrollableNode: null, + + preCreate: function () { + this.addInvalidatingProperties("scrollDirection"); + }, + + refreshRendering: function () { + if (!this.scrollableNode) { + this.scrollableNode = this; // If unspecified, defaults to 'this'. + } + + domClass.toggle(this.scrollableNode, "d-scrollable", this.scrollDirection !== "none"); + + dom.setSelectable(this.scrollableNode, false); + + domStyle.set(this.scrollableNode, "overflowX", + /^(both|horizontal)$/.test(this.scrollDirection) ? "scroll" : ""); + domStyle.set(this.scrollableNode, "overflowY", + /^(both|vertical)$/.test(this.scrollDirection) ? "scroll" : ""); + }, + + buildRendering: function () { + this.invalidateRendering(); + }, + + isTopScroll: function () { + // summary: + // Returns true if container's scroll has reached the maximum at + // the top of the content. Returns false otherwise. + // example: + // | scrollContainer.on("scroll", function () { + // | if (scrollContainer.isTopScroll()) { + // | console.log("Scroll reached the maximum at the top"); + // | } + // | } + // returns: Boolean + return this.scrollableNode.scrollTop === 0; + }, + + isBottomScroll: function () { + // summary: + // Returns true if container's scroll has reached the maximum at + // the bottom of the content. Returns false otherwise. + // example: + // | scrollContainer.on("scroll", function () { + // | if (scrollContainer.isBottomScroll()) { + // | console.log("Scroll reached the maximum at the bottom"); + // | } + // | } + // returns: Boolean + var scrollableNode = this.scrollableNode; + return scrollableNode.offsetHeight + scrollableNode.scrollTop >= + scrollableNode.scrollHeight; + }, + + isLeftScroll: function () { + // summary: + // Returns true if container's scroll has reached the maximum at + // the left of the content. Returns false otherwise. + // example: + // | scrollContainer.on("scroll", function () { + // | if (scrollContainer.isLeftScroll()) { + // | console.log("Scroll reached the maximum at the left"); + // | } + // | } + // returns: Boolean + return this.scrollableNode.scrollLeft === 0; + }, + + isRightScroll: function () { + // summary: + // Returns true if container's scroll has reached the maximum at + // the right of the content. Returns false otherwise. + // example: + // | scrollContainer.on("scroll", function () { + // | if (scrollContainer.isRightScroll()) { + // | console.log("Scroll reached the maximum at the right"); + // | } + // | } + // returns: Boolean + var scrollableNode = this.scrollableNode; + return scrollableNode.offsetWidth + scrollableNode.scrollLeft >= scrollableNode.scrollWidth; + }, + + getCurrentScroll: function () { + // summary: + // Returns the current amount of scroll, as an object with x and y properties + // for the horizontal and vertical scroll amount. + // This is a convenience method and it is not supposed to be overridden. + // returns: Object + return {x: this.scrollableNode.scrollLeft, y: this.scrollableNode.scrollTop}; + }, + + scrollBy: function (by, duration) { + // summary: + // Scrolls by the given amount. + // by: + // The scroll amount. An object with x and/or y properties, for example + // {x:0, y:-5} or {y:-29}. + // duration: + // Duration of scrolling animation in milliseconds. If 0 or unspecified, + // scrolls without animation. + var to = {}; + if (by.x !== undefined) { + to.x = this.scrollableNode.scrollLeft + by.x; + } + if (by.y !== undefined) { + to.y = this.scrollableNode.scrollTop + by.y; + } + this.scrollTo(to, duration); + }, + + scrollTo: function (to, /*Number?*/duration) { + // summary: + // Scrolls to the given position. + // to: + // The scroll destination position. An object with x and/or y properties, + // for example {x:0, y:-5} or {y:-29}. + // duration: + // Duration of scrolling animation in milliseconds. If 0 or unspecified, + // scrolls without animation. + + var self = this; + var scrollableNode = this.scrollableNode; + if (!duration || duration <= 0) { // shortcut + if (to.x !== undefined) { + scrollableNode.scrollLeft = to.x; + } + if (to.y !== undefined) { + scrollableNode.scrollTop = to.y; + } + } else { + var from = { + x: to.x !== undefined ? scrollableNode.scrollLeft : undefined, + y: to.y !== undefined ? scrollableNode.scrollTop : undefined + }; + var animation = function () { + if (self._animation && self._animation.status() === "playing") { + self._animation.stop(); + } + // dojo/_base/fx._Line cannot be used for animating several + // properties at once. Hence: + baseFx._Line.prototype.getValue = function (/*float*/ n) { + return { + x: ((this.end.x - this.start.x) * n) + this.start.x, + y: ((this.end.y - this.start.y) * n) + this.start.y + }; + }; + var anim = new baseFx.Animation({ + beforeBegin: function () { + if (this.curve) { + delete this.curve; + } + anim.curve = new baseFx._Line(from, to); + }, + onAnimate: function (val) { + if (val.x !== undefined) { + scrollableNode.scrollLeft = val.x; + } + if (val.y !== undefined) { + scrollableNode.scrollTop = val.y; + } + }, + easing: easing.expoInOut, // TODO: IMPROVEME + duration: duration, + rate: 20 // TODO: IMPROVEME + }); + self._animation = anim; + + return anim; // dojo/_base/fx/Animation + }; + animation().play(); + } + } + }); +}); diff --git a/Scrollable/themes/Scrollable_template.less b/Scrollable/themes/Scrollable_template.less new file mode 100644 index 0000000000..f0997a04ad --- /dev/null +++ b/Scrollable/themes/Scrollable_template.less @@ -0,0 +1,5 @@ +.d-scrollable { + -webkit-overflow-scrolling: touch; + /* enable hardware acceleration */ + -webkit-transform: translate3d(0,0,0); +} diff --git a/Scrollable/themes/blackberry/Scrollable.less b/Scrollable/themes/blackberry/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/blackberry/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/blackberry/Scrollable_css.js b/Scrollable/themes/blackberry/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/blackberry/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/Scrollable/themes/bootstrap/Scrollable.less b/Scrollable/themes/bootstrap/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/bootstrap/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/bootstrap/Scrollable_css.js b/Scrollable/themes/bootstrap/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/bootstrap/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/Scrollable/themes/custom/Scrollable.less b/Scrollable/themes/custom/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/custom/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/custom/Scrollable_css.js b/Scrollable/themes/custom/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/custom/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/Scrollable/themes/holodark/Scrollable.less b/Scrollable/themes/holodark/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/holodark/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/holodark/Scrollable_css.js b/Scrollable/themes/holodark/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/holodark/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/Scrollable/themes/ios/Scrollable.less b/Scrollable/themes/ios/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/ios/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/ios/Scrollable_css.js b/Scrollable/themes/ios/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/ios/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/Scrollable/themes/windows/Scrollable.less b/Scrollable/themes/windows/Scrollable.less new file mode 100644 index 0000000000..a8bd0c59ab --- /dev/null +++ b/Scrollable/themes/windows/Scrollable.less @@ -0,0 +1 @@ +@import "../Scrollable_template"; diff --git a/Scrollable/themes/windows/Scrollable_css.js b/Scrollable/themes/windows/Scrollable_css.js new file mode 100644 index 0000000000..168d02bf46 --- /dev/null +++ b/Scrollable/themes/windows/Scrollable_css.js @@ -0,0 +1,7 @@ +define(function(){ return '\ +.d-scrollable {\ + -webkit-overflow-scrolling: touch;\ + /* enable hardware acceleration */\ + -webkit-transform: translate3d(0, 0, 0);\ +}\ +'; } ); diff --git a/tests/Scrollable-shared.js b/tests/Scrollable-shared.js new file mode 100644 index 0000000000..d96e9878ed --- /dev/null +++ b/tests/Scrollable-shared.js @@ -0,0 +1,191 @@ +define([ + "intern!object", + "intern/chai!assert", + "dojo/dom-geometry", + "dojo/dom-class" +], function (registerSuite, assert, domGeom, domClass) { + + // This object is shared by ScrollableContainer tests. + + return { + "Default CSS" : function () { + var w = document.getElementById("sc1"); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + + w = document.getElementById("sc2"); // with scrollDirection == "none" + assert.equal(w.scrollDirection, "none", "wrong scroll direction for sc2!"); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + // when scrollDirection is "none", this CSS class should NOT be present: + assert.isFalse(domClass.contains(w, "d-scrollable")); + + w = document.getElementById("mysc1"); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + }, + + "CSS class dependency on scrollDirection" : function () { + var w = document.getElementById("sc1"); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + + w.scrollDirection = "none"; + w.validateRendering(); // scrollDirection is an invalidating property + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + // when scrollDirection is "none", this CSS class should NOT be present: + assert.isFalse(domClass.contains(w, "d-scrollable")); + + w.scrollDirection = "vertical"; // set back to "vertical" + w.validateRendering(); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + + w.scrollDirection = "horizontal"; // same for "horizontal" + w.validateRendering(); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + + w.scrollDirection = "both"; // same for "both" + w.validateRendering(); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + + w.scrollDirection = "none"; // and none again + w.validateRendering(); + assert.isTrue(domClass.contains(w, "test-scrollable-container")); + // when scrollDirection is "none", this CSS class should NOT be present: + assert.isFalse(domClass.contains(w, "d-scrollable")); + }, + + "scrollableNode" : function () { + var w = document.getElementById("sc1"); + assert.isTrue(w.scrollableNode === w); + }, + + "scrollTop/scrollLeft" : function () { + var w = document.getElementById("sc1"); + w.scrollDirection = "both"; + w.validateRendering(); + assert.equal(w.scrollableNode.scrollTop, 0, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 0, "scrollLeft"); + }, + + "scrollBy" : function () { + var w = document.getElementById("sc1"); + var d = this.async(1000); + w.scrollDirection = "both"; + w.validateRendering(); + w.scrollBy({x: 10}); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 0, "scrollTop"); + w.scrollBy({y: 10}); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop"); + w.scrollBy({x: 10, y: 10}); + assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop"); + + // Now with animation: + w.scrollBy({x: 10, y: 10}, 100/*duration*/); + setTimeout(d.callback(function () { + assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop"); + + w.scrollBy({x: 10, y: 10}, 0/*duration*/); + // when the duration is 0, no animation, thus no need to test asynchronously + assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop"); + }), 1000); + + return d; + }, + + "scrollTo" : function () { + var w = document.getElementById("sc1"); + var d = this.async(1000); + w.scrollDirection = "both"; + w.validateRendering(); + w.scrollTo({x: 10}); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); + w.scrollTo({y: 10}); + assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop"); + w.scrollTo({x: 20, y: 20}); + assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop"); + + // Now with animation: + w.scrollTo({x: 30, y: 30}, 100/*duration*/); + setTimeout(d.callback(function () { + assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop"); + + w.scrollTo({x: 40, y: 40}, 0/*duration*/); + // when the duration is 0, no animation, thus no need to test asynchronously + assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft"); + assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop"); + }), 1000); + + return d; + }, + + "getCurrentScroll" : function () { + var w = document.getElementById("sc1"); + var pos = {x: 10, y: 10}; + w.scrollDirection = "both"; + w.validateRendering(); + w.scrollTo(pos); + assert.deepEqual(w.getCurrentScroll(), pos); + }, + + "isTop/Bottom/Left/RightScroll" : function () { + var w = document.getElementById("sc1"); + var wContent = document.getElementById("sc1content"); + var pos = {x: 10, y: 10}; + var box = domGeom.getMarginBox(wContent); + var width = box.w; + var height = box.h; + w.scrollDirection = "both"; + w.validateRendering(); + w.scrollTo(pos); + assert.isFalse(w.isTopScroll()); + assert.isFalse(w.isBottomScroll()); + assert.isFalse(w.isRightScroll()); + assert.isFalse(w.isLeftScroll()); + + pos = {x: 0, y: 10}; + w.scrollTo(pos); + assert.isFalse(w.isTopScroll()); + assert.isFalse(w.isBottomScroll()); + assert.isFalse(w.isRightScroll()); + assert.isTrue(w.isLeftScroll()); + + pos = {x: 10, y: 0}; + w.scrollTo(pos); + assert.isTrue(w.isTopScroll()); + assert.isFalse(w.isBottomScroll()); + assert.isFalse(w.isRightScroll()); + assert.isFalse(w.isLeftScroll()); + + pos = {x: width, y: 10}; + w.scrollTo(pos); + assert.isFalse(w.isTopScroll()); + assert.isFalse(w.isBottomScroll()); + assert.isTrue(w.isRightScroll()); + assert.isFalse(w.isLeftScroll()); + + pos = {x: 10, y: height}; + w.scrollTo(pos); + assert.isFalse(w.isTopScroll()); + assert.isTrue(w.isBottomScroll()); + assert.isFalse(w.isRightScroll()); + assert.isFalse(w.isLeftScroll()); + + pos = {x: 0, y: 0}; + w.scrollTo(pos); + assert.isTrue(w.isTopScroll()); + assert.isFalse(w.isBottomScroll()); + assert.isFalse(w.isRightScroll()); + assert.isTrue(w.isLeftScroll()); + } + }; +}); diff --git a/tests/Scrollable.js b/tests/Scrollable.js new file mode 100644 index 0000000000..4a75d7d54e --- /dev/null +++ b/tests/Scrollable.js @@ -0,0 +1,48 @@ +define([ + "dcl/dcl", + "intern!object", + "intern/chai!assert", + "dojo/dom-class", + "delite/register", + "delite/Widget", + "delite/Scrollable" +], function (dcl, registerSuite, assert, domClass, register, Widget, Scrollable) { + var container, MyScrollableWidget; + + registerSuite({ + name: "delite/Scrollable", + setup: function () { + container = document.createElement("div"); + document.body.appendChild(container); + MyScrollableWidget = register("my-scrollable-widget", [HTMLElement, Widget, Scrollable], { + buildRendering: dcl.superCall(function (sup) { + return function () { + sup.apply(this, arguments); + }; + }) + }); + }, + "parse" : function () { + register.parse(container); + }, + + "Default CSS" : function () { + var w = (new MyScrollableWidget({id: "mysw"})).placeAt(container); + w.startup(); + w.validateRendering(); + + assert.isTrue(domClass.contains(w.scrollableNode, "d-scrollable")); // via the mixin delite/Scrollable + }, + + // The remaining of the API of the mixin delite/Scrollable is tested + // in tests/ScrollableTestContainer-markup and tests/ScrollableTestContainer-prog + // via an ad-hoc widget (tests/ScrollableTestContainer) which uses the mixin. + + teardown: function () { + var body = document.body; + while (body.firstChild) { + body.removeChild(body.firstChild); + } + } + }); +}); diff --git a/tests/ScrollableTestContainer-markup.js b/tests/ScrollableTestContainer-markup.js new file mode 100644 index 0000000000..f395a3ba42 --- /dev/null +++ b/tests/ScrollableTestContainer-markup.js @@ -0,0 +1,48 @@ +define([ + "dcl/dcl", + "intern!object", + "intern/chai!assert", + "dojo/dom-geometry", + "dojo/dom-class", + "delite/register", + "./ScrollableTestContainer", + "./Scrollable-shared" +], function (dcl, registerSuite, assert, domGeom, domClass, register, + ScrollableTestContainer, ScrollableSharedTests) { + var container; + + /*jshint multistr: true */ + html = " \ +
\ +
\ + \ + \ + \ + "; + + // The test cases are shared with tests/ScrollableTestContainer-prog via + // tests/Scrollable-shared which is dynamically mixed into the + // test suite below. + + var suite = { + name: "delite/Scrollable: ScrollableTestContainer in markup", + setup: function () { + container = document.createElement("div"); + document.body.appendChild(container); + container.innerHTML = html; + register("my-scrolable-test-container", [ScrollableTestContainer], {}); + register.parse(); + }, + teardown: function () { + var body = document.body; + while (body.firstChild) { + body.removeChild(body.firstChild); + } + } + }; + + dcl.mix(suite, ScrollableSharedTests); + + registerSuite(suite); +}); diff --git a/tests/ScrollableTestContainer-prog.js b/tests/ScrollableTestContainer-prog.js new file mode 100644 index 0000000000..ed16333950 --- /dev/null +++ b/tests/ScrollableTestContainer-prog.js @@ -0,0 +1,57 @@ +define([ + "dcl/dcl", + "intern!object", + "intern/chai!assert", + "dojo/dom-geometry", + "dojo/dom-class", + "delite/register", + "./ScrollableTestContainer", + "./Scrollable-shared" +], function (dcl, registerSuite, assert, domGeom, domClass, register, + ScrollableTestContainer, ScrollableSharedTests) { + var container, MyScrollableTestContainer; + + // The test cases are shared with tests/ScrollableTestContainer-markup via + // tests/Scrollable-shared which is dynamically mixed into the + // test suite below. + + var suite = { + name: "delite/Scrollable: ScrollableTestContainer programatically", + setup: function () { + MyScrollableTestContainer = register("my-sc-prog", [ScrollableTestContainer], {}); + + var w = new ScrollableTestContainer({ id: "sc1" }); + w.style.position = "absolute"; + w.style.width = "200px"; + w.style.height = "200px"; + w.startup(); + document.body.appendChild(w); + + var innerContent = document.createElement("div"); + innerContent.id = "sc1content"; + innerContent.style.width = "2000px"; + innerContent.style.height = "2000px"; + w.startup(); + w.appendChild(innerContent); + + w = new MyScrollableTestContainer({ id: "mysc1" }); + w.startup(); + document.body.appendChild(w); + + w = new ScrollableTestContainer({ id: "sc2" }); + w.scrollDirection = "none"; + w.startup(); + document.body.appendChild(w); + }, + teardown: function () { + var body = document.body; + while (body.firstChild) { + body.removeChild(body.firstChild); + } + } + }; + + dcl.mix(suite, ScrollableSharedTests); + + registerSuite(suite); +}); diff --git a/tests/ScrollableTestContainer.js b/tests/ScrollableTestContainer.js new file mode 100644 index 0000000000..7aa0cfc659 --- /dev/null +++ b/tests/ScrollableTestContainer.js @@ -0,0 +1,15 @@ +define([ + "delite/register", + "delite/Widget", + "delite/Container", + "delite/Scrollable" +], function (register, Widget, Container, Scrollable) { + + // The purpose of this module is to provide a concrete widget using + // the mixin delite/Scrollable in order to ease the testing of the mixin itself. + + return register("test-scrollable-container", + [HTMLElement, Widget, Container, Scrollable], { + baseClass: "test-scrollable-container" + }); +}); diff --git a/tests/unit.js b/tests/unit.js index 4e6431cfbb..d295428645 100644 --- a/tests/unit.js +++ b/tests/unit.js @@ -15,5 +15,8 @@ define([ "./Stateful", "./Selection", "./StoreMap", - "./Store" + "./Store", + "./Scrollable", + "./ScrollableTestContainer-markup", + "./ScrollableTestContainer-prog" ]); From ec8757d9cbc6ab59b4a2ed56e06b0ab2c4a5a562 Mon Sep 17 00:00:00 2001 From: Adrian Vasiliu Date: Mon, 13 Jan 2014 17:03:44 +0100 Subject: [PATCH 2/2] Taking into account Bill's comments --- Scrollable.js | 53 +++++---- tests/Scrollable-shared.js | 144 +++++++++++++----------- tests/Scrollable.js | 93 +++++++++++++-- tests/ScrollableTestContainer-markup.js | 48 -------- tests/ScrollableTestContainer-prog.js | 57 ---------- tests/unit.js | 4 +- 6 files changed, 197 insertions(+), 202 deletions(-) delete mode 100644 tests/ScrollableTestContainer-markup.js delete mode 100644 tests/ScrollableTestContainer-prog.js diff --git a/Scrollable.js b/Scrollable.js index 17b3c2d890..a44f0903c3 100644 --- a/Scrollable.js +++ b/Scrollable.js @@ -55,7 +55,7 @@ define([ this.addInvalidatingProperties("scrollDirection"); }, - refreshRendering: function () { + refreshRendering: dcl.after(function () { if (!this.scrollableNode) { this.scrollableNode = this; // If unspecified, defaults to 'this'. } @@ -68,10 +68,14 @@ define([ /^(both|horizontal)$/.test(this.scrollDirection) ? "scroll" : ""); domStyle.set(this.scrollableNode, "overflowY", /^(both|vertical)$/.test(this.scrollDirection) ? "scroll" : ""); - }, + }), - buildRendering: function () { + buildRendering: dcl.after(function () { this.invalidateRendering(); + }), + + destroy: function () { + this._stopAnimation(); }, isTopScroll: function () { @@ -170,9 +174,11 @@ define([ // duration: // Duration of scrolling animation in milliseconds. If 0 or unspecified, // scrolls without animation. - var self = this; var scrollableNode = this.scrollableNode; + var from; + var animation, anim, Curve; + this._stopAnimation(); if (!duration || duration <= 0) { // shortcut if (to.x !== undefined) { scrollableNode.scrollLeft = to.x; @@ -181,28 +187,30 @@ define([ scrollableNode.scrollTop = to.y; } } else { - var from = { + from = { x: to.x !== undefined ? scrollableNode.scrollLeft : undefined, y: to.y !== undefined ? scrollableNode.scrollTop : undefined }; - var animation = function () { - if (self._animation && self._animation.status() === "playing") { - self._animation.stop(); - } + anim = function () { // dojo/_base/fx._Line cannot be used for animating several - // properties at once. Hence: - baseFx._Line.prototype.getValue = function (/*float*/ n) { + // properties at once (scrollTop and scrollLeft in our case). + // Hence, using instead a custom function: + Curve = function (/*int*/ start, /*int*/ end){ + this.start = start; + this.end = end; + }; + Curve.prototype.getValue = function (/*float*/ n){ return { - x: ((this.end.x - this.start.x) * n) + this.start.x, - y: ((this.end.y - this.start.y) * n) + this.start.y + x: ((to.x - from.x) * n) + from.x, + y: ((to.y - from.y) * n) + from.y }; }; - var anim = new baseFx.Animation({ + animation = new baseFx.Animation({ beforeBegin: function () { if (this.curve) { delete this.curve; } - anim.curve = new baseFx._Line(from, to); + animation.curve = new Curve(from, to); }, onAnimate: function (val) { if (val.x !== undefined) { @@ -216,12 +224,19 @@ define([ duration: duration, rate: 20 // TODO: IMPROVEME }); - self._animation = anim; - - return anim; // dojo/_base/fx/Animation + self._animation = animation; + return animation; // dojo/_base/fx/Animation }; - animation().play(); + anim().play(); } + }, + + _stopAnimation: function () { + // summary: + // Stops the scrolling animation if it is currently playing. + if (this._animation && this._animation.status() === "playing") { + this._animation.stop(); + } } }); }); diff --git a/tests/Scrollable-shared.js b/tests/Scrollable-shared.js index d96e9878ed..0c3c78b0ff 100644 --- a/tests/Scrollable-shared.js +++ b/tests/Scrollable-shared.js @@ -10,56 +10,74 @@ define([ return { "Default CSS" : function () { var w = document.getElementById("sc1"); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (id='sc1')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (id='sc1')"); w = document.getElementById("sc2"); // with scrollDirection == "none" - assert.equal(w.scrollDirection, "none", "wrong scroll direction for sc2!"); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.equal(w.scrollDirection, "none", "wrong scroll direction for id=sc2!"); + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (id='sc2')"); // when scrollDirection is "none", this CSS class should NOT be present: - assert.isFalse(domClass.contains(w, "d-scrollable")); + assert.isFalse(domClass.contains(w, "d-scrollable"), + "Not expecting d-scrollable CSS class! (id='sc2')"); w = document.getElementById("mysc1"); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (id='mysc1')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (id='mysc1')"); }, "CSS class dependency on scrollDirection" : function () { var w = document.getElementById("sc1"); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (id='sc1')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (id='sc1')"); w.scrollDirection = "none"; w.validateRendering(); // scrollDirection is an invalidating property - assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (scrollDirection='none')"); // when scrollDirection is "none", this CSS class should NOT be present: - assert.isFalse(domClass.contains(w, "d-scrollable")); + assert.isFalse(domClass.contains(w, "d-scrollable"), + "Not expecting d-scrollable CSS class! (scrollDirection='none')"); w.scrollDirection = "vertical"; // set back to "vertical" w.validateRendering(); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (scrollDirection='vertical')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (scrollDirection='vertical')"); w.scrollDirection = "horizontal"; // same for "horizontal" w.validateRendering(); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (scrollDirection='horizontal')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (scrollDirection='horizontal')"); w.scrollDirection = "both"; // same for "both" w.validateRendering(); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); - assert.isTrue(domClass.contains(w, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (scrollDirection='both')"); + assert.isTrue(domClass.contains(w, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class! (scrollDirection='both')"); w.scrollDirection = "none"; // and none again w.validateRendering(); - assert.isTrue(domClass.contains(w, "test-scrollable-container")); + assert.isTrue(domClass.contains(w, "test-scrollable-container"), + "Expecting test-scrollable-container CSS class! (scrollDirection='none')"); // when scrollDirection is "none", this CSS class should NOT be present: - assert.isFalse(domClass.contains(w, "d-scrollable")); + assert.isFalse(domClass.contains(w, "d-scrollable"), + "Not expecting d-scrollable CSS class! (scrollDirection='none')"); }, "scrollableNode" : function () { var w = document.getElementById("sc1"); - assert.isTrue(w.scrollableNode === w); + assert.isTrue(w.scrollableNode === w, "Wrong scrollableNode!"); }, "scrollTop/scrollLeft" : function () { @@ -76,25 +94,25 @@ define([ w.scrollDirection = "both"; w.validateRendering(); w.scrollBy({x: 10}); - assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 0, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft #1"); + assert.equal(w.scrollableNode.scrollTop, 0, "scrollTop #1"); w.scrollBy({y: 10}); - assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft #2"); + assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop #2"); w.scrollBy({x: 10, y: 10}); - assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft #3"); + assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop #3"); // Now with animation: w.scrollBy({x: 10, y: 10}, 100/*duration*/); setTimeout(d.callback(function () { - assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft #4"); + assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop #4"); w.scrollBy({x: 10, y: 10}, 0/*duration*/); // when the duration is 0, no animation, thus no need to test asynchronously - assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft #5"); + assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop #5"); }), 1000); return d; @@ -106,23 +124,23 @@ define([ w.scrollDirection = "both"; w.validateRendering(); w.scrollTo({x: 10}); - assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft"); + assert.equal(w.scrollableNode.scrollLeft, 10, "scrollLeft #1"); w.scrollTo({y: 10}); - assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop"); + assert.equal(w.scrollableNode.scrollTop, 10, "scrollTop #1"); w.scrollTo({x: 20, y: 20}); - assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 20, "scrollLeft #2"); + assert.equal(w.scrollableNode.scrollTop, 20, "scrollTop #2"); // Now with animation: w.scrollTo({x: 30, y: 30}, 100/*duration*/); setTimeout(d.callback(function () { - assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 30, "scrollLeft #3"); + assert.equal(w.scrollableNode.scrollTop, 30, "scrollTop #3"); w.scrollTo({x: 40, y: 40}, 0/*duration*/); // when the duration is 0, no animation, thus no need to test asynchronously - assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft"); - assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop"); + assert.equal(w.scrollableNode.scrollLeft, 40, "scrollLeft #4"); + assert.equal(w.scrollableNode.scrollTop, 40, "scrollTop #4"); }), 1000); return d; @@ -134,7 +152,7 @@ define([ w.scrollDirection = "both"; w.validateRendering(); w.scrollTo(pos); - assert.deepEqual(w.getCurrentScroll(), pos); + assert.deepEqual(w.getCurrentScroll(), pos, "Wrong getCurrentScroll!"); }, "isTop/Bottom/Left/RightScroll" : function () { @@ -147,45 +165,45 @@ define([ w.scrollDirection = "both"; w.validateRendering(); w.scrollTo(pos); - assert.isFalse(w.isTopScroll()); - assert.isFalse(w.isBottomScroll()); - assert.isFalse(w.isRightScroll()); - assert.isFalse(w.isLeftScroll()); + assert.isFalse(w.isTopScroll(), "isTopScroll() #1"); + assert.isFalse(w.isBottomScroll(), "isBottomScroll() #1"); + assert.isFalse(w.isRightScroll(), "isRightScroll() #1"); + assert.isFalse(w.isLeftScroll(), "isLeftScroll() #1"); pos = {x: 0, y: 10}; w.scrollTo(pos); - assert.isFalse(w.isTopScroll()); - assert.isFalse(w.isBottomScroll()); - assert.isFalse(w.isRightScroll()); - assert.isTrue(w.isLeftScroll()); + assert.isFalse(w.isTopScroll(), "isTopScroll() #2"); + assert.isFalse(w.isBottomScroll(), "isBottomScroll() #2"); + assert.isFalse(w.isRightScroll(), "isRightScroll() #2"); + assert.isTrue(w.isLeftScroll(), "isLeftScroll() #2"); pos = {x: 10, y: 0}; w.scrollTo(pos); - assert.isTrue(w.isTopScroll()); - assert.isFalse(w.isBottomScroll()); - assert.isFalse(w.isRightScroll()); - assert.isFalse(w.isLeftScroll()); + assert.isTrue(w.isTopScroll(), "isTopScroll() #3"); + assert.isFalse(w.isBottomScroll(), "isBottomScroll() #3"); + assert.isFalse(w.isRightScroll(), "isRightScroll() #3"); + assert.isFalse(w.isLeftScroll(), "isLeftScroll() #3"); pos = {x: width, y: 10}; w.scrollTo(pos); - assert.isFalse(w.isTopScroll()); - assert.isFalse(w.isBottomScroll()); - assert.isTrue(w.isRightScroll()); - assert.isFalse(w.isLeftScroll()); + assert.isFalse(w.isTopScroll(), "isTopScroll() #4"); + assert.isFalse(w.isBottomScroll(), "isBottomScroll() #4"); + assert.isTrue(w.isRightScroll(), "isRightScroll() #4"); + assert.isFalse(w.isLeftScroll(), "isLeftScroll() #4"); pos = {x: 10, y: height}; w.scrollTo(pos); - assert.isFalse(w.isTopScroll()); - assert.isTrue(w.isBottomScroll()); - assert.isFalse(w.isRightScroll()); - assert.isFalse(w.isLeftScroll()); + assert.isFalse(w.isTopScroll(), "isTopScroll() #5"); + assert.isTrue(w.isBottomScroll(), "isBottomScroll() #5"); + assert.isFalse(w.isRightScroll(), "isRightScroll() #5"); + assert.isFalse(w.isLeftScroll(), "isLeftScroll() #5"); pos = {x: 0, y: 0}; w.scrollTo(pos); - assert.isTrue(w.isTopScroll()); - assert.isFalse(w.isBottomScroll()); - assert.isFalse(w.isRightScroll()); - assert.isTrue(w.isLeftScroll()); + assert.isTrue(w.isTopScroll(), "isTopScroll() #6"); + assert.isFalse(w.isBottomScroll(), "isBottomScroll() #6"); + assert.isFalse(w.isRightScroll(), "isRightScroll() #6"); + assert.isTrue(w.isLeftScroll(), "isLeftScroll() #6"); } }; }); diff --git a/tests/Scrollable.js b/tests/Scrollable.js index 4a75d7d54e..6a1e97c145 100644 --- a/tests/Scrollable.js +++ b/tests/Scrollable.js @@ -5,9 +5,22 @@ define([ "dojo/dom-class", "delite/register", "delite/Widget", - "delite/Scrollable" -], function (dcl, registerSuite, assert, domClass, register, Widget, Scrollable) { - var container, MyScrollableWidget; + "delite/Scrollable", + "./ScrollableTestContainer", + "./Scrollable-shared" +], function (dcl, registerSuite, assert, domClass, register, Widget, + Scrollable, ScrollableTestContainer, ScrollableSharedTests) { + + var container, MyScrollableWidget, MyScrollableTestContainer; + /*jshint multistr: true */ + var html = " \ +
\ +
\ + \ + \ + \ + "; registerSuite({ name: "delite/Scrollable", @@ -22,16 +35,13 @@ define([ }) }); }, - "parse" : function () { - register.parse(container); - }, "Default CSS" : function () { var w = (new MyScrollableWidget({id: "mysw"})).placeAt(container); w.startup(); w.validateRendering(); - - assert.isTrue(domClass.contains(w.scrollableNode, "d-scrollable")); // via the mixin delite/Scrollable + assert.isTrue(domClass.contains(w.scrollableNode, "d-scrollable"), // class added by the mixin delite/Scrollable + "Expecting d-scrollable CSS class!"); }, // The remaining of the API of the mixin delite/Scrollable is tested @@ -39,10 +49,69 @@ define([ // via an ad-hoc widget (tests/ScrollableTestContainer) which uses the mixin. teardown: function () { - var body = document.body; - while (body.firstChild) { - body.removeChild(body.firstChild); - } + container.parentNode.removeChild(container); } }); + + // Markup use-case + + var suite = { + name: "delite/Scrollable: ScrollableTestContainer in markup", + setup: function () { + container = document.createElement("div"); + document.body.appendChild(container); + container.innerHTML = html; + register("my-scrolable-test-container", [ScrollableTestContainer], {}); + register.parse(); + }, + teardown: function () { + container.parentNode.removeChild(container); + } + }; + + dcl.mix(suite, ScrollableSharedTests); + + registerSuite(suite); + + // Programatic creation + + suite = { + name: "delite/Scrollable: ScrollableTestContainer programatically", + setup: function () { + container = document.createElement("div"); + document.body.appendChild(container); + + MyScrollableTestContainer = register("my-sc-prog", [ScrollableTestContainer], {}); + + var w = new ScrollableTestContainer({ id: "sc1" }); + w.style.position = "absolute"; + w.style.width = "200px"; + w.style.height = "200px"; + container.appendChild(w); + w.startup(); + + var innerContent = document.createElement("div"); + innerContent.id = "sc1content"; + innerContent.style.width = "2000px"; + innerContent.style.height = "2000px"; + w.appendChild(innerContent); + w.startup(); + + w = new MyScrollableTestContainer({ id: "mysc1" }); + container.appendChild(w); + w.startup(); + + w = new ScrollableTestContainer({ id: "sc2" }); + w.scrollDirection = "none"; + container.appendChild(w); + w.startup(); + }, + teardown: function () { + container.parentNode.removeChild(container); + } + }; + + dcl.mix(suite, ScrollableSharedTests); + + registerSuite(suite); }); diff --git a/tests/ScrollableTestContainer-markup.js b/tests/ScrollableTestContainer-markup.js deleted file mode 100644 index f395a3ba42..0000000000 --- a/tests/ScrollableTestContainer-markup.js +++ /dev/null @@ -1,48 +0,0 @@ -define([ - "dcl/dcl", - "intern!object", - "intern/chai!assert", - "dojo/dom-geometry", - "dojo/dom-class", - "delite/register", - "./ScrollableTestContainer", - "./Scrollable-shared" -], function (dcl, registerSuite, assert, domGeom, domClass, register, - ScrollableTestContainer, ScrollableSharedTests) { - var container; - - /*jshint multistr: true */ - html = " \ -
\ -
\ - \ - \ - \ - "; - - // The test cases are shared with tests/ScrollableTestContainer-prog via - // tests/Scrollable-shared which is dynamically mixed into the - // test suite below. - - var suite = { - name: "delite/Scrollable: ScrollableTestContainer in markup", - setup: function () { - container = document.createElement("div"); - document.body.appendChild(container); - container.innerHTML = html; - register("my-scrolable-test-container", [ScrollableTestContainer], {}); - register.parse(); - }, - teardown: function () { - var body = document.body; - while (body.firstChild) { - body.removeChild(body.firstChild); - } - } - }; - - dcl.mix(suite, ScrollableSharedTests); - - registerSuite(suite); -}); diff --git a/tests/ScrollableTestContainer-prog.js b/tests/ScrollableTestContainer-prog.js deleted file mode 100644 index ed16333950..0000000000 --- a/tests/ScrollableTestContainer-prog.js +++ /dev/null @@ -1,57 +0,0 @@ -define([ - "dcl/dcl", - "intern!object", - "intern/chai!assert", - "dojo/dom-geometry", - "dojo/dom-class", - "delite/register", - "./ScrollableTestContainer", - "./Scrollable-shared" -], function (dcl, registerSuite, assert, domGeom, domClass, register, - ScrollableTestContainer, ScrollableSharedTests) { - var container, MyScrollableTestContainer; - - // The test cases are shared with tests/ScrollableTestContainer-markup via - // tests/Scrollable-shared which is dynamically mixed into the - // test suite below. - - var suite = { - name: "delite/Scrollable: ScrollableTestContainer programatically", - setup: function () { - MyScrollableTestContainer = register("my-sc-prog", [ScrollableTestContainer], {}); - - var w = new ScrollableTestContainer({ id: "sc1" }); - w.style.position = "absolute"; - w.style.width = "200px"; - w.style.height = "200px"; - w.startup(); - document.body.appendChild(w); - - var innerContent = document.createElement("div"); - innerContent.id = "sc1content"; - innerContent.style.width = "2000px"; - innerContent.style.height = "2000px"; - w.startup(); - w.appendChild(innerContent); - - w = new MyScrollableTestContainer({ id: "mysc1" }); - w.startup(); - document.body.appendChild(w); - - w = new ScrollableTestContainer({ id: "sc2" }); - w.scrollDirection = "none"; - w.startup(); - document.body.appendChild(w); - }, - teardown: function () { - var body = document.body; - while (body.firstChild) { - body.removeChild(body.firstChild); - } - } - }; - - dcl.mix(suite, ScrollableSharedTests); - - registerSuite(suite); -}); diff --git a/tests/unit.js b/tests/unit.js index d295428645..3a5cae690c 100644 --- a/tests/unit.js +++ b/tests/unit.js @@ -16,7 +16,5 @@ define([ "./Selection", "./StoreMap", "./Store", - "./Scrollable", - "./ScrollableTestContainer-markup", - "./ScrollableTestContainer-prog" + "./Scrollable" ]);