Merge lp:~jcsackett/juju-gui/charm-slider into lp:juju-gui/experimental

Proposed by j.c.sackett
Status: Merged
Merged at revision: 420
Proposed branch: lp:~jcsackett/juju-gui/charm-slider
Merge into: lp:juju-gui/experimental
Diff against target: 512 lines (+447/-2)
8 files modified
app/modules-debug.js (+4/-0)
app/templates/charm-small-widget.handlebars (+1/-1)
app/widgets/charm-slider.js (+329/-0)
app/widgets/charm-small.js (+1/-1)
lib/views/browser/charm-slider.less (+29/-0)
lib/views/stylesheet.less (+1/-0)
test/index.html (+1/-0)
test/test_charm_slider.js (+81/-0)
To merge this branch: bzr merge lp:~jcsackett/juju-gui/charm-slider
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+152418@code.launchpad.net

Description of the change

Adds the charm slider widget

This adds a slider widget derived from Jeff Pihach's flickr carousel. It
doesn't wire it into anything yet.

https://codereview.appspot.com/7641043/

To post a comment you must log in.
Revision history for this message
j.c.sackett (jcsackett) wrote :

Reviewers: mp+152418_code.launchpad.net,

Message:
Please take a look.

Description:
Adds the charm slider widget

This adds a slider widget derived from Jeff Pihach's flickr carousel. It
doesn't wire it into anything yet.

https://code.launchpad.net/~jcsackett/juju-gui/charm-slider/+merge/152418

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/7641043/

Affected files:
   A [revision details]
   M app/modules-debug.js
   M app/templates/charm-small-widget.handlebars
   A app/widgets/charm-slider.js
   M app/widgets/charm-small.js
   A lib/views/browser/charm-slider.less
   M lib/views/stylesheet.less
   M test/index.html
   A test/test_charm_slider.js

Revision history for this message
Richard Harding (rharding) wrote :
Download full text (4.7 KiB)

Some light weight changes. Many have a lot of occurances so didn't mark
each one for the first pass, but {Object} vs { Object } and String vs
string.

Some other suggestions and additional tests requested.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js
File app/widgets/charm-slider.js (right):

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode7
app/widgets/charm-slider.js:7: * @namespace juju.widgets.browser
namespace juju; modules widgets; submodule browser.notifier I think is
how it works.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode12
app/widgets/charm-slider.js:12: var sub = Y.Lang.sub;
comma here and combine with next var

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode21
app/widgets/charm-slider.js:21: *
In the doc string can you put a sample of min. html needed to use the
widget? Want to include enough to reuse without too much hunting.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode29
app/widgets/charm-slider.js:29: * @type { string }
Caps String for a class name. No spaces inside the {}.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode66
app/widgets/charm-slider.js:66:
extra space here

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode82
app/widgets/charm-slider.js:82:
extra space here (my snippets fault I know...)

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode83
app/widgets/charm-slider.js:83: _generateDOM: function() {
please move private methods to the top of the class functions.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode90
app/widgets/charm-slider.js:90: sub(that.itemTemplate, {width:
that.get('width'), index: index}));
you get width twice. Please just get the var and cache it to avoid
lookups that aren't required.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode115
app/widgets/charm-slider.js:115: * Advances the slider to the next item,
or a designated index
end comment with .

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode128
app/widgets/charm-slider.js:128: index = parseInt(index, 10);
why does index need to be parsed? How is it coming in as a string?

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode184
app/widgets/charm-slider.js:184: this.set('pauseOnHover', true);
can we rename this to pause(d)OnHover. It matches up better since it's a
completed state. Maybe even just move to paused. Who cares if we're
paused for hover or some manual control.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode200
app/widgets/charm-slider.js:200:
Y.juju.widgets.browser.CharmSlider.superclass.bindUI.apply(this);
to prevent the nested lookup use ns. please.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode244
app/widgets/charm-slider.js:244: * @default 500
since this is a little slider let's default to something closer to what
we would use like 150 or 200px.

https://coderevie...

Read more...

lp:~jcsackett/juju-gui/charm-slider updated
431. By j.c.sackett

Addressed comments from review.

Revision history for this message
j.c.sackett (jcsackett) wrote :

Agree with most comments, address the remainder. Code is coming up
shortly.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js
File app/widgets/charm-slider.js (right):

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode21
app/widgets/charm-slider.js:21: *
On 2013/03/08 15:12:02, rharding wrote:
> In the doc string can you put a sample of min. html needed to use the
widget?
> Want to include enough to reuse without too much hunting.

Per discussion, this doesn't actual require any setup; just pass in
parentNode to render, as with default Y.Widget.

https://codereview.appspot.com/7641043/diff/1/app/widgets/charm-slider.js#newcode128
app/widgets/charm-slider.js:128: index = parseInt(index, 10);
On 2013/03/08 15:12:02, rharding wrote:
> why does index need to be parsed? How is it coming in as a string?

We get index out of a data-* attribute on the element, but I have moved
the parseInt to where we fetch it, so it's an int when it hits this
method.

https://codereview.appspot.com/7641043/

Revision history for this message
j.c.sackett (jcsackett) wrote :
Revision history for this message
Jeff Pihach (hatch) wrote :

Thanks for the code! See my comments (as we discussed) below.

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js
File app/widgets/charm-slider.js (right):

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode72
app/widgets/charm-slider.js:72: if (Y.Lang.isValue(index)) {
We decided to no longer use isValue() as all it's really doing is a
glorified falsy check

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode102
app/widgets/charm-slider.js:102: sub(that.itemTemplate, {width: width,
index: index}));
There is no need to do the that=this trick here because (like most
methods of this type in yui) it has a final param which is the context.

http://yuilibrary.com/yui/docs/api/classes/Array.html#method_map

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode103
app/widgets/charm-slider.js:103: tmpNode.setContent(item);
setContent() is depricated use setHTML()

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode116
app/widgets/charm-slider.js:116: Y.log('_generateSliderControls',
'info', this.name);
I think we have standardized on using console.log()

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode119
app/widgets/charm-slider.js:119: Y.Array.each(this.get('items'),
function(item, index) {
Like I mentioned above, YUI's iterators have a context param as the
final param so the that=this can be removed in favour of that.

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode195
app/widgets/charm-slider.js:195: var index =
this.getAttribute('data-index');
event callbacks are passed an event object which hold reference to the
target.

so this can be changed to e.currentTarget.getAttribute('data-index');

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode198
app/widgets/charm-slider.js:198: }, 'li'));
delegate() also has a context property

https://codereview.appspot.com/7641043/diff/8001/lib/views/browser/charm-slider.less
File lib/views/browser/charm-slider.less (right):

https://codereview.appspot.com/7641043/diff/8001/lib/views/browser/charm-slider.less#newcode1
lib/views/browser/charm-slider.less:1:
.yui3-browser-charm-slider-content {
Because we are using less you can actually nest most of the rules in
this commit - let me know if you need help doing this.

https://codereview.appspot.com/7641043/

lp:~jcsackett/juju-gui/charm-slider updated
432. By j.c.sackett

Changes from hatch's review

Revision history for this message
j.c.sackett (jcsackett) wrote :

On 2013/03/08 19:23:49, jeff.pihach wrote:
> Thanks for the code! See my comments (as we discussed) below.

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js
> File app/widgets/charm-slider.js (right):

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode72
> app/widgets/charm-slider.js:72: if (Y.Lang.isValue(index)) {
> We decided to no longer use isValue() as all it's really doing is a
glorified
> falsy check

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode102
> app/widgets/charm-slider.js:102: sub(that.itemTemplate, {width: width,
index:
> index}));
> There is no need to do the that=this trick here because (like most
methods of
> this type in yui) it has a final param which is the context.

> http://yuilibrary.com/yui/docs/api/classes/Array.html#method_map

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode103
> app/widgets/charm-slider.js:103: tmpNode.setContent(item);
> setContent() is depricated use setHTML()

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode116
> app/widgets/charm-slider.js:116: Y.log('_generateSliderControls',
'info',
> this.name);
> I think we have standardized on using console.log()

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode119
> app/widgets/charm-slider.js:119: Y.Array.each(this.get('items'),
function(item,
> index) {
> Like I mentioned above, YUI's iterators have a context param as the
final param
> so the that=this can be removed in favour of that.

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode195
> app/widgets/charm-slider.js:195: var index =
this.getAttribute('data-index');
> event callbacks are passed an event object which hold reference to the
target.

> so this can be changed to e.currentTarget.getAttribute('data-index');

https://codereview.appspot.com/7641043/diff/8001/app/widgets/charm-slider.js#newcode198
> app/widgets/charm-slider.js:198: }, 'li'));
> delegate() also has a context property

https://codereview.appspot.com/7641043/diff/8001/lib/views/browser/charm-slider.less
> File lib/views/browser/charm-slider.less (right):

https://codereview.appspot.com/7641043/diff/8001/lib/views/browser/charm-slider.less#newcode1
> lib/views/browser/charm-slider.less:1:
.yui3-browser-charm-slider-content {
> Because we are using less you can actually nest most of the rules in
this commit
> - let me know if you need help doing this.

I've address your points, code coming shortly.

https://codereview.appspot.com/7641043/

Revision history for this message
j.c.sackett (jcsackett) wrote :
Revision history for this message
Jeff Pihach (hatch) wrote :
Revision history for this message
Richard Harding (rharding) wrote :

On 2013/03/08 20:17:48, jeff.pihach wrote:
> LGTM

lgtm as well

https://codereview.appspot.com/7641043/

Revision history for this message
j.c.sackett (jcsackett) wrote :

*** Submitted:

Adds the charm slider widget

This adds a slider widget derived from Jeff Pihach's flickr carousel. It
doesn't wire it into anything yet.

R=rharding, jeff.pihach
CC=
https://codereview.appspot.com/7641043

https://codereview.appspot.com/7641043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/modules-debug.js'
2--- app/modules-debug.js 2013-03-06 16:17:11 +0000
3+++ app/modules-debug.js 2013-03-08 19:44:21 +0000
4@@ -52,6 +52,10 @@
5 fullpath: '/juju-ui/widgets/charm-small.js'
6 },
7
8+ 'browser-charm-slider': {
9+ fullpath: '/juju-ui/widgets/charm-slider.js'
10+ },
11+
12 'reconnecting-websocket': {
13 fullpath: '/juju-ui/assets/javascripts/reconnecting-websocket.js'
14 },
15
16=== modified file 'app/templates/charm-small-widget.handlebars'
17--- app/templates/charm-small-widget.handlebars 2013-03-01 20:58:58 +0000
18+++ app/templates/charm-small-widget.handlebars 2013-03-08 19:44:21 +0000
19@@ -1,4 +1,4 @@
20-<div >
21+<div>
22 <img url="{{ iconfile }}" />
23 <h3 class="title">{{ title }}</h3>
24 <p class="description">{{ description }}</p>
25
26=== added file 'app/widgets/charm-slider.js'
27--- app/widgets/charm-slider.js 1970-01-01 00:00:00 +0000
28+++ app/widgets/charm-slider.js 2013-03-08 19:44:21 +0000
29@@ -0,0 +1,329 @@
30+'use strict';
31+
32+
33+/**
34+ * Provides the Charm Slider widget.
35+ *
36+ * @namespace juju
37+ * @module widgets
38+ * @submodule browser.CharmSlider
39+ *
40+ */
41+YUI.add('browser-charm-slider', function(Y) {
42+ var sub = Y.Lang.sub,
43+ ns = Y.namespace('juju.widgets.browser');
44+
45+ /**
46+ * The CharmSlider provides a rotating display of one member of a generic set
47+ * of items, with controls to go directly to a given item.
48+ *
49+ * @class CharmSlider
50+ * @extends {Y.ScrollView}
51+ *
52+ */
53+ ns.CharmSlider = new Y.Base.create('browser-charm-slider', Y.ScrollView, [], {
54+
55+ /**
56+ * Template for the CharmSlider
57+ *
58+ * @property charmSliderTemplate
59+ * @type {String}
60+ *
61+ */
62+ charmSliderTemplate: '<ul width="{width}px" />',
63+
64+ /**
65+ * Template for a given item in the slider
66+ *
67+ * @property itemTemplate
68+ * @type {String}
69+ *
70+ */
71+ itemTemplate: '<li width="{width}px" data-index="{index}" />',
72+
73+ /**
74+ * Template used for the navigation controls.
75+ *
76+ * @property prevNavTemplate
77+ * @type {String}
78+ */
79+ navTemplate: '<ul class="navigation"></div>',
80+
81+ /**
82+ * Template used for items in the navigation.
83+ *
84+ * @property navItemTemplate
85+ * @type {String}
86+ */
87+ navItemTemplate: '<li data-index="{index}">O</li>',
88+
89+ /**
90+ * Advances the slider to the next item, or a designated index.
91+ *
92+ * @method _advanceSlide
93+ * @param {string} Index to move to; if not supplied, advances to next
94+ * slide.
95+ * @private
96+ */
97+ _advanceSlide: function(index) {
98+ var pages = this.pages;
99+ if (index) {
100+ this._stopTimer();
101+ pages.scrollToIndex(index);
102+ this._startTimer();
103+ } else {
104+ index = pages.get('index');
105+ if (index < pages.get('total') - 1) {
106+ pages.next();
107+ } else {
108+ pages.scrollToIndex(0);
109+ }
110+ }
111+ },
112+
113+ /**
114+ * Creates the structure and DOM nodes for the slider.
115+ *
116+ * @method _generateDOM
117+ * @private
118+ * @return {Node} The slider's DOM nodes.
119+ *
120+ */
121+ _generateDOM: function() {
122+ var width = this.get('width'),
123+ slider = Y.Node.create(
124+ sub(this.charmSliderTemplate, {width: width}));
125+
126+ Y.Array.map(this.get('items'), function(item, index) {
127+ var tmpNode = Y.Node.create(
128+ sub(this.itemTemplate, {width: width, index: index}));
129+ tmpNode.setHTML(item);
130+ slider.append(tmpNode);
131+ }, this);
132+ return slider;
133+ },
134+
135+ /**
136+ * Generates and appends the navigation controls for the slider
137+ *
138+ * @method _generateSliderControls
139+ * @private
140+ */
141+ _generateSliderControls: function() {
142+ var nav = Y.Node.create(this.navTemplate);
143+ Y.Array.each(this.get('items'), function(item, index) {
144+ nav.append(Y.Node.create(sub(
145+ this.navItemTemplate, {index: index})));
146+ }, this);
147+ this.get('boundingBox').append(nav);
148+ },
149+
150+ /**
151+ * Mouseenter/mouseleave event handler
152+ *
153+ * @method _pauseAutoAdvance
154+ * @private
155+ * @param {object} mouseout or mouseover event object.
156+ */
157+ _pauseAutoAdvance: function(e) {
158+ if (e.type === 'mouseenter') {
159+ this.set('paused', true);
160+ } else {
161+ this.set('paused', false);
162+ }
163+ },
164+
165+ /**
166+ * Checks to see if autoadvance is set then sets up the timeouts
167+ *
168+ * @method _startTimer
169+ * @private
170+ */
171+ _startTimer: function() {
172+
173+ if (this.get('autoAdvance') === true) {
174+ var timer = Y.later(this.get('advanceDelay'), this, function() {
175+ if (this.get('paused') !== true) {
176+ this._advanceSlide();
177+ }
178+ }, null, true);
179+ this.set('timer', timer);
180+ }
181+ },
182+
183+ /**
184+ * Stops the timer for autoadvance
185+ *
186+ * @method _stopTimer
187+ * @private
188+ */
189+ _stopTimer: function() {
190+ var timer = this.get('timer');
191+ if (timer) {
192+ timer.cancel();
193+ }
194+ },
195+
196+ /**
197+ * Binds the navigate event listeners
198+ *
199+ * @method bindUI
200+ * @private
201+ */
202+ bindUI: function() {
203+
204+ //Call the parent bindUI method
205+ ns.CharmSlider.superclass.bindUI.apply(this);
206+
207+ var events = this.get('_events'),
208+ boundingBox = this.get('boundingBox'),
209+ nav = boundingBox.one('.navigation');
210+ events.push(this.after('render', this._startTimer, this));
211+ events.push(boundingBox.on('mouseenter', this._pauseAutoAdvance, this));
212+ events.push(boundingBox.on('mouseleave', this._pauseAutoAdvance, this));
213+ events.push(nav.delegate('click', function(e) {
214+ var index = e.currentTarget.getAttribute('data-index');
215+ index = parseInt(index, 10);
216+ this._advanceSlide(index);
217+ }, 'li', this));
218+ },
219+
220+ /**
221+ * Detaches events attached during instantiation
222+ *
223+ * @method destructor
224+ * @private
225+ */
226+ destructor: function() {
227+ this.get('_events').each(function(event) {
228+ event.detach();
229+ });
230+ },
231+
232+ /**
233+ * Initializer
234+ *
235+ * @method initializer
236+ * @param {Object} The config object.
237+ *
238+ */
239+ initializer: function(cfg) {
240+ this.plug(Y.Plugin.ScrollViewPaginator, {
241+ selector: 'li'
242+ });
243+
244+ },
245+
246+ /**
247+ * Render the nodes and HTML for the slider.
248+ *
249+ * @method renderUI
250+ * @private
251+ */
252+ renderUI: function() {
253+ this.get('contentBox').setHTML(this._generateDOM());
254+ this._generateSliderControls();
255+ }
256+ }, {
257+ ATTRS: {
258+
259+ /**
260+ * @attribute width
261+ * @default 200
262+ * @type {Int}
263+ *
264+ */
265+ width: {
266+ value: 500
267+ },
268+
269+ /**
270+ * @attribute autoAdvance
271+ * @default true
272+ * @type {Boolean}
273+ *
274+ */
275+ autoAdvance: {
276+ value: true
277+ },
278+
279+ /**
280+ * @attribute advanceDelay
281+ * @default 3000
282+ * @type {Int}
283+ *
284+ */
285+ advanceDelay: {
286+ value: 3000
287+ },
288+
289+ /**
290+ * @attribute paused
291+ * @default false
292+ * @type {Boolean}
293+ *
294+ */
295+ paused: {
296+ value: false
297+ },
298+
299+ /**
300+ * @attribute items
301+ * @default []
302+ * @type {Array}
303+ *
304+ */
305+ items: {
306+ value: [],
307+ /**
308+ * Verify items aren't larger than max value.
309+ *
310+ * @method validator
311+ * @param {Array} The items being validated.
312+ */
313+ validator: function(val) {
314+ return (val.length <= this.get('max'));
315+ }
316+ },
317+
318+ /**
319+ * @attribute _events
320+ * @default []
321+ * @type {Array}
322+ *
323+ */
324+ _events: {
325+ value: []
326+ },
327+
328+ /**
329+ * @attribute max
330+ * @default 5
331+ * @type {Int}
332+ *
333+ */
334+ max: {
335+ value: 5
336+ },
337+
338+ /**
339+ * @attribute timer
340+ * @default null
341+ * @type {Object}
342+ *
343+ */
344+ timer: {
345+ value: null
346+ }
347+ }
348+ });
349+
350+}, '0.1.0', {
351+ requires: [
352+ 'array-extras',
353+ 'base',
354+ 'event-mouseenter',
355+ 'scrollview',
356+ 'scrollview-paginator'
357+ ]
358+});
359
360=== modified file 'app/widgets/charm-small.js'
361--- app/widgets/charm-small.js 2013-03-04 21:26:27 +0000
362+++ app/widgets/charm-small.js 2013-03-08 19:44:21 +0000
363@@ -57,7 +57,7 @@
364 },
365
366 /**
367- * Desctructor
368+ * Destructor
369 *
370 * @method destructor
371 * @return {undefined} Mutates only.
372
373=== added file 'lib/views/browser/charm-slider.less'
374--- lib/views/browser/charm-slider.less 1970-01-01 00:00:00 +0000
375+++ lib/views/browser/charm-slider.less 2013-03-08 19:44:21 +0000
376@@ -0,0 +1,29 @@
377+.yui3-browser-charm-slider {
378+
379+ .yui3-browser-charm-slider-content {
380+ white-space: nowrap;
381+
382+ ul {
383+ margin: 0;
384+ -moz-padding-start: 0;
385+ padding-start: 0;
386+ -webkit-padding-start: 0;
387+ }
388+
389+ li {
390+ display: inline-block;
391+ text-align: center;
392+ vertical-align: middle;
393+ }
394+ }
395+
396+ .navigate {
397+ cursor: pointer;
398+ list-style-type: none;
399+
400+ li {
401+ display: block-inline;
402+ width: auto;
403+ }
404+ }
405+}
406
407=== modified file 'lib/views/stylesheet.less'
408--- lib/views/stylesheet.less 2013-03-06 15:07:47 +0000
409+++ lib/views/stylesheet.less 2013-03-08 19:44:21 +0000
410@@ -1635,3 +1635,4 @@
411 }
412
413 @import "browser/charm-small.less";
414+@import "browser/charm-slider.less";
415
416=== modified file 'test/index.html'
417--- test/index.html 2013-03-06 15:59:28 +0000
418+++ test/index.html 2013-03-08 19:44:21 +0000
419@@ -39,6 +39,7 @@
420 <script src="test_charm_configuration.js"></script>
421 <script src="test_charm_panel.js"></script>
422 <script src="test_charm_small_widget.js"></script>
423+ <script src="test_charm_slider.js"></script>
424 <script src="test_charm_store.js"></script>
425 <script src="test_charm_view.js"></script>
426 <script src="test_console.js"></script>
427
428=== added file 'test/test_charm_slider.js'
429--- test/test_charm_slider.js 1970-01-01 00:00:00 +0000
430+++ test/test_charm_slider.js 2013-03-08 19:44:21 +0000
431@@ -0,0 +1,81 @@
432+'use strict';
433+
434+describe('charm slider', function() {
435+ var container, Y;
436+
437+ before(function(done) {
438+ Y = YUI(GlobalConfig).use(
439+ ['browser-charm-slider', 'browser-charm-small', 'event-simulate',
440+ 'node-event-simulate', 'node'], function(Y) {
441+ done();
442+ });
443+ });
444+
445+ beforeEach(function() {
446+ container = Y.Node.create('<div id="container"></div>');
447+ Y.one('body').prepend(container);
448+ });
449+
450+ afterEach(function() {
451+ container.remove(true);
452+ });
453+
454+ it('initializes', function() {
455+ var cs = new Y.juju.widgets.browser.CharmSlider();
456+ assert.isObject(cs);
457+ });
458+
459+ it('creates the right DOM', function() {
460+ var cs = new Y.juju.widgets.browser.CharmSlider(),
461+ items = ['foo', 'bar', 'baz'];
462+ cs.set('items', items);
463+ var sliderDOM = cs._generateDOM();
464+ assert.equal(3, sliderDOM.all('li').size());
465+ var html = sliderDOM.get('outerHTML');
466+ Y.Array.each(items, function(item) {
467+ assert.notEqual(-1, html.indexOf(item));
468+ });
469+ });
470+
471+ it('renders', function() {
472+ var cs = new Y.juju.widgets.browser.CharmSlider({
473+ items: ['<div id="foo"/>']
474+ });
475+ cs.render(container);
476+ assert.isObject(Y.one('#foo'));
477+ });
478+
479+ it('it generates buttons for each', function() {
480+ var cs = new Y.juju.widgets.browser.CharmSlider(),
481+ items = ['<div />', '<div />'];
482+ cs.set('items', items);
483+ cs.render(container);
484+ var nav = Y.one('.navigation');
485+ assert.equal(items.length, nav.all('li').size());
486+ });
487+
488+ it('pauses on hover', function() {
489+ var cs = new Y.juju.widgets.browser.CharmSlider({items: ['<div/>']});
490+ cs.render(container);
491+ Y.one('.yui3-browser-charm-slider').simulate('mouseover');
492+ assert.isTrue(cs.get('paused'), 'Slider is not paused.');
493+ Y.one('.yui3-browser-charm-slider').simulate('mouseout');
494+ assert.isFalse(cs.get('paused'), 'Slider is not paused.');
495+ });
496+
497+ it('goes to the right slide on nav click', function() {
498+ var cs = new Y.juju.widgets.browser.CharmSlider({
499+ items: ['<div/>', '<div/>'],
500+ autoAdvance: false
501+ });
502+ cs.render(container);
503+ assert.equal(
504+ 0, cs.pages.get('index'),
505+ 'Slider did not start on first slide.');
506+ var li = Y.one('.navigation').all('li').pop();
507+ li.simulate('click');
508+ assert.equal(
509+ 1, cs.pages.get('index'),
510+ 'Slider did not advance to second slide.');
511+ });
512+});

Subscribers

People subscribed via source and target branches