helios 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/Gemfile.lock +82 -37
  2. data/README.md +16 -0
  3. data/bin/helios +4 -0
  4. data/example/Gemfile +7 -0
  5. data/example/Gemfile.lock +149 -0
  6. data/example/Procfile +1 -0
  7. data/example/Sample.xcdatamodeld/Sample.xcdatamodel/contents +23 -0
  8. data/example/config.ru +6 -0
  9. data/helios.gemspec +17 -7
  10. data/lib/helios.rb +15 -1
  11. data/lib/helios/backend.rb +46 -0
  12. data/lib/helios/backend/data.rb +36 -0
  13. data/lib/helios/backend/in-app-purchase.rb +33 -0
  14. data/lib/helios/backend/passbook.rb +25 -0
  15. data/lib/helios/backend/push-notification.rb +90 -0
  16. data/lib/helios/commands.rb +1 -0
  17. data/lib/helios/commands/new.rb +27 -0
  18. data/lib/helios/frontend.rb +56 -0
  19. data/lib/helios/frontend/images/data.png +0 -0
  20. data/lib/helios/frontend/images/data.svg +1 -0
  21. data/lib/helios/frontend/images/in-app-purchase.png +0 -0
  22. data/lib/helios/frontend/images/in-app-purchase.svg +1 -0
  23. data/lib/helios/frontend/images/passbook.png +0 -0
  24. data/lib/helios/frontend/images/passbook.svg +1 -0
  25. data/lib/helios/frontend/images/push-notification.png +0 -0
  26. data/lib/helios/frontend/images/push-notification.svg +1 -0
  27. data/lib/helios/frontend/javascripts/foundation/foundation.alerts.js +50 -0
  28. data/lib/helios/frontend/javascripts/foundation/foundation.clearing.js +478 -0
  29. data/lib/helios/frontend/javascripts/foundation/foundation.cookie.js +74 -0
  30. data/lib/helios/frontend/javascripts/foundation/foundation.dropdown.js +122 -0
  31. data/lib/helios/frontend/javascripts/foundation/foundation.forms.js +403 -0
  32. data/lib/helios/frontend/javascripts/foundation/foundation.joyride.js +613 -0
  33. data/lib/helios/frontend/javascripts/foundation/foundation.js +331 -0
  34. data/lib/helios/frontend/javascripts/foundation/foundation.magellan.js +130 -0
  35. data/lib/helios/frontend/javascripts/foundation/foundation.orbit.js +355 -0
  36. data/lib/helios/frontend/javascripts/foundation/foundation.placeholder.js +159 -0
  37. data/lib/helios/frontend/javascripts/foundation/foundation.reveal.js +272 -0
  38. data/lib/helios/frontend/javascripts/foundation/foundation.section.js +183 -0
  39. data/lib/helios/frontend/javascripts/foundation/foundation.tooltips.js +195 -0
  40. data/lib/helios/frontend/javascripts/foundation/foundation.topbar.js +208 -0
  41. data/lib/helios/frontend/javascripts/helios.coffee +48 -0
  42. data/lib/helios/frontend/javascripts/helios/collections.coffee +30 -0
  43. data/lib/helios/frontend/javascripts/helios/models.coffee +23 -0
  44. data/lib/helios/frontend/javascripts/helios/router.coffee +52 -0
  45. data/lib/helios/frontend/javascripts/helios/views.coffee +92 -0
  46. data/lib/helios/frontend/javascripts/vendor/backbone.datagrid.js +662 -0
  47. data/lib/helios/frontend/javascripts/vendor/backbone.js +1487 -0
  48. data/lib/helios/frontend/javascripts/vendor/jquery.js +9597 -0
  49. data/lib/helios/frontend/javascripts/vendor/underscore.js +1227 -0
  50. data/lib/helios/frontend/stylesheets/_settings.scss +988 -0
  51. data/lib/helios/frontend/stylesheets/screen.sass +98 -0
  52. data/lib/helios/frontend/templates/data/entities.hbs +7 -0
  53. data/lib/helios/frontend/templates/data/entity.hbs +17 -0
  54. data/lib/helios/frontend/templates/in-app-purchase/receipt.hbs +53 -0
  55. data/lib/helios/frontend/templates/in-app-purchase/receipts.hbs +39 -0
  56. data/lib/helios/frontend/templates/passbook/passes.hbs +25 -0
  57. data/lib/helios/frontend/templates/push-notification/device.hbs +35 -0
  58. data/lib/helios/frontend/templates/push-notification/devices.hbs +37 -0
  59. data/lib/helios/frontend/views/devices.jst.tpl +3 -0
  60. data/lib/helios/frontend/views/entities.jst.tpl +9 -0
  61. data/lib/helios/frontend/views/index.haml +30 -0
  62. data/lib/helios/frontend/views/passes.jst.tpl +3 -0
  63. data/lib/helios/frontend/views/receipts.jst.tpl +3 -0
  64. data/lib/helios/templates/Gemfile.erb +7 -0
  65. data/lib/helios/templates/Procfile.erb +1 -0
  66. data/lib/helios/templates/README.md.erb +9 -0
  67. data/lib/helios/templates/config.ru.erb +6 -0
  68. data/lib/helios/version.rb +3 -0
  69. metadata +199 -26
@@ -0,0 +1,355 @@
1
+ ;(function ($, window, document, undefined) {
2
+ 'use strict';
3
+
4
+ Foundation.libs = Foundation.libs || {};
5
+
6
+ Foundation.libs.orbit = {
7
+ version: '4.0.0',
8
+
9
+ settings: {
10
+ timer_speed: 10000,
11
+ animation_speed: 500,
12
+ bullets: true,
13
+ stack_on_small: true,
14
+ container_class: 'orbit-container',
15
+ stack_on_small_class: 'orbit-stack-on-small',
16
+ next_class: 'orbit-next',
17
+ prev_class: 'orbit-prev',
18
+ timer_container_class: 'orbit-timer',
19
+ timer_paused_class: 'paused',
20
+ timer_progress_class: 'orbit-progress',
21
+ slides_container_class: 'orbit-slides-container',
22
+ bullets_container_class: 'orbit-bullets',
23
+ bullets_active_class: 'active',
24
+ slide_number_class: 'orbit-slide-number',
25
+ caption_class: 'orbit-caption',
26
+ active_slide_class: 'active',
27
+ orbit_transition_class: 'orbit-transitioning'
28
+ },
29
+
30
+ init: function (scope, method, options) {
31
+ var self = this;
32
+
33
+ if (typeof method === 'object') {
34
+ $.extend(true, self.settings, method);
35
+ }
36
+
37
+ $('[data-orbit]', scope).each($.proxy(self._init, self));
38
+ },
39
+
40
+ _container_html: function() {
41
+ var self = this;
42
+ return '<div class="' + self.settings.container_class + '"></div>';
43
+ },
44
+
45
+ _bullets_container_html: function($slides) {
46
+ var self = this,
47
+ $list = $('<ol class="' + self.settings.bullets_container_class + '"></ol>');
48
+ $slides.each(function(idx, slide) {
49
+ var $item = $('<li data-orbit-slide-number="' + (idx+1) + '" class=""></li>');
50
+ if (idx === 0) {
51
+ $item.addClass(self.settings.bullets_active_class);
52
+ }
53
+ $list.append($item);
54
+ });
55
+ return $list;
56
+ },
57
+
58
+ _slide_number_html: function(slide_number, total_slides) {
59
+ var self = this,
60
+ $container = $('<div class="' + self.settings.slide_number_class + '"></div>');
61
+ $container.append('<span>' + slide_number + '</span> of <span>' + total_slides + '</span>');
62
+ return $container;
63
+ },
64
+
65
+ _timer_html: function() {
66
+ var self = this;
67
+ if (typeof self.settings.timer_speed === 'number' && self.settings.timer_speed > 0) {
68
+ return '<div class="' + self.settings.timer_container_class
69
+ + '"><span></span><div class="' + self.settings.timer_progress_class
70
+ + '"></div></div>';
71
+ } else {
72
+ return '';
73
+ }
74
+ },
75
+
76
+ _next_html: function() {
77
+ var self = this;
78
+ return '<a href="#" class="' + self.settings.next_class + '">Next <span></span></a>';
79
+ },
80
+
81
+ _prev_html: function() {
82
+ var self = this;
83
+ return '<a href="#" class="' + self.settings.prev_class + '">Prev <span></span></a>';
84
+ },
85
+
86
+ _init: function (idx, slider) {
87
+ var self = this,
88
+ $slides_container = $(slider),
89
+ $container = $slides_container.wrap(self._container_html()).parent(),
90
+ $slides = $slides_container.children();
91
+
92
+ $container.append(self._prev_html());
93
+ $container.append(self._next_html());
94
+ $slides_container.addClass(self.settings.slides_container_class);
95
+ if (self.settings.stack_on_small) {
96
+ $container.addClass(self.settings.stack_on_small_class);
97
+ }
98
+ $container.append(self._slide_number_html(1, $slides.length));
99
+ $container.append(self._timer_html());
100
+ if (self.settings.bullets) {
101
+ $container.after(self._bullets_container_html($slides));
102
+ }
103
+ // To better support the "sliding" effect it's easier
104
+ // if we just clone the first and last slides
105
+ $slides_container.append($slides.first().clone().attr('data-orbit-slide',''));
106
+ $slides_container.prepend($slides.last().clone().attr('data-orbit-slide',''));
107
+ // Make the first "real" slide active
108
+ $slides_container.css('marginLeft', '-100%');
109
+ $slides.first().addClass(self.settings.active_slide_class);
110
+
111
+ self._init_events($slides_container);
112
+ self._init_dimensions($slides_container);
113
+ self._start_timer($slides_container);
114
+ },
115
+
116
+ _init_events: function ($slides_container) {
117
+ var self = this,
118
+ $container = $slides_container.parent();
119
+
120
+ $(window)
121
+ .on('load.fndtn.orbit', function() {
122
+ $slides_container.height('');
123
+ $slides_container.height($slides_container.height($container.height()));
124
+ $slides_container.trigger('orbit:ready');
125
+ })
126
+ .on('resize.fndtn.orbit', function() {
127
+ $slides_container.height('');
128
+ $slides_container.height($slides_container.height($container.height()));
129
+ });
130
+
131
+ $(document).on('click.fndtn.orbit', '[data-orbit-link]', function(e) {
132
+ e.preventDefault();
133
+ var id = $(e.currentTarget).attr('data-orbit-link'),
134
+ $slide = $slides_container.find('[data-orbit-slide=' + id + ']').first();
135
+
136
+ if ($slide.length === 1) {
137
+ self._reset_timer($slides_container, true);
138
+ self.goto($slides_container, $slide.index(), function() {});
139
+ }
140
+ });
141
+
142
+ $container.siblings('.' + self.settings.bullets_container_class)
143
+ .on('click.fndtn.orbit', '[data-orbit-slide-number]', function(e) {
144
+ e.preventDefault();
145
+ self._reset_timer($slides_container, true);
146
+ self.goto($slides_container, $(e.currentTarget).data('orbit-slide-number'),function() {});
147
+ });
148
+
149
+ $container
150
+ .on('orbit:after-slide-change.fndtn.orbit', function(e, orbit) {
151
+ var $slide_number = $container.find('.' + self.settings.slide_number_class);
152
+
153
+ if ($slide_number.length === 1) {
154
+ $slide_number.replaceWith(self._slide_number_html(orbit.slide_number, orbit.total_slides));
155
+ }
156
+ })
157
+ .on('orbit:next-slide.fndtn.orbit click.fndtn.orbit', '.' + self.settings.next_class, function(e) {
158
+ e.preventDefault();
159
+ self._reset_timer($slides_container, true);
160
+ self.goto($slides_container, 'next', function() {});
161
+ })
162
+ .on('orbit:prev-slide.fndtn.orbit click.fndtn.orbit', '.' + self.settings.prev_class, function(e) {
163
+ e.preventDefault();
164
+ self._reset_timer($slides_container, true);
165
+ self.goto($slides_container, 'prev', function() {});
166
+ })
167
+ .on('orbit:toggle-play-pause.fndtn.orbit click.fndtn.orbit touchstart.fndtn.orbit', '.' + self.settings.timer_container_class, function(e) {
168
+ e.preventDefault();
169
+ var $timer = $(e.currentTarget).toggleClass(self.settings.timer_paused_class),
170
+ $slides_container = $timer.closest('.' + self.settings.container_class)
171
+ .find('.' + self.settings.slides_container_class);
172
+
173
+ if ($timer.hasClass(self.settings.timer_paused_class)) {
174
+ self._stop_timer($slides_container);
175
+ } else {
176
+ self._start_timer($slides_container);
177
+ }
178
+ })
179
+ .on('touchstart.fndtn.orbit', function(e) {
180
+ var data = {
181
+ start_page_x: e.touches[0].pageX,
182
+ start_page_y: e.touches[0].pageY,
183
+ start_time: (new Date()).getTime(),
184
+ delta_x: 0,
185
+ is_scrolling: undefined
186
+ };
187
+ $container.data('swipe-transition', data);
188
+ e.stopPropagation();
189
+ })
190
+ .on('touchmove.fndtn.orbit', function(e) {
191
+ // Ignore pinch/zoom events
192
+ if(e.touches.length > 1 || e.scale && e.scale !== 1) return;
193
+
194
+ var data = $container.data('swipe-transition');
195
+ if (typeof data === 'undefined') {
196
+ data = {};
197
+ }
198
+
199
+ data.delta_x = e.touches[0].pageX - data.start_page_x;
200
+
201
+ if ( typeof data.is_scrolling === 'undefined') {
202
+ data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) );
203
+ }
204
+
205
+ if (!data.is_scrolling && !data.active) {
206
+ e.preventDefault();
207
+ self._stop_timer($slides_container);
208
+ var direction = (data.delta_x < 0) ? 'next' : 'prev';
209
+ data.active = true;
210
+ self.goto($slides_container, direction, function() {});
211
+ }
212
+ })
213
+ .on('touchend.fndtn.orbit', function(e) {
214
+ $container.data('swipe-transition', {});
215
+ e.stopPropagation();
216
+ });
217
+ },
218
+
219
+ _init_dimensions: function ($slides_container) {
220
+ var $container = $slides_container.parent(),
221
+ $slides = $slides_container.children();
222
+
223
+ $slides_container.css('width', $slides.length * 100 + '%');
224
+ $slides.css('width', 100 / $slides.length + '%');
225
+ $slides_container.height($container.height());
226
+ $slides_container.css('width', $slides.length * 100 + '%');
227
+ },
228
+
229
+ _start_timer: function ($slides_container) {
230
+ var self = this,
231
+ $container = $slides_container.parent();
232
+
233
+ var callback = function() {
234
+ self._reset_timer($slides_container, false);
235
+ self.goto($slides_container, 'next', function() {
236
+ self._start_timer($slides_container);
237
+ });
238
+ };
239
+
240
+ var $timer = $container.find('.' + self.settings.timer_container_class),
241
+ $progress = $timer.find('.' + self.settings.timer_progress_class),
242
+ progress_pct = ($progress.width() / $timer.width()),
243
+ delay = self.settings.timer_speed - (progress_pct * self.settings.timer_speed);
244
+
245
+ $progress.animate({'width': '100%'}, delay, 'linear', callback).data('is-original', 'beans?');
246
+ $slides_container.trigger('orbit:timer-started');
247
+ },
248
+
249
+ _stop_timer: function ($slides_container) {
250
+ var self = this,
251
+ $container = $slides_container.parent(),
252
+ $timer = $container.find('.' + self.settings.timer_container_class),
253
+ $progress = $timer.find('.' + self.settings.timer_progress_class),
254
+ progress_pct = $progress.width() / $timer.width()
255
+ self._rebuild_timer($container, progress_pct * 100 + '%');
256
+ // $progress.stop();
257
+ $slides_container.trigger('orbit:timer-stopped');
258
+ $timer = $container.find('.' + self.settings.timer_container_class);
259
+ $timer.addClass(self.settings.timer_paused_class);
260
+ },
261
+
262
+ _reset_timer: function($slides_container, is_paused) {
263
+ var self = this,
264
+ $container = $slides_container.parent();
265
+ self._rebuild_timer($container, '0%');
266
+ if (typeof is_paused === 'boolean' && is_paused) {
267
+ var $timer = $container.find('.' + self.settings.timer_container_class);
268
+ $timer.addClass(self.settings.timer_paused_class);
269
+ }
270
+ },
271
+
272
+ _rebuild_timer: function ($container, width_pct) {
273
+ // Zepto is unable to stop animations since they
274
+ // are css-based. This is a workaround for that
275
+ // limitation, which rebuilds the dom element
276
+ // thus stopping the animation
277
+ var self = this,
278
+ $timer = $container.find('.' + self.settings.timer_container_class),
279
+ $new_timer = $(self._timer_html()),
280
+ $new_timer_progress = $new_timer.find('.' + self.settings.timer_progress_class);
281
+
282
+ if (typeof Zepto === 'function') {
283
+ $timer.remove();
284
+ $container.append($new_timer);
285
+ $new_timer_progress.css('width', width_pct);
286
+ } else if (typeof jQuery === 'function') {
287
+ var $progress = $timer.find('.' + self.settings.timer_progress_class);
288
+ $progress.css('width', width_pct);
289
+ $progress.stop();
290
+ }
291
+ },
292
+
293
+ goto: function($slides_container, index_or_direction, callback) {
294
+ var self = this,
295
+ $container = $slides_container.parent(),
296
+ $slides = $slides_container.children(),
297
+ $active_slide = $slides_container.find('.' + self.settings.active_slide_class),
298
+ active_index = $active_slide.index();
299
+
300
+ if ($container.hasClass(self.settings.orbit_transition_class)) {
301
+ return false;
302
+ }
303
+
304
+ if (index_or_direction === 'prev') {
305
+ if (active_index === 0) {
306
+ active_index = $slides.length - 1;
307
+ }
308
+ else {
309
+ active_index--;
310
+ }
311
+ }
312
+ else if (index_or_direction === 'next') {
313
+ active_index = (active_index+1) % $slides.length;
314
+ }
315
+ else if (typeof index_or_direction === 'number') {
316
+ active_index = (index_or_direction % $slides.length);
317
+ }
318
+ if (active_index === ($slides.length - 1) && index_or_direction === 'next') {
319
+ $slides_container.css('marginLeft', '0%');
320
+ active_index = 1;
321
+ }
322
+ else if (active_index === 0 && index_or_direction === 'prev') {
323
+ $slides_container.css('marginLeft', '-' + ($slides.length - 1) * 100 + '%');
324
+ active_index = $slides.length - 2;
325
+ }
326
+ // Start transition, make next slide active
327
+ $container.addClass(self.settings.orbit_transition_class);
328
+ $active_slide.removeClass(self.settings.active_slide_class);
329
+ $($slides[active_index]).addClass(self.settings.active_slide_class);
330
+ // Make next bullet active
331
+ var $bullets = $container.siblings('.' + self.settings.bullets_container_class);
332
+ if ($bullets.length === 1) {
333
+ $bullets.children().removeClass(self.settings.bullets_active_class);
334
+ $($bullets.children()[active_index-1]).addClass(self.settings.bullets_active_class);
335
+ }
336
+ var new_margin_left = '-' + (active_index * 100) + '%';
337
+ // Check to see if animation will occur, otherwise perform
338
+ // callbacks manually
339
+ $slides_container.trigger('orbit:before-slide-change');
340
+ if ($slides_container.css('marginLeft') === new_margin_left) {
341
+ $container.removeClass(self.settings.orbit_transition_class);
342
+ $slides_container.trigger('orbit:after-slide-change', [{slide_number: active_index, total_slides: $slides_container.children().length - 2}]);
343
+ callback();
344
+ } else {
345
+ $slides_container.animate({
346
+ 'marginLeft' : new_margin_left
347
+ }, self.settings.animation_speed, 'linear', function() {
348
+ $container.removeClass(self.settings.orbit_transition_class);
349
+ $slides_container.trigger('orbit:after-slide-change', [{slide_number: active_index, total_slides: $slides_container.children().length - 2}]);
350
+ callback();
351
+ });
352
+ }
353
+ }
354
+ };
355
+ }(Foundation.zj, this, this.document));
@@ -0,0 +1,159 @@
1
+ /*! http://mths.be/placeholder v2.0.7 by @mathias
2
+ Modified to work with Zepto.js by ZURB
3
+ */
4
+ ;(function(window, document, $) {
5
+
6
+ var isInputSupported = 'placeholder' in document.createElement('input'),
7
+ isTextareaSupported = 'placeholder' in document.createElement('textarea'),
8
+ prototype = $.fn,
9
+ valHooks = $.valHooks,
10
+ hooks,
11
+ placeholder;
12
+
13
+ if (isInputSupported && isTextareaSupported) {
14
+
15
+ placeholder = prototype.placeholder = function() {
16
+ return this;
17
+ };
18
+
19
+ placeholder.input = placeholder.textarea = true;
20
+
21
+ } else {
22
+
23
+ placeholder = prototype.placeholder = function() {
24
+ var $this = this;
25
+ $this
26
+ .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
27
+ .not('.placeholder')
28
+ .bind({
29
+ 'focus.placeholder': clearPlaceholder,
30
+ 'blur.placeholder': setPlaceholder
31
+ })
32
+ .data('placeholder-enabled', true)
33
+ .trigger('blur.placeholder');
34
+ return $this;
35
+ };
36
+
37
+ placeholder.input = isInputSupported;
38
+ placeholder.textarea = isTextareaSupported;
39
+
40
+ hooks = {
41
+ 'get': function(element) {
42
+ var $element = $(element);
43
+ return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
44
+ },
45
+ 'set': function(element, value) {
46
+ var $element = $(element);
47
+ if (!$element.data('placeholder-enabled')) {
48
+ return element.value = value;
49
+ }
50
+ if (value == '') {
51
+ element.value = value;
52
+ // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
53
+ if (element != document.activeElement) {
54
+ // We can't use `triggerHandler` here because of dummy text/password inputs :(
55
+ setPlaceholder.call(element);
56
+ }
57
+ } else if ($element.hasClass('placeholder')) {
58
+ clearPlaceholder.call(element, true, value) || (element.value = value);
59
+ } else {
60
+ element.value = value;
61
+ }
62
+ // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
63
+ return $element;
64
+ }
65
+ };
66
+
67
+ isInputSupported || (valHooks.input = hooks);
68
+ isTextareaSupported || (valHooks.textarea = hooks);
69
+
70
+ $(function() {
71
+ // Look for forms
72
+ $(document).delegate('form', 'submit.placeholder', function() {
73
+ // Clear the placeholder values so they don't get submitted
74
+ var $inputs = $('.placeholder', this).each(clearPlaceholder);
75
+ setTimeout(function() {
76
+ $inputs.each(setPlaceholder);
77
+ }, 10);
78
+ });
79
+ });
80
+
81
+ // Clear placeholder values upon page reload
82
+ $(window).bind('beforeunload.placeholder', function() {
83
+ $('.placeholder').each(function() {
84
+ this.value = '';
85
+ });
86
+ });
87
+
88
+ }
89
+
90
+ function args(elem) {
91
+ // Return an object of element attributes
92
+ var newAttrs = {},
93
+ rinlinejQuery = /^jQuery\d+$/;
94
+ $.each(elem.attributes, function(i, attr) {
95
+ if (attr.specified && !rinlinejQuery.test(attr.name)) {
96
+ newAttrs[attr.name] = attr.value;
97
+ }
98
+ });
99
+ return newAttrs;
100
+ }
101
+
102
+ function clearPlaceholder(event, value) {
103
+ var input = this,
104
+ $input = $(input);
105
+ if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
106
+ if ($input.data('placeholder-password')) {
107
+ $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
108
+ // If `clearPlaceholder` was called from `$.valHooks.input.set`
109
+ if (event === true) {
110
+ return $input[0].value = value;
111
+ }
112
+ $input.focus();
113
+ } else {
114
+ input.value = '';
115
+ $input.removeClass('placeholder');
116
+ input == document.activeElement && input.select();
117
+ }
118
+ }
119
+ }
120
+
121
+ function setPlaceholder() {
122
+ var $replacement,
123
+ input = this,
124
+ $input = $(input),
125
+ $origInput = $input,
126
+ id = this.id;
127
+ if (input.value == '') {
128
+ if (input.type == 'password') {
129
+ if (!$input.data('placeholder-textinput')) {
130
+ try {
131
+ $replacement = $input.clone().attr({ 'type': 'text' });
132
+ } catch(e) {
133
+ $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
134
+ }
135
+ $replacement
136
+ .removeAttr('name')
137
+ .data({
138
+ 'placeholder-password': true,
139
+ 'placeholder-id': id
140
+ })
141
+ .bind('focus.placeholder', clearPlaceholder);
142
+ $input
143
+ .data({
144
+ 'placeholder-textinput': $replacement,
145
+ 'placeholder-id': id
146
+ })
147
+ .before($replacement);
148
+ }
149
+ $input = $input.removeAttr('id').hide().prev().attr('id', id).show();
150
+ // Note: `$input[0] != input` now!
151
+ }
152
+ $input.addClass('placeholder');
153
+ $input[0].value = $input.attr('placeholder');
154
+ } else {
155
+ $input.removeClass('placeholder');
156
+ }
157
+ }
158
+
159
+ }(this, document, Foundation.zj));