diff --git a/web/spec/features/avatar_spec.rb b/web/spec/features/avatar_spec.rb
index 2261b5a2e..18aab6609 100644
--- a/web/spec/features/avatar_spec.rb
+++ b/web/spec/features/avatar_spec.rb
@@ -21,12 +21,13 @@ describe "Avatar", :js => true, :type => :feature, :capybara_feature => true do
end
it {
- pending "capybara crashes trying this test"
should have_selector('#account-edit-avatar-upload')
- click_link "UPLOAD" # launch filepicker dialog, which is an iframe
- within_frame('filepicker_dialog') {
- attach_file('fileUpload', 'spec/assets/images/sample_avatar.png')
- find('div.jcrop-tracker').should_not be_nil
- }
+
+ # this causes capybara 1.9.0 and 1.9.2 to crash.
+ #click_link "UPLOAD" # launch filepicker dialog, which is an iframe
+ #within_frame('filepicker_dialog') {
+ # attach_file('fileUpload', 'spec/assets/images/sample_avatar.png')
+ # find('div.jcrop-tracker').should_not be_nil
+ #}
}
end
diff --git a/web/spec/features/find_sessions_spec.rb b/web/spec/features/find_sessions_spec.rb
index 0551c54e6..2cd68738f 100644
--- a/web/spec/features/find_sessions_spec.rb
+++ b/web/spec/features/find_sessions_spec.rb
@@ -43,7 +43,7 @@ describe "Find Session", :js => true, :type => :feature, :capybara_feature => tr
within('#create-session-form') do
fill_in('description', :with => @unique_session_desc)
select('Rock', :from => 'genres')
- check('intellectual-property')
+ find('intellectual-property').trigger(:click)
click_link('btn-create-session') # fails if page width is low
end
diff --git a/web/spec/features/music_sessions_spec.rb b/web/spec/features/music_sessions_spec.rb
index 99fbcae3d..cadf2c85c 100644
--- a/web/spec/features/music_sessions_spec.rb
+++ b/web/spec/features/music_sessions_spec.rb
@@ -9,7 +9,7 @@ describe "Music Session", :js => true, :type => :feature, :capybara_feature => t
within('#create-session-form') do
fill_in('description', :with => 'foobar')
select('Ambient', :from => 'genres')
- check('intellectual-property')
+ find('intellectual-property').trigger(:click)
click_link('btn-create-session')
end
uu
diff --git a/web/vendor/assets/images/icheck/minimal.png b/web/vendor/assets/images/icheck/minimal.png
new file mode 100644
index 000000000..943be16fb
Binary files /dev/null and b/web/vendor/assets/images/icheck/minimal.png differ
diff --git a/web/vendor/assets/images/icheck/minimal@2x.png b/web/vendor/assets/images/icheck/minimal@2x.png
new file mode 100644
index 000000000..d62291daa
Binary files /dev/null and b/web/vendor/assets/images/icheck/minimal@2x.png differ
diff --git a/web/vendor/assets/javascripts/jquery.icheck.js b/web/vendor/assets/javascripts/jquery.icheck.js
new file mode 100644
index 000000000..d7d819da3
--- /dev/null
+++ b/web/vendor/assets/javascripts/jquery.icheck.js
@@ -0,0 +1,462 @@
+/*!
+ * iCheck v0.9.1, http://git.io/uhUPMA
+ * =================================
+ * Powerful jQuery plugin for checkboxes and radio buttons customization
+ *
+ * (c) 2013 Damir Foy, http://damirfoy.com
+ * MIT Licensed
+ */
+
+(function($) {
+
+ // Cached vars
+ var _iCheck = 'iCheck',
+ _iCheckHelper = _iCheck + '-helper',
+ _checkbox = 'checkbox',
+ _radio = 'radio',
+ _checked = 'checked',
+ _unchecked = 'un' + _checked,
+ _disabled = 'disabled',
+ _determinate = 'determinate',
+ _indeterminate = 'in' + _determinate,
+ _update = 'update',
+ _type = 'type',
+ _click = 'click',
+ _touch = 'touchbegin.i touchend.i',
+ _add = 'addClass',
+ _remove = 'removeClass',
+ _callback = 'trigger',
+ _label = 'label',
+ _cursor = 'cursor',
+ _mobile = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);
+
+ // Plugin init
+ $.fn[_iCheck] = function(options, fire) {
+
+ // Walker
+ var handle = ':' + _checkbox + ', :' + _radio,
+ stack = $(),
+ walker = function(object) {
+ object.each(function() {
+ var self = $(this);
+
+ if (self.is(handle)) {
+ stack = stack.add(self);
+ } else {
+ stack = stack.add(self.find(handle));
+ };
+ });
+ };
+
+ // Check if we should operate with some method
+ if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {
+
+ // Normalize method's name
+ options = options.toLowerCase();
+
+ // Find checkboxes and radio buttons
+ walker(this);
+
+ return stack.each(function() {
+ if (options == 'destroy') {
+ tidy(this, 'ifDestroyed');
+ } else {
+ operate($(this), true, options);
+ };
+
+ // Fire method's callback
+ if ($.isFunction(fire)) {
+ fire();
+ };
+ });
+
+ // Customization
+ } else if (typeof options == 'object' || !options) {
+
+ // Check if any options were passed
+ var settings = $.extend({
+ checkedClass: _checked,
+ disabledClass: _disabled,
+ indeterminateClass: _indeterminate,
+ labelHover: true
+ }, options),
+
+ selector = settings.handle,
+ hoverClass = settings.hoverClass || 'hover',
+ focusClass = settings.focusClass || 'focus',
+ activeClass = settings.activeClass || 'active',
+ labelHover = !!settings.labelHover,
+ labelHoverClass = settings.labelHoverClass || 'hover',
+
+ // Setup clickable area
+ area = ('' + settings.increaseArea).replace('%', '') | 0;
+
+ // Selector limit
+ if (selector == _checkbox || selector == _radio) {
+ handle = ':' + selector;
+ };
+
+ // Clickable area limit
+ if (area < -50) {
+ area = -50;
+ };
+
+ // Walk around the selector
+ walker(this);
+
+ return stack.each(function() {
+
+ // If already customized
+ tidy(this);
+
+ var self = $(this),
+ node = this,
+ id = node.id,
+
+ // Layer styles
+ offset = -area + '%',
+ size = 100 + (area * 2) + '%',
+ layer = {
+ position: 'absolute',
+ top: offset,
+ left: offset,
+ display: 'block',
+ width: size,
+ height: size,
+ margin: 0,
+ padding: 0,
+ background: '#fff',
+ border: 0,
+ opacity: 0
+ },
+
+ // Choose how to hide input
+ hide = _mobile ? {
+ position: 'absolute',
+ visibility: 'hidden'
+ } : area ? layer : {
+ position: 'absolute',
+ opacity: 0
+ },
+
+ // Get proper class
+ className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,
+
+ // Find assigned labels
+ label = $(_label + '[for="' + id + '"]').add(self.closest(_label)),
+
+ // Wrap input
+ parent = self.wrap('
')[_callback]('ifCreated').parent().append(settings.insert),
+
+ // Layer addition
+ helper = $('
').css(layer).appendTo(parent);
+
+ // Finalize customization
+ self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);
+ !!settings.inheritClass && parent[_add](node.className);
+ !!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);
+ parent.css('position') == 'static' && parent.css('position', 'relative');
+ operate(self, true, _update);
+
+ // Label events
+ if (label.length) {
+ label.on(_click + '.i mouseenter.i mouseleave.i ' + _touch, function(event) {
+ var type = event[_type],
+ item = $(this);
+
+ // Do nothing if input is disabled
+ if (!node[_disabled]) {
+
+ // Click
+ if (type == _click) {
+ operate(self, false, true);
+
+ // Hover state
+ } else if (labelHover) {
+
+ // mouseleave|touchend
+ if (/ve|nd/.test(type)) {
+ parent[_remove](hoverClass);
+ item[_remove](labelHoverClass);
+ } else {
+ parent[_add](hoverClass);
+ item[_add](labelHoverClass);
+ };
+ };
+
+ if (_mobile) {
+ event.stopPropagation();
+ } else {
+ return false;
+ };
+ };
+ });
+ };
+
+ // Input events
+ self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {
+ var type = event[_type],
+ key = event.keyCode;
+
+ // Click
+ if (type == _click) {
+ return false;
+
+ // Keydown
+ } else if (type == 'keydown' && key == 32) {
+ if (!(node[_type] == _radio && node[_checked])) {
+ if (node[_checked]) {
+ off(self, _checked);
+ } else {
+ on(self, _checked);
+ };
+ };
+
+ return false;
+
+ // Keyup
+ } else if (type == 'keyup' && node[_type] == _radio) {
+ !node[_checked] && on(self, _checked);
+
+ // Focus/blur
+ } else if (/us|ur/.test(type)) {
+ parent[type == 'blur' ? _remove : _add](focusClass);
+ };
+ });
+
+ // Helper events
+ helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {
+ var type = event[_type],
+
+ // mousedown|mouseup
+ toggle = /wn|up/.test(type) ? activeClass : hoverClass;
+
+ // Do nothing if input is disabled
+ if (!node[_disabled]) {
+
+ // Click
+ if (type == _click) {
+ operate(self, false, true);
+
+ // Active and hover states
+ } else {
+
+ // State is on
+ if (/wn|er|in/.test(type)) {
+
+ // mousedown|mouseover|touchbegin
+ parent[_add](toggle);
+
+ // State is off
+ } else {
+ parent[_remove](toggle + ' ' + activeClass);
+ };
+
+ // Label hover
+ if (label.length && labelHover && toggle == hoverClass) {
+
+ // mouseout|touchend
+ label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);
+ };
+ };
+
+ if (_mobile) {
+ event.stopPropagation();
+ } else {
+ return false;
+ };
+ };
+ });
+ });
+ } else {
+ return this;
+ };
+ };
+
+ // Do something with inputs
+ function operate(input, direct, method) {
+ var node = input[0];
+ state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,
+ active = method == _update ? {
+ checked: node[_checked],
+ disabled: node[_disabled],
+ indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'
+ } : node[state];
+
+ // Check, disable or indeterminate
+ if (/^(ch|di|in)/.test(method) && !active) {
+ on(input, state);
+
+ // Uncheck, enable or determinate
+ } else if (/^(un|en|de)/.test(method) && active) {
+ off(input, state);
+
+ // Update
+ } else if (method == _update) {
+
+ // Handle states
+ for (var state in active) {
+ if (active[state]) {
+ on(input, state, true);
+ } else {
+ off(input, state, true);
+ };
+ };
+
+ } else if (!direct || method == 'toggle') {
+
+ // Helper or label was clicked
+ if (!direct) {
+ input[_callback]('ifClicked');
+ };
+
+ // Toggle checked state
+ if (active) {
+ if (node[_type] !== _radio) {
+ off(input, state);
+ };
+ } else {
+ on(input, state);
+ };
+ };
+ };
+
+ // Add checked, disabled or indeterminate state
+ function on(input, state, keep) {
+ var node = input[0],
+ parent = input.parent(),
+ checked = state == _checked,
+ indeterminate = state == _indeterminate,
+ callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
+ regular = option(node, callback + capitalize(node[_type])),
+ specific = option(node, state + capitalize(node[_type]));
+
+ // Prevent unnecessary actions
+ if (node[state] !== true) {
+
+ // Toggle assigned radio buttons
+ if (!keep && state == _checked && node[_type] == _radio && node.name) {
+ var form = input.closest('form'),
+ inputs = 'input[name="' + node.name + '"]';
+
+ inputs = form.length ? form.find(inputs) : $(inputs);
+
+ inputs.each(function() {
+ if (this !== node && $.data(this, _iCheck)) {
+ off($(this), state);
+ };
+ });
+ };
+
+ // Indeterminate state
+ if (indeterminate) {
+
+ // Add indeterminate state
+ node[state] = true;
+
+ // Remove checked state
+ if (node[_checked]) {
+ off(input, _checked, 'force');
+ };
+
+ // Checked or disabled state
+ } else {
+
+ // Add checked or disabled state
+ if (!keep) {
+ node[state] = true;
+ };
+
+ // Remove indeterminate state
+ if (checked && node[_indeterminate]) {
+ off(input, _indeterminate, false);
+ };
+ };
+
+ // Trigger callbacks
+ callbacks(input, checked, state, keep);
+ };
+
+ // Add proper cursor
+ if (node[_disabled] && !!option(node, _cursor, true)) {
+ parent.find('.' + _iCheckHelper).css(_cursor, 'default');
+ };
+
+ // Add state class
+ parent[_add](specific || option(node, state));
+
+ // Remove regular state class
+ parent[_remove](regular || option(node, callback) || '');
+ };
+
+ // Remove checked, disabled or indeterminate state
+ function off(input, state, keep) {
+ var node = input[0],
+ parent = input.parent(),
+ checked = state == _checked,
+ indeterminate = state == _indeterminate,
+ callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',
+ regular = option(node, callback + capitalize(node[_type])),
+ specific = option(node, state + capitalize(node[_type]));
+
+ // Prevent unnecessary actions
+ if (node[state] !== false) {
+
+ // Toggle state
+ if (indeterminate || !keep || keep == 'force') {
+ node[state] = false;
+ };
+
+ // Trigger callbacks
+ callbacks(input, checked, callback, keep);
+ };
+
+ // Add proper cursor
+ if (!node[_disabled] && !!option(node, _cursor, true)) {
+ parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');
+ };
+
+ // Remove state class
+ parent[_remove](specific || option(node, state) || '');
+
+ // Add regular state class
+ parent[_add](regular || option(node, callback));
+ };
+
+ // Remove all traces
+ function tidy(node, callback) {
+ if ($.data(node, _iCheck)) {
+ var input = $(node);
+
+ // Remove everything except input
+ input.parent().html(input.attr('style', $.data(node, _iCheck).s || '')[_callback](callback || ''));
+
+ // Unbind events
+ input.off('.i').unwrap();
+ $(_label + '[for="' + node.id + '"]').add(input.closest(_label)).off('.i');
+ };
+ };
+
+ // Get some option
+ function option(node, state, regular) {
+ if ($.data(node, _iCheck)) {
+ return $.data(node, _iCheck).o[state + (regular ? '' : 'Class')];
+ };
+ };
+
+ // Capitalize some string
+ function capitalize(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+ };
+
+ // Executable handlers
+ function callbacks(input, checked, callback, keep) {
+ if (!keep) {
+ if (checked) {
+ input[_callback]('ifToggled');
+ };
+
+ input[_callback]('ifChanged')[_callback]('if' + capitalize(callback));
+ };
+ };
+})(jQuery);
diff --git a/web/vendor/assets/stylesheets/icheck/minimal/minimal.css b/web/vendor/assets/stylesheets/icheck/minimal/minimal.css
new file mode 100644
index 000000000..fea9c54f1
--- /dev/null
+++ b/web/vendor/assets/stylesheets/icheck/minimal/minimal.css
@@ -0,0 +1,60 @@
+/* iCheck plugin Minimal skin, black
+----------------------------------- */
+.icheckbox_minimal,
+.iradio_minimal {
+ display: block;
+ margin: 0;
+ padding: 0;
+ width: 18px;
+ height: 18px;
+ background: url(/assets/icheck/jamkazam.png) no-repeat;
+ border: none;
+ cursor: pointer;
+}
+
+.icheckbox_minimal {
+ background-position: 0 0;
+}
+ .icheckbox_minimal.hover {
+ background-position: -20px 0;
+ }
+ .icheckbox_minimal.checked {
+ background-position: -40px 0;
+ }
+ .icheckbox_minimal.disabled {
+ background-position: -60px 0;
+ cursor: default;
+ }
+ .icheckbox_minimal.checked.disabled {
+ background-position: -80px 0;
+ }
+
+.iradio_minimal {
+ background-position: -100px 0;
+}
+ .iradio_minimal.hover {
+ background-position: -120px 0;
+ }
+ .iradio_minimal.checked {
+ background-position: -140px 0;
+ }
+ .iradio_minimal.disabled {
+ background-position: -160px 0;
+ cursor: default;
+ }
+ .iradio_minimal.checked.disabled {
+ background-position: -180px 0;
+ }
+
+/* Retina support */
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
+ only screen and (-moz-min-device-pixel-ratio: 1.5),
+ only screen and (-o-min-device-pixel-ratio: 3/2),
+ only screen and (min-device-pixel-ratio: 1.5) {
+ .icheckbox_minimal,
+ .iradio_minimal {
+ background-image: url(/assets/icheck/jamkazam@2x.png);
+ -webkit-background-size: 200px 20px;
+ background-size: 200px 20px;
+ }
+}
\ No newline at end of file