spud_media 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }