spud_media 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/Rakefile +2 -14
  2. data/Readme.markdown +21 -1
  3. data/app/assets/images/spud/admin/media_tiny.png +0 -0
  4. data/app/assets/javascripts/spud/admin/{media.js → media/application.js} +12 -13
  5. data/app/assets/javascripts/spud/admin/media/picker.js +208 -0
  6. data/app/assets/javascripts/spud/admin/media/plugin.js +98 -0
  7. data/app/assets/stylesheets/spud/admin/{media.css → media/application.css} +1 -0
  8. data/app/assets/stylesheets/spud/admin/media/plugin.css +154 -0
  9. data/app/controllers/spud/admin/media_controller.rb +1 -1
  10. data/app/controllers/spud/admin/media_picker_controller.rb +28 -0
  11. data/app/models/spud_media.rb +6 -7
  12. data/app/views/spud/admin/media/edit.html.erb +1 -1
  13. data/app/views/spud/admin/media/index.html.erb +6 -2
  14. data/app/views/spud/admin/media_picker/_media.html.erb +19 -0
  15. data/app/views/spud/admin/media_picker/create.html.erb +1 -0
  16. data/app/views/spud/admin/media_picker/create.js.erb +1 -0
  17. data/app/views/spud/admin/media_picker/index.html.erb +103 -0
  18. data/config/routes.rb +1 -0
  19. data/lib/responds_to_parent.rb +69 -0
  20. data/lib/spud_media.rb +1 -0
  21. data/lib/spud_media/engine.rb +2 -5
  22. data/lib/spud_media/version.rb +1 -1
  23. metadata +61 -82
  24. data/app/views/layouts/spud/admin/media/detail.html.erb +0 -5
  25. data/test/dummy/README.rdoc +0 -261
  26. data/test/dummy/Rakefile +0 -7
  27. data/test/dummy/app/assets/javascripts/application.js +0 -15
  28. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  29. data/test/dummy/app/controllers/application_controller.rb +0 -3
  30. data/test/dummy/app/helpers/application_helper.rb +0 -2
  31. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  32. data/test/dummy/config.ru +0 -4
  33. data/test/dummy/config/application.rb +0 -56
  34. data/test/dummy/config/boot.rb +0 -10
  35. data/test/dummy/config/database.yml +0 -25
  36. data/test/dummy/config/environment.rb +0 -5
  37. data/test/dummy/config/environments/development.rb +0 -37
  38. data/test/dummy/config/environments/production.rb +0 -67
  39. data/test/dummy/config/environments/test.rb +0 -37
  40. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  41. data/test/dummy/config/initializers/inflections.rb +0 -15
  42. data/test/dummy/config/initializers/mime_types.rb +0 -5
  43. data/test/dummy/config/initializers/secret_token.rb +0 -7
  44. data/test/dummy/config/initializers/session_store.rb +0 -8
  45. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  46. data/test/dummy/config/locales/en.yml +0 -5
  47. data/test/dummy/config/routes.rb +0 -4
  48. data/test/dummy/public/404.html +0 -26
  49. data/test/dummy/public/422.html +0 -26
  50. data/test/dummy/public/500.html +0 -25
  51. data/test/dummy/public/favicon.ico +0 -0
  52. data/test/dummy/script/rails +0 -6
data/Rakefile CHANGED
@@ -20,21 +20,9 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
20
  rdoc.rdoc_files.include('lib/**/*.rb')
21
21
  end
22
22
 
23
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
24
  load 'rails/tasks/engine.rake'
25
25
 
26
-
27
-
28
26
  Bundler::GemHelper.install_tasks
29
27
 
30
- require 'rake/testtask'
31
-
32
- Rake::TestTask.new(:test) do |t|
33
- t.libs << 'lib'
34
- t.libs << 'test'
35
- t.pattern = 'test/**/*_test.rb'
36
- t.verbose = false
37
- end
38
-
39
-
40
- task :default => :test
28
+ require 'rake'
@@ -50,4 +50,24 @@ Files marked as unprotected will be uploaded to Amazon using the `public_read` A
50
50
 
51
51
  Files marked as protected are uploaded using the `private` ACL. In this case, calling `@media.attachment_url` will return a local URL that hits the show action of our `ProtectedMedia` controller. Once we have verified the user is logged in we generate a secure URL and redirect the user to it. The generated URL is good for 10 minutes.
52
52
 
53
- [1]:https://github.com/davydotcom/spud_core_admin
53
+ [1]:https://github.com/davydotcom/spud_core_admin
54
+
55
+ Testing
56
+ -----------------
57
+
58
+ Spud uses RSpec for testing. Get the tests running with a few short commands:
59
+
60
+ 1. Create and migrate the databases:
61
+
62
+ rake db:create
63
+ rake db:migrate
64
+
65
+ 2. Load the schema in to the test database:
66
+
67
+ rake app:db:test:prepare
68
+
69
+ 3. Run the tests with RSpec
70
+
71
+ rspec spec
72
+
73
+ After the tests have completed the current code coverage stats is available by opening ```/coverage/index.html``` in a browser.
@@ -1,10 +1,9 @@
1
1
  //= require jcrop/js/jquery.Jcrop
2
+ //= require spud/admin/media/plugin
3
+ //= require spud/admin/media/picker
2
4
  //= require_self
3
5
 
4
- Spud = (typeof(Spud) == 'undefined') ? {} : Spud;
5
- Spud.Admin = (typeof(Spud.Admin) == 'undefined') ? {} : Spud.Admin;
6
-
7
- Spud.Admin.Media = new function(){
6
+ spud.admin.media = new function(){
8
7
 
9
8
  var self = this;
10
9
  var cropimage;
@@ -51,7 +50,7 @@ Spud.Admin.Media = new function(){
51
50
  cropscaleincrement = Math.ceil(3.0 * (maxcropscale / 100));
52
51
 
53
52
  // scale down the original if necessary
54
- cropscale = parseInt($('#spud_media_crop_s').val());
53
+ cropscale = parseInt($('#spud_media_crop_s').val(), 10);
55
54
  if(cropscale > maxcropscale){
56
55
  $('#spud_media_crop_s').val(maxcropscale);
57
56
  cropscale = maxcropscale;
@@ -114,14 +113,14 @@ Spud.Admin.Media = new function(){
114
113
 
115
114
  this.changedMediaCropScale = function(e){
116
115
  var val = $(this).val();
117
- var percent = parseInt(val);
116
+ var percent = parseInt(val, 10);
118
117
  if(!percent || percent > maxcropscale){
119
118
  $(this).val(maxcropscale);
120
119
  }
121
120
  else{
122
121
  $(this).val(percent);
123
122
  cropscale = percent;
124
- self.resizeAndCenter(percent);
123
+ self.resizeAndCenter(percent);
125
124
  }
126
125
  };
127
126
 
@@ -136,7 +135,7 @@ Spud.Admin.Media = new function(){
136
135
  $('#spud_media_crop_s').val(cropscale);
137
136
  self.resizeAndCenter(cropscale);
138
137
  return false;
139
- }
138
+ };
140
139
 
141
140
  this.changedMediaCropDimensions = function(e){
142
141
  var selection = self.getSelectFields();
@@ -146,10 +145,10 @@ Spud.Admin.Media = new function(){
146
145
  };
147
146
 
148
147
  this.getSelectFields = function(){
149
- var x = parseInt($('#spud_media_crop_x').val());
150
- var y = parseInt($('#spud_media_crop_y').val());
151
- var w = parseInt($('#spud_media_crop_w').val());
152
- var h = parseInt($('#spud_media_crop_h').val());
148
+ var x = parseInt($('#spud_media_crop_x').val(), 10);
149
+ var y = parseInt($('#spud_media_crop_y').val(), 10);
150
+ var w = parseInt($('#spud_media_crop_w').val(), 10);
151
+ var h = parseInt($('#spud_media_crop_h').val(), 10);
153
152
  var x2 = x + w;
154
153
  var y2 = y + h;
155
154
  if(isNaN(x) || isNaN(w) || isNaN(x2) || isNaN(y2)){
@@ -158,7 +157,7 @@ Spud.Admin.Media = new function(){
158
157
  else{
159
158
  return [x * (100 / cropscale), y * (100 / cropscale), x2 * (100 / cropscale), y2 * (100 / cropscale)];
160
159
  }
161
- }
160
+ };
162
161
 
163
162
  this.preventSubmitOnEnterKey = function(e){
164
163
  if(e.keyCode == 13) {
@@ -0,0 +1,208 @@
1
+ spud.admin.mediapicker = new function(){
2
+
3
+ var self = this;
4
+ var supportsHtml5Upload = false;
5
+ var selectedFile = {};
6
+
7
+ self.init = function(){
8
+ if(typeof(FormData) != 'undefined'){
9
+ supportsHtml5Upload = true;
10
+ }
11
+ $('.spud_media_picker_tab').on('click', self.clickedTab);
12
+ $('.spud_media_picker_upload_form').on('submit', self.submittedUpload);
13
+ $('.spud_media_picker_list').on('click', '.spud_media_picker_item', self.clickedListItem);
14
+ $('.spud_media_picker_button_cancel').on('click', self.clickedCancel);
15
+ $('.spud_media_picker_button_use_selected').on('click', self.clickedUseSelected);
16
+ $('.spud_media_picker_button_insert').on('click', self.clickedInsert);
17
+ $('.spud_media_picker_item').first().click();
18
+ $('.spud_media_picker_tabs a').first().click();
19
+ $('.spud_media_picker_tab_advanced').on('spud_media_picker_tab_activated', self.activatedAdvancedTab);
20
+ $('.spud_media_picker_option_dimensions').on('blur', 'input', self.dimensionsChanged);
21
+ };
22
+
23
+ self.clickedTab = function(e){
24
+ e.preventDefault();
25
+ self.goToTab($(this).attr('href'));
26
+ };
27
+
28
+ self.goToTab = function(tabName){
29
+ $('.spud_media_picker_tab_active').removeClass('spud_media_picker_tab_active');
30
+ $('a[href="'+tabName+'"]').addClass('spud_media_picker_tab_active');
31
+ var selector = tabName.replace('#', '.');
32
+ $('.spud_media_picker_tab_body').hide();
33
+ $(selector).show();
34
+ $(selector).trigger('spud_media_picker_tab_activated');
35
+ };
36
+
37
+ self.clickedListItem = function(){
38
+ $('.spud_media_picker_item_selected').removeClass('spud_media_picker_item_selected');
39
+ var element = $(this);
40
+ element.addClass('spud_media_picker_item_selected');
41
+ $('.spud_media_picker_details_thumb').attr('src', element.find('img').attr('src'));
42
+ $('.spud_media_picker_details_name').text(element.attr('data-name'));
43
+ $('.spud_media_picker_details_size').text(element.attr('data-size'));
44
+ $('.spud_media_picker_details_lastmod').text(element.attr('data-lastmod'));
45
+ $('.spud_media_picker_details_protected').text(element.attr('data-protected'));
46
+ $('.spud_media_picker_details').show();
47
+ };
48
+
49
+ self.clickedCancel = function(e){
50
+ e.preventDefault();
51
+ tinyMCEPopup.close();
52
+ };
53
+
54
+ self.clickedUseSelected = function(e){
55
+ e.preventDefault();
56
+ self.goToTab('#spud_media_picker_tab_advanced');
57
+ };
58
+
59
+ self.submittedUpload = function(e){
60
+ if(!$('#spud_media_attachment').val()){
61
+ window.alert("Please select a file.");
62
+ return false;
63
+ }
64
+
65
+ if(supportsHtml5Upload){
66
+ e.preventDefault();
67
+
68
+ // create html5 form object
69
+ var fd = new FormData();
70
+ var form = $(this);
71
+ var file = form.find('#spud_media_attachment')[0].files[0];
72
+ fd.append('_method', form.find('[name=_method]').val());
73
+ fd.append('authenticity_token', form.find('[name=authenticity_token]').val());
74
+ fd.append('spud_media[attachment]', file);
75
+
76
+ // upload via xhr
77
+ var xhr = new XMLHttpRequest();
78
+ xhr.upload.addEventListener('progress', self.onFileUploadProgress);
79
+ xhr.addEventListener('load', self.onFileUploadComplete);
80
+ xhr.addEventListener('error', self.onFileUploadError);
81
+ xhr.addEventListener('abort', self.onFileUploadAbort);
82
+ xhr.open('POST', form.attr('action'));
83
+ xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
84
+ xhr.send(fd);
85
+
86
+ $('.spud_media_picker_upload_progress').show();
87
+ }
88
+ };
89
+
90
+ this.onFileUploadProgress = function(e){
91
+ var percent = Math.round(e.loaded * 100 / e.total);
92
+ var progress = $('.spud_media_picker_upload_progress');
93
+ progress.find('.bar').css({width: percent + '%'});
94
+ if(percent == 100){
95
+ progress.addClass('progress-success');
96
+ }
97
+ };
98
+
99
+ this.onFileUploadComplete = function(e){
100
+ var html = e.target.response;
101
+ self.onLegacyUploadComplete(html);
102
+ };
103
+
104
+ this.onFileUploadError = function(e){
105
+ window.alert('Whoops! Something has gone wrong.');
106
+ self.resetUploadForm();
107
+ };
108
+
109
+ this.onFileUploadAbort = function(e){
110
+ self.resetUploadForm();
111
+ };
112
+
113
+ // Non-html5 upload
114
+ this.onLegacyUploadComplete = function(html){
115
+ $('.spud_media_picker_list').prepend(html);
116
+ $('.spud_media_picker_item').first().click();
117
+ self.goToTab('#spud_media_picker_tab_choose');
118
+ self.resetUplaodForm();
119
+ };
120
+
121
+ this.resetUploadForm = function(){
122
+ // reset twitter bootstrap "loading" button state
123
+ $('.spud_media_picker_tab_upload_submit').button('reset');
124
+ $('#spud_media_attachment').val('');
125
+ $('.spud_media_picker_upload_progress').hide();
126
+ $('.spud_media_picker_upload_progress .bar').css({width:0});
127
+ };
128
+
129
+ this.activatedAdvancedTab = function(){
130
+ var selected = $('.spud_media_picker_item_selected');
131
+ selectedFile = {
132
+ id: selected.attr('data-id'),
133
+ type: selected.attr('data-type'),
134
+ url: selected.attr('data-url'),
135
+ name: selected.attr('data-name'),
136
+ size: selected.attr('data-size'),
137
+ lastmod: selected.attr('data-lastmod'),
138
+ isprotected: selected.attr('data-protected')
139
+ };
140
+ $('input[name="spud_media_picker_option_selected_file"]').val(selectedFile.name);
141
+ $('input[name="spud_media_picker_option_type"]').val(selectedFile.type == 'img' ? 'Image' : 'File');
142
+ if(selectedFile.type == 'img'){
143
+ $('.spud_media_picker_option_target').hide();
144
+ $('.spud_media_picker_option_text').hide();
145
+ $('.spud_media_picker_option_float').show();
146
+ $('.spud_media_picker_option_title').show();
147
+ $('.spud_media_picker_option_dimensions').show();
148
+ self.getOriginalImageDimensions(selectedFile.url);
149
+ }
150
+ else{
151
+ $('.spud_media_picker_option_target').show();
152
+ $('.spud_media_picker_option_text').show();
153
+ $('.spud_media_picker_option_float').hide();
154
+ $('.spud_media_picker_option_title').hide();
155
+ $('.spud_media_picker_option_dimensions').hide();
156
+ }
157
+ };
158
+
159
+ var _originalWidth, _originalHeight;
160
+ self.getOriginalImageDimensions = function(url){
161
+ var img = new Image();
162
+ img.onload = function(){
163
+ _originalWidth = img.width;
164
+ _originalHeight = img.height;
165
+ console.log(_originalWidth, _originalHeight);
166
+ };
167
+ img.src = url;
168
+ };
169
+
170
+ self.dimensionsChanged = function(e){
171
+ var element = $(this);
172
+ var val = parseInt(element.val(), 10);
173
+ if(isNaN(val)){
174
+ element.val('');
175
+ return;
176
+ }
177
+ var name = element.attr('name');
178
+ if(name == 'spud_media_picker_option_dimension_w'){
179
+ var height = Math.floor((_originalHeight/_originalWidth) * val);
180
+ $('input[name="spud_media_picker_option_dimension_h"]').val(height);
181
+ }
182
+ else{
183
+ var width = Math.ceil((_originalWidth/_originalHeight) * val);
184
+ $('input[name="spud_media_picker_option_dimension_w"]').val(width);
185
+ }
186
+ };
187
+
188
+ self.clickedInsert = function(e){
189
+ e.preventDefault();
190
+ if(selectedFile.type == 'img'){
191
+ selectedFile.title = $('input[name="spud_media_picker_option_title"]').val();
192
+ selectedFile.width = parseInt($('input[name="spud_media_picker_option_dimension_w"]').val(), 10);
193
+ selectedFile.height = parseInt($('input[name="spud_media_picker_option_dimension_h"]').val(), 10);
194
+ var float = $('select[name="spud_media_picker_option_float"]').val();
195
+ var style = "";
196
+ if(float){
197
+ style += "float:" + float + ";";
198
+ }
199
+ selectedFile.style = style;
200
+ }
201
+ else{
202
+ selectedFile.target = $('select[name="spud_media_picker_option_target"]').val();
203
+ selectedFile.text = $('input[name="spud_media_picker_option_text"]').val();
204
+ }
205
+ tinyMCEPopup.editor.execCommand('spudMediaInsertSelected', false, selectedFile);
206
+ tinyMCEPopup.close();
207
+ };
208
+ };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * editor_plugin_src.js
3
+ *
4
+ * Copyright 2009, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://tinymce.moxiecode.com/license
8
+ * Contributing: http://tinymce.moxiecode.com/contributing
9
+ */
10
+
11
+ (function() {
12
+
13
+ spud.admin.editor.registerPlugin('spud_media_picker');
14
+ spud.admin.editor.registerButton('spud_media_picker');
15
+
16
+ tinymce.create('tinymce.plugins.SpudMediaPicker', {
17
+ /**
18
+ * Initializes the plugin, this will be executed after the plugin has been created.
19
+ * This call is done before the editor instance has finished it's initialization so use the onInit event
20
+ * of the editor instance to intercept that event.
21
+ *
22
+ * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
23
+ * @param {string} url Absolute URL to where the plugin is located.
24
+ */
25
+ init : function(ed, url) {
26
+ // Register the command so that it can be invoked by using tinyMCE.activeEditor.execCommand('mceExample');
27
+ ed.addCommand('spudMediaShowPicker', function(){
28
+ ed.windowManager.open({
29
+ title: 'Spud Media Picker',
30
+ file: '/spud/admin/media_picker',
31
+ width: 450 + parseInt(ed.getLang('example.delta_width', 0), 10),
32
+ height: 300 + parseInt(ed.getLang('example.delta_height', 0), 10),
33
+ inline: 1,
34
+ resizable: false,
35
+ popup_css: false, // prevent tinymce from injecting some default css into our dialog box
36
+ close_previous: true, // close any previously opened dialogs
37
+ scrollbars: false
38
+ });
39
+ });
40
+
41
+ // Register picker button
42
+ ed.addButton('spud_media_picker', {
43
+ title: 'Insert Spud Media',
44
+ cmd: 'spudMediaShowPicker',
45
+ image: '/assets/spud/admin/media_tiny.png'
46
+ });
47
+
48
+ ed.addCommand('spudMediaInsertSelected', function(ui, data){
49
+ if(data.type == 'img'){
50
+ var img = ed.dom.createHTML('img', {
51
+ src: data.url,
52
+ title: data.title,
53
+ style: data.style,
54
+ width: data.width,
55
+ height: data.height
56
+ });
57
+ ed.execCommand('mceInsertContent', false, img);
58
+ }
59
+ else{
60
+ var link = ed.dom.createHTML('a', {
61
+ href: data.url,
62
+ target: data.target
63
+ }, data.text);
64
+ ed.execCommand('mceInsertContent', false, link);
65
+ }
66
+ });
67
+
68
+ /*
69
+ * Add a node change handler, selects the button in the UI when a image is selected
70
+ * @param {tinymce.Editor} ed Editor
71
+ * @param {tinymce.ControlManager} cm
72
+ * @param {node} n
73
+ */
74
+ // ed.onNodeChange.add(function(ed, cm, n) {
75
+ // cm.setActive('spud_media_picker', n.nodeName == 'IMG');
76
+ // });
77
+ },
78
+
79
+ /**
80
+ * Returns information about the plugin as a name/value array.
81
+ * The current keys are longname, author, authorurl, infourl and version.
82
+ *
83
+ * @return {Object} Name/value array containing information about the plugin.
84
+ */
85
+ getInfo: function(){
86
+ return {
87
+ longname : 'Spud Media',
88
+ author : 'Greg Woods',
89
+ authorurl : 'https://github.com/davydotcom/spud_media',
90
+ infourl : 'https://github.com/davydotcom/spud_media',
91
+ version : "1.0"
92
+ };
93
+ }
94
+ });
95
+
96
+ // Register plugin
97
+ tinymce.PluginManager.add('spud_media_picker', tinymce.plugins.SpudMediaPicker);
98
+ })();
@@ -1,5 +1,6 @@
1
1
  /*
2
2
  *= require jcrop/css/jquery.Jcrop
3
+ *= require spud/admin/media/plugin
3
4
  */
4
5
 
5
6
  img.size-50-thumb {
@@ -0,0 +1,154 @@
1
+ .spud_media_picker{
2
+ background: white;
3
+ font: normal 12px/12px sans-serif;
4
+ }
5
+ .spud_media_picker_container{
6
+ padding: 10px;
7
+ }
8
+
9
+ /* Picker Tabs
10
+ -------------- */
11
+ .spud_media_picker_tabs{
12
+ border-bottom: 1px solid #ccc;
13
+ margin: 0 0 10px;
14
+ }
15
+ .spud_media_picker_tab{
16
+ display: inline-block;
17
+ font: normal 12px/22px sans-serif;
18
+ padding: 0 5px;
19
+ margin: 0 5px 0 0;
20
+ position: relative;
21
+ top: 1px;
22
+ -webkit-touch-callout: none;
23
+ -webkit-user-select: none;
24
+ -khtml-user-select: none;
25
+ -moz-user-select: none;
26
+ -ms-user-select: none;
27
+ user-select: none;
28
+ }
29
+ .spud_media_picker_tab_active{
30
+ border: 1px solid #ccc;
31
+ border-bottom: 1px solid white;
32
+ }
33
+ .spud_media_picker_tab_body{
34
+ display: none;
35
+ height: 200px;
36
+ padding-bottom: 40px;
37
+ position: relative;
38
+ }
39
+
40
+ /* Buttons
41
+ ------------ */
42
+ .spud_media_picker_buttons{
43
+ position: absolute;
44
+ bottom: 0;
45
+ left: 0;
46
+ width: 100%;
47
+ }
48
+ .spud_media_picker_buttons a, .spud_media_picker_buttons input, .spud_media_picker_buttons button{
49
+ float: right;
50
+ margin-left: 5px;
51
+ }
52
+ .spud_media_picker label{
53
+ font-size: 12px;
54
+ }
55
+
56
+ /* Uploader
57
+ ------------ */
58
+ .spud_media_picker_upload_progress{
59
+ display: none;
60
+ }
61
+ .spud_media_picker_upload_progress .bar{
62
+ width: 0;
63
+ }
64
+
65
+ /* Picker List
66
+ --------------- */
67
+ .spud_media_picker_list{
68
+ height: 100%;
69
+ width: 200px;
70
+ overflow: auto;
71
+ border: 1px solid #ccc;
72
+ float: left;
73
+ margin: 0 0 10px 0;
74
+ }
75
+ .spud_media_picker_item{
76
+ cursor: pointer;
77
+ padding: 3px;
78
+ font: normal 12px/20px sans-serif;
79
+ border-top: 1px solid #ccc;
80
+ overflow: hidden;
81
+ height: 20px;
82
+ white-space: nowrap;
83
+ -webkit-touch-callout: none;
84
+ -webkit-user-select: none;
85
+ -khtml-user-select: none;
86
+ -moz-user-select: none;
87
+ -ms-user-select: none;
88
+ user-select: none;
89
+ }
90
+ .spud_media_picker_item:first-child{
91
+ border-top: none;
92
+ }
93
+ .spud_media_picker_item:last-child{
94
+ border-bottom: 1px solid #ccc;
95
+ }
96
+ .spud_media_picker_item:hover{
97
+ background: #E6E6E6;
98
+ }
99
+ .spud_media_picker_item_selected{
100
+ background: #D6E4F5;
101
+ }
102
+ .spud_media_picker_item img{
103
+ max-width: 20px;
104
+ max-height: 20px;
105
+ float: left;
106
+ margin: 0 4px 0 0;
107
+ }
108
+
109
+ /* Picker Details
110
+ -------------------- */
111
+ .spud_media_picker_details{
112
+ margin: 0 0 0 220px;
113
+ display: none;
114
+ overflow-x: hidden;
115
+ }
116
+ .spud_media_picker_details_thumb{
117
+ max-width: 100px;
118
+ max-height: 100px;
119
+ }
120
+ .spud_media_picker_details_meta{
121
+ font: bold 11px sans-serif;
122
+ margin: 10px 0 0;
123
+ padding: 0 0 0 15px;
124
+ white-space: nowrap;
125
+ }
126
+ .spud_media_picker_details_meta span{
127
+ font-weight: normal;
128
+ }
129
+
130
+ /* Advanced Options
131
+ ------------------- */
132
+ .spud_media_picker_tab_advanced{
133
+
134
+ }
135
+ .spud_media_picker_option{
136
+ margin: 10px 0;
137
+ }
138
+ .spud_media_picker_tab_advanced label{
139
+ width: 100px;
140
+ padding: 0 5px 0 0;
141
+ text-align: right;
142
+ }
143
+ .spud_media_picker_tab_advanced label, .spud_media_picker_tab_advanced select, .spud_media_picker_tab_advanced input{
144
+ display: inline-block;
145
+ margin: 0;
146
+ }
147
+ .spud_media_picker_tab_advanced select{
148
+ font: normal 12px/12px sans-serif;
149
+ height: auto;
150
+ padding: 0;
151
+ }
152
+ .spud_media_picker_option_dimensions input{
153
+ width: 50px;
154
+ }