From c241b6ce3590e56c3964dbab0be332c039d3a5a6 Mon Sep 17 00:00:00 2001 From: Phil Cockfield Date: Tue, 20 Dec 2011 21:41:32 -0800 Subject: [PATCH] Scroll controller --- .../controls/controllers/index.coffee | 7 +- .../controls/controllers/scroll.coffee | 37 +++++++++ .../modules/harness.tabs/views/base.coffee | 9 +-- .../controls/controllers/scroll_spec.coffee | 76 +++++++++++++++++++ test/specs/client/core/util/util_spec.coffee | 3 - 5 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 lib/src/open.client/controls/controllers/scroll.coffee create mode 100644 test/specs/client/controls/controllers/scroll_spec.coffee diff --git a/lib/src/open.client/controls/controllers/index.coffee b/lib/src/open.client/controls/controllers/index.coffee index 1b3e7d1..44172eb 100644 --- a/lib/src/open.client/controls/controllers/index.coffee +++ b/lib/src/open.client/controls/controllers/index.coffee @@ -1,4 +1,5 @@ module.exports = - Focus: require './focus' - Popup: require './popup' - Size: require './size' \ No newline at end of file + Focus: require './focus' + Popup: require './popup' + Scroll: require './scroll' + Size: require './size' \ No newline at end of file diff --git a/lib/src/open.client/controls/controllers/scroll.coffee b/lib/src/open.client/controls/controllers/scroll.coffee new file mode 100644 index 0000000..e80802c --- /dev/null +++ b/lib/src/open.client/controls/controllers/scroll.coffee @@ -0,0 +1,37 @@ +core = require 'open.client/core' + + +### +Extends a view to make it scrollable. +### +module.exports = class ScrollController + constructor: (view) -> + + # Add the scroll property. + unless view.scroll?.onChanged? + view.addProps + scroll: null # Gets or sets the scroll behavior of the content (values: null, 'x', 'y' or 'xy'). + + # Sycers. + sync = -> core.util.syncScroll view.el, view.scroll() + + # Wire up events. + # - Handler: Validate property. + view.scroll.onChanging (e) -> + value = e.newValue + value = value?.toLowerCase() + throw "'#{value}' not valid scroll value (x,y or xy)" if not isValid value + e.newValue = value + + # - Handler: Sync state on scroll changed. + view.scroll.onChanged sync + + # Finish up. + sync() + + +# PRIVATE -------------------------------------------------------------------------- + + +isValid = (value) -> return true if value is valid for valid in ['x', 'y', 'xy'] + diff --git a/lib/src/open.client/modules/harness.tabs/views/base.coffee b/lib/src/open.client/modules/harness.tabs/views/base.coffee index 87ed6a2..1d29b8d 100644 --- a/lib/src/open.client/modules/harness.tabs/views/base.coffee +++ b/lib/src/open.client/modules/harness.tabs/views/base.coffee @@ -7,14 +7,9 @@ module.exports = (module) -> # Setup initial conditions. super _.extend props, className:'th_tab' - # Syncers. - syncScroll = => module.core.util.syncScroll @el, @scroll() + # Enabled scrolling. + new module.controls.controllers.Scroll @ - # Wire up events. - @scroll.onChanged syncScroll - - # Finish up. - syncScroll() ### diff --git a/test/specs/client/controls/controllers/scroll_spec.coffee b/test/specs/client/controls/controllers/scroll_spec.coffee new file mode 100644 index 0000000..4a2877c --- /dev/null +++ b/test/specs/client/controls/controllers/scroll_spec.coffee @@ -0,0 +1,76 @@ +describe 'controls/controllers/scroll', -> + View = null + Scroll = null + + class MyView extends core.mvc.View + defaults: + scroll: 'y' + + class MyScrollView extends MyView + constructor: (props = {}) -> + super + new Scroll @ + + + + beforeEach -> + View = core.mvc.View + Scroll = controls.controllers.Scroll + + it 'exists', -> + expect(Scroll).toBeDefined() + + it 'adds a [scroll] property function to a view', -> + view = new View() + expect(view.scroll).not.toBeDefined() + new Scroll(view) + expect(view.scroll.onChanged instanceof Function).toEqual true + + it 'keeps a pre-defined [scroll] property', -> + view = new MyView() + new Scroll view + expect(view.scroll()).toEqual 'y' + + + it 'converts property to lower case', -> + view = new MyScrollView() + view.scroll 'XY' + expect(view.scroll()).toEqual 'xy' + + it 'throws if a non valid valid is passed', -> + view = new MyScrollView() + view.scroll 'z' + + + describe 'delegate to syncScroll() method', -> + callArgs = -> core.util.syncScroll.mostRecentCall.args + beforeEach -> + + it 'syncs scroll on construction', -> + spyOn(core.util, 'syncScroll') + view = new MyScrollView() + args = callArgs() + + expect(core.util.syncScroll.callCount).toEqual 1 + expect(args[0]).toEqual view.el + expect(args[1]).toEqual 'y' + + it 'syncs on property changed', -> + view = new MyScrollView() + + spyOn(core.util, 'syncScroll') + view.scroll 'x' + args = callArgs() + + expect(core.util.syncScroll.callCount).toEqual 1 + expect(args[0]).toEqual view.el + expect(args[1]).toEqual 'x' + + + + + + + + + \ No newline at end of file diff --git a/test/specs/client/core/util/util_spec.coffee b/test/specs/client/core/util/util_spec.coffee index df10e78..2f4aa60 100644 --- a/test/specs/client/core/util/util_spec.coffee +++ b/test/specs/client/core/util/util_spec.coffee @@ -111,9 +111,6 @@ describe 'util', -> it 'does not set the target for [mailto:] links', -> expect(a8.attr('target')).toEqual null - - - describe 'scrollClasses', -> div = null