diff --git a/Changelog.md b/Changelog.md index 609ff5db9..c4d31b6d4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,7 @@ This release recommends using Ruby 2.2, while retaining Ruby 2.1 as an officiall Ruby 2.0 is no longer officially supported. ## Refactor +* Improve bookmarklet [#5904](https://github.com/diaspora/diaspora/pull/5904) ## Bug fixes * Destroy Participation when removing interactions with a post [#5852](https://github.com/diaspora/diaspora/pull/5852) diff --git a/app/assets/javascripts/app/views/bookmarklet_view.js b/app/assets/javascripts/app/views/bookmarklet_view.js index c8e982fc3..71b505edd 100644 --- a/app/assets/javascripts/app/views/bookmarklet_view.js +++ b/app/assets/javascripts/app/views/bookmarklet_view.js @@ -1,7 +1,7 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later app.views.Bookmarklet = Backbone.View.extend({ - separator: ' - ', + separator: "\n\n", initialize: function(opts) { // init a standalone publisher @@ -25,8 +25,12 @@ app.views.Bookmarklet = Backbone.View.extend({ var p = this.param_contents; if( p.content ) return p.content; - var contents = p.title + this.separator + p.url; - if( p.notes ) contents += this.separator + p.notes; + var contents = "### " + p.title + this.separator; + if( p.notes ) { + var notes = p.notes.toString().replace(/(?:\r\n|\r|\n)/g, "\n> "); + contents += "> " + notes + this.separator; + } + contents += p.url; return contents; }, diff --git a/app/assets/javascripts/bookmarklet.js b/app/assets/javascripts/bookmarklet.js new file mode 100644 index 000000000..1a9ac7117 --- /dev/null +++ b/app/assets/javascripts/bookmarklet.js @@ -0,0 +1,45 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later + +var bookmarklet = function(url, width, height, opts) { + // calculate popup dimensions & placement + var dim = function() { + var w = window, + winTop = (w.screenTop ? w.screenTop : w.screenY), + winLeft = (w.screenLeft ? w.screenLeft : w.screenX), + top = (winTop + (w.innerHeight / 2) - (height / 2)), + left = (winLeft + (w.innerWidth / 2) - (width / 2)); + return "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left; + }; + + // prepare url parameters + var params = function() { + var w = window, + d = document, + href = w.location.href, + title = d.title, + sel = w.getSelection ? w.getSelection() : + d.getSelection ? d.getSelection() : + d.selection.createRange().text, + notes = sel.toString(); + return "url=" + encodeURIComponent(href) + + "&title=" + encodeURIComponent(title) + + "¬es=" + encodeURIComponent(notes); + }; + + // popup (or redirect) action + var act = function() { + var popupOpts = (opts || "location=yes,links=no,scrollbars=yes,toolbar=no"), + jumpUrl = url + "?jump=yes"; + + (window.open(url + "?" + params(), "diaspora_bookmarklet", popupOpts + "," + dim()) || + (window.location.href = jumpUrl + "&" + params())); + }; + + if( /Firefox/.test(navigator.userAgent) ) { + setTimeout(act, 0); + } else { + act(); + } +}; + +// @license-end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e0952ff4c..2e55122e4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,8 +25,10 @@ module ApplicationHelper timeago_tag(time, options.merge(:class => 'timeago', :title => time.iso8601, :force => true)) if time end - def bookmarklet_url( height = 400, width = 620) - "javascript:(function(){f='#{AppConfig.pod_uri.to_s}bookmarklet?url='+encodeURIComponent(window.location.href)+'&title='+encodeURIComponent(document.title)+'¬es='+encodeURIComponent(''+(window.getSelection?window.getSelection():document.getSelection?document.getSelection():document.selection.createRange().text))+'&v=1&';a=function(){if(!window.open(f+'noui=1&jump=doclose','diasporav1','location=yes,links=no,scrollbars=yes,toolbar=no,width=#{width},height=#{height}'))location.href=f+'jump=yes'};if(/Firefox/.test(navigator.userAgent)){setTimeout(a,0)}else{a()}})()" + def bookmarklet_code(height=400, width=620) + "javascript:" + + BookmarkletRenderer.body + + "bookmarklet('#{bookmarklet_url}', #{width}, #{height});" end def contacts_link diff --git a/app/views/shared/_right_sections.html.haml b/app/views/shared/_right_sections.html.haml index fb64a3e83..b57e7fc62 100644 --- a/app/views/shared/_right_sections.html.haml +++ b/app/views/shared/_right_sections.html.haml @@ -66,7 +66,7 @@ %i.entypo.bookmark = t('bookmarklet.heading') .content - != t('bookmarklet.explanation', :link => link_to(t('bookmarklet.post_something'), bookmarklet_url)) + != t('bookmarklet.explanation', :link => link_to(t('bookmarklet.post_something'), bookmarklet_code)) - if AppConfig.settings.paypal_donations.enable? || AppConfig.bitcoin_donation_address .section diff --git a/lib/bookmarklet_renderer.rb b/lib/bookmarklet_renderer.rb new file mode 100644 index 000000000..b45fb7dbf --- /dev/null +++ b/lib/bookmarklet_renderer.rb @@ -0,0 +1,27 @@ + +class BookmarkletRenderer + class << self + def cached_name + @cached ||= File.join(Rails.application.config.paths["tmp"].first, "cache", "bookmarklet.cached") + end + + def source_name + @source ||= Rails.application.assets["bookmarklet.js"].pathname.to_s + end + + def body + if !File.exist?(cached_name) && Rails.env.production? + raise "please run the Rake task to compile the bookmarklet: `bundle exec rake assets:uglify_bookmarklet`" + end + + compile unless Rails.env.production? # don't make me re-run rake in development + @body ||= File.read(cached_name) + end + + def compile + src = File.read(source_name) + @body = Uglifier.compile(src) + File.open(cached_name, "w") {|f| f.write(@body) } + end + end +end diff --git a/lib/error_page_renderer.rb b/lib/error_page_renderer.rb new file mode 100644 index 000000000..dae92f419 --- /dev/null +++ b/lib/error_page_renderer.rb @@ -0,0 +1,47 @@ + +# Inspired by https://github.com/route/errgent/blob/master/lib/errgent/renderer.rb +class ErrorPageRenderer + def initialize options={} + @codes = options.fetch :codes, [404, 500] + @output = options.fetch :output, "public/%s.html" + @vars = options.fetch :vars, {} + @template = options.fetch :template, "errors/error_%s" + @layout = options.fetch :layout, "layouts/error_page" + end + + def render + @codes.each do |code| + view = build_action_view + view.assign @vars.merge(code: code) + path = Rails.root.join(@output % code) + File.write path, view.render(template: @template % code, layout: @layout) + end + end + + def helpers(&block) + @helpers = block + end + + private + + def build_action_view + paths = ::ActionController::Base.view_paths + ::ActionView::Base.new(paths).tap do |view| + view.class_eval do + include Rails.application.helpers + include Rails.application.routes.url_helpers + end + view.assets_manifest = build_manifest(Rails.application) + view.class_eval(&@helpers) if @helpers + end + end + + # Internal API from the sprocket-rails railtie, if somebody finds a way to + # call it, please replace it. Might need to be updated on sprocket-rails + # updates. + def build_manifest(app) + config = app.config + path = File.join(config.paths['public'].first, config.assets.prefix) + Sprockets::Manifest.new(app.assets, path, config.assets.manifest) + end +end diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index cc84fbf97..efee85b60 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -1,49 +1,3 @@ -# Inspired by https://github.com/route/errgent/blob/master/lib/errgent/renderer.rb -class ErrorPageRenderer - def initialize options={} - @codes = options.fetch :codes, [404, 500] - @output = options.fetch :output, "public/%s.html" - @vars = options.fetch :vars, {} - @template = options.fetch :template, "errors/error_%s" - @layout = options.fetch :layout, "layouts/error_page" - end - - def render - @codes.each do |code| - view = build_action_view - view.assign @vars.merge(code: code) - path = Rails.root.join(@output % code) - File.write path, view.render(template: @template % code, layout: @layout) - end - end - - def helpers(&block) - @helpers = block - end - - private - - def build_action_view - paths = ::ActionController::Base.view_paths - ::ActionView::Base.new(paths).tap do |view| - view.class_eval do - include Rails.application.helpers - include Rails.application.routes.url_helpers - end - view.assets_manifest = build_manifest(Rails.application) - view.class_eval(&@helpers) if @helpers - end - end - - # Internal API from the sprocket-rails railtie, if somebody finds a way to - # call it, please replace it. Might need to be updated on sprocket-rails - # updates. - def build_manifest(app) - config = app.config - path = File.join(config.paths['public'].first, config.assets.prefix) - Sprockets::Manifest.new(app.assets, path, config.assets.manifest) - end -end namespace :assets do desc "Generate error pages" @@ -52,8 +6,14 @@ namespace :assets do renderer.render end + desc "Uglify bookmarklet snippet" + task :uglify_bookmarklet => :environment do + BookmarkletRenderer.compile + end + # Augment precompile with error page generation task :precompile do Rake::Task['assets:generate_error_pages'].invoke + Rake::Task['assets:uglify_bookmarklet'].invoke end end