diff --git a/app/assets/javascripts/discourse/views/composer/composer_view.js b/app/assets/javascripts/discourse/views/composer/composer_view.js index 19d05537461..68fc451e2d9 100644 --- a/app/assets/javascripts/discourse/views/composer/composer_view.js +++ b/app/assets/javascripts/discourse/views/composer/composer_view.js @@ -115,6 +115,15 @@ Discourse.ComposerView = Discourse.View.extend(Ember.Evented, { var $replyControl = $('#reply-control'); $replyControl.DivResizer({ resize: this.resize, onDrag: this.movePanels }); Discourse.TransitionHelper.after($replyControl, this.resize); + this.ensureMaximumDimensionForImagesInPreview(); + }, + + ensureMaximumDimensionForImagesInPreview: function() { + $('' + ).appendTo('head'); }, click: function() { diff --git a/app/assets/stylesheets/desktop/compose.css.scss b/app/assets/stylesheets/desktop/compose.css.scss index cd4f8e001b6..02c2062ef54 100644 --- a/app/assets/stylesheets/desktop/compose.css.scss +++ b/app/assets/stylesheets/desktop/compose.css.scss @@ -292,9 +292,6 @@ } #wmd-input, #wmd-preview { color: $black; - img { - max-width: 100%; - } video { max-width: 100%; diff --git a/app/assets/stylesheets/mobile/compose.css.scss b/app/assets/stylesheets/mobile/compose.css.scss index f279e195b24..484e2a8e448 100644 --- a/app/assets/stylesheets/mobile/compose.css.scss +++ b/app/assets/stylesheets/mobile/compose.css.scss @@ -245,9 +245,6 @@ display: none; } #wmd-input, #wmd-preview { color: $black; - img { - max-width: 100%; - } video { max-width: 100%; @@ -455,7 +452,7 @@ div.ac-wrap { } .control-row.reply-area { - + } @media screen and (min-width: 1550px) { diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 7023c5c5fc4..eabf5d9017d 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -229,7 +229,6 @@ class PostsController < ApplicationController :category, :target_usernames, :reply_to_post_number, - :image_sizes, :auto_close_days, :auto_track ] @@ -245,6 +244,7 @@ class PostsController < ApplicationController params.require(:raw) params.permit(*permitted).tap do |whitelisted| + whitelisted[:image_sizes] = params[:image_sizes] # TODO this does not feel right, we should name what meta_data is allowed whitelisted[:meta_data] = params[:meta_data] end diff --git a/app/models/optimized_image.rb b/app/models/optimized_image.rb index 80a7b204504..6fc88dd825a 100644 --- a/app/models/optimized_image.rb +++ b/app/models/optimized_image.rb @@ -19,7 +19,7 @@ class OptimizedImage < ActiveRecord::Base temp_file = Tempfile.new(["discourse-thumbnail", File.extname(original_path)]) temp_path = temp_file.path - if ImageSorcery.new("#{original_path}[0]").convert(temp_path, resize: "#{width}x#{height}") + if ImageSorcery.new("#{original_path}[0]").convert(temp_path, resize: "#{width}x#{height}!") thumbnail = OptimizedImage.create!( upload_id: upload.id, sha1: Digest::SHA1.file(temp_path).hexdigest, diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index e257ee2f24d..1d771e6fb16 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -78,8 +78,8 @@ class SiteSetting < ActiveRecord::Base setting(:use_ssl, false) setting(:queue_jobs, !Rails.env.test?) setting(:crawl_images, !Rails.env.test?) - setting(:max_image_width, 690) - setting(:max_image_height, 500) + client_setting(:max_image_width, 690) + client_setting(:max_image_height, 500) setting(:create_thumbnails, true) client_setting(:category_featured_topics, 6) setting(:topics_per_page, 30) diff --git a/app/models/upload.rb b/app/models/upload.rb index a7fcafecb1c..5ef3e11d26f 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -14,19 +14,26 @@ class Upload < ActiveRecord::Base validates_presence_of :filesize validates_presence_of :original_filename - def thumbnail + def thumbnail(width = nil, height = nil) + width ||= self.width + height ||= self.height optimized_images.where(width: width, height: height).first end - def has_thumbnail? - thumbnail.present? + def has_thumbnail?(width = nil, height = nil) + thumbnail(width, height).present? end - def create_thumbnail! + def create_thumbnail!(width, height) return unless SiteSetting.create_thumbnails? - return if has_thumbnail? + return if has_thumbnail?(width, height) thumbnail = OptimizedImage.create_for(self, width, height) - optimized_images << thumbnail if thumbnail + if thumbnail + optimized_images << thumbnail + self.width = width + self.height = height + save! + end end def destroy diff --git a/lib/cooked_post_processor.rb b/lib/cooked_post_processor.rb index 7924991a47e..321ae5fce7c 100644 --- a/lib/cooked_post_processor.rb +++ b/lib/cooked_post_processor.rb @@ -85,15 +85,14 @@ class CookedPostProcessor end def update_dimensions!(img) - return if img['width'].present? && img['height'].present? - - w, h = get_size_from_image_sizes(img['src'], @opts[:image_sizes]) || image_dimensions(img['src']) - - if w && h - img['width'] = w - img['height'] = h - @dirty = true - end + w, h = get_size_from_image_sizes(img['src'], @opts[:image_sizes]) || get_size(img['src']) + # make sure we limit the size of the thumbnail + w, h = ImageSizer.resize(w, h) + # check whether the dimensions have changed + @dirty = (img['width'].to_i != w) || (img['height'].to_i != h) + # update the dimensions + img['width'] = w + img['height'] = h end def associate_to_post(upload) @@ -123,7 +122,7 @@ class CookedPostProcessor if upload # create a thumbnail - upload.create_thumbnail! + upload.create_thumbnail!(width, height) # optimize image # TODO: optimize_image!(img) end @@ -156,7 +155,9 @@ class CookedPostProcessor a.add_child(img) # replace the image by its thumbnail - img['src'] = relative_to_absolute(upload.thumbnail.url) if upload && upload.has_thumbnail? + w = img["width"] + h = img["height"] + img['src'] = relative_to_absolute(upload.thumbnail(w, h).url) if upload && upload.has_thumbnail?(w, h) # then, some overlay informations meta = Nokogiri::XML::Node.new("div", @doc) @@ -193,23 +194,13 @@ class CookedPostProcessor end def get_size_from_image_sizes(src, image_sizes) - if image_sizes.present? - if dim = image_sizes[src] - ImageSizer.resize(dim['width'], dim['height']) - end - end - end - - # Retrieve the image dimensions for a url - def image_dimensions(url) - w, h = get_size(url) - ImageSizer.resize(w, h) if w && h + [image_sizes[src]["width"], image_sizes[src]["height"]] if image_sizes.present? && image_sizes[src].present? end def get_size(url) uri = url # make sure urls have a scheme (otherwise, FastImage will fail) - uri = (SiteSetting.use_ssl? ? "https:" : "http:") + url if url.start_with?("//") + uri = (SiteSetting.use_ssl? ? "https:" : "http:") + url if url && url.start_with?("//") return unless is_valid_image_uri?(uri) # we can *always* crawl our own images return unless SiteSetting.crawl_images? || Discourse.store.has_been_uploaded?(url) diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb index 692af6d94a4..0141e371895 100644 --- a/spec/components/cooked_post_processor_spec.rb +++ b/spec/components/cooked_post_processor_spec.rb @@ -89,11 +89,6 @@ describe CookedPostProcessor do before { FastImage.stubs(:size).returns([150, 250]) } - it "doesn't call image_dimensions because it knows the size" do - cpp.expects(:image_dimensions).never - cpp.post_process_images - end - it "adds the width from the image sizes provided" do cpp.post_process_images cpp.html.should =~ /width=\"111\"/ @@ -136,7 +131,7 @@ describe CookedPostProcessor do it "generates overlay information" do cpp.post_process_images - cpp.html.should match_html '
+ cpp.html.should match_html '
uploaded.jpg1000x2000 1.21 KB
' cpp.should be_dirty @@ -202,24 +197,6 @@ describe CookedPostProcessor do end - context "image_dimensions" do - - let(:post) { build(:post) } - let(:cpp) { CookedPostProcessor.new(post) } - - it "calls the resizer" do - SiteSetting.stubs(:max_image_width).returns(200) - cpp.expects(:get_size).returns([1000, 2000]) - cpp.image_dimensions("http://foo.bar/image.png").should == [200, 400] - end - - it "doesn't call the resizer when there is no size" do - cpp.expects(:get_size).returns(nil) - cpp.image_dimensions("http://foo.bar/image.png").should == nil - end - - end - context "get_size" do let(:post) { build(:post) } diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 6a63fe5d61a..b97f6f08697 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -393,8 +393,8 @@ describe PostsController do end it "passes image_sizes through" do - PostCreator.expects(:new).with(user, has_entries('image_sizes' => 'test')).returns(post_creator) - xhr :post, :create, {raw: 'hello', image_sizes: 'test'} + PostCreator.expects(:new).with(user, has_entries('image_sizes' => {'width' => '100', 'height' => '200'})).returns(post_creator) + xhr :post, :create, {raw: 'hello', image_sizes: {width: '100', height: '200'}} end it "passes meta_data through" do diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb index f5a3dd148ee..7c812ffe3df 100644 --- a/spec/models/upload_spec.rb +++ b/spec/models/upload_spec.rb @@ -43,14 +43,14 @@ describe Upload do it "does not create a thumbnail when disabled" do SiteSetting.stubs(:create_thumbnails?).returns(false) OptimizedImage.expects(:create_for).never - upload.create_thumbnail! + upload.create_thumbnail!(100, 100) end it "does not create another thumbnail" do SiteSetting.expects(:create_thumbnails?).returns(true) upload.expects(:has_thumbnail?).returns(true) OptimizedImage.expects(:create_for).never - upload.create_thumbnail! + upload.create_thumbnail!(100, 100) end it "creates a thumbnail" do @@ -59,7 +59,7 @@ describe Upload do SiteSetting.expects(:create_thumbnails?).returns(true) upload.expects(:has_thumbnail?).returns(false) OptimizedImage.expects(:create_for).returns(thumbnail) - upload.create_thumbnail! + upload.create_thumbnail!(100, 100) upload.reload upload.optimized_images.count.should == 1 end