Skip to content
Permalink
Browse files

Change: Promote URLs in plain text to HTML anchors in comments. (#5401)

* Change: Promote URLs in plain text to HTML anchors in comments.

* Add CHANGELOG entry

* Extract use of Anchored::Linker into a ContentProcessor
  • Loading branch information...
aitorlb authored and oriolgual committed Oct 7, 2019
1 parent 080a4c7 commit b0e3598f7dce275a2507a7eda2d810831f7e107e
@@ -28,6 +28,7 @@

**Changed**:

- **decidim-comments**: Change: Promote URLs in plain text to HTML anchors in comments.[\#5401](https://github.com/decidim/decidim/pull/5401)
- **decidim-core**: Promote URLs in plain text to HTML anchors after strip_tags. [\#5341](https://github.com/decidim/decidim/pull/5341)
- **decidim-accountability**, **decidim-assemblies**, **decidim-consultations**, **decidim-core**, **decidim-proposals**, **decidim-debates**, **decidim-dev**, **decidim-generators**, **decidim-initiatives**, **decidim-meetings**, **decidim-participatory_processes**, **decidim-proposals**, **decidim-sortitions**, **decidim_app-design**: Change: social share button default sites [\#5270](https://github.com/decidim/decidim/pull/5270)
- **decidim-core**: Changes default format date [#5330](https://github.com/decidim/decidim/pull/5330)
@@ -114,7 +114,8 @@ module Comments
end

describe "#formatted_body" do
let(:comment) { create(:comment, commentable: commentable, author: author, body: "<b>bold text</b> *lorem* <a href='https://example.com'>link</a>") }
let(:comment) { create(:comment, commentable: commentable, author: author, body: body) }
let(:body) { "<b>bold text</b> *lorem* <a href='https://example.com'>link</a>" }

before do
allow(Decidim).to receive(:content_processors).and_return([:dummy_foo])
@@ -133,6 +134,21 @@ module Comments
it "returns the body sanitized and processed" do
expect(comment.formatted_body).to eq("<p>bold text <em>neque dicta enim quasi</em> link</p>")
end

describe "when the body contains urls" do
before { allow(Decidim).to receive(:content_processors).and_return([:link]) }

let(:body) do
%(Content with <a href="http://urls.net" onmouseover="alert('hello')">URLs</a> of anchor type and text urls like https://decidim.org. And a malicous <a href="javascript:document.cookies">click me</a>)
end
let(:result) do
%(<p>Content with URLs of anchor type and text urls like <a href="https://decidim.org" target="_blank" rel="noopener">https://decidim.org</a>. And a malicous click me</p>)
end

it "converts all URLs to links and strips attributes in anchors" do
expect(comment.formatted_body).to eq(result)
end
end
end

describe "#comment_threads count" do
@@ -6,5 +6,6 @@ module ContentParsers
autoload :UserParser, "decidim/content_parsers/user_parser"
autoload :HashtagParser, "decidim/content_parsers/hashtag_parser"
autoload :NewlineParser, "decidim/content_parsers/newline_parser"
autoload :LinkParser, "decidim/content_parsers/link_parser"
end
end
@@ -0,0 +1,10 @@
# frozen_string_literal: true

module Decidim
module ContentParsers
# As recommended here: decidim-core/lib/decidim/content_processor.rb
# We are declaring the class and leaving it empty as we only want the renderer.
class LinkParser < BaseParser
end
end
end
@@ -5,5 +5,6 @@ module ContentRenderers
autoload :BaseRenderer, "decidim/content_renderers/base_renderer"
autoload :UserRenderer, "decidim/content_renderers/user_renderer"
autoload :HashtagRenderer, "decidim/content_renderers/hashtag_renderer"
autoload :LinkRenderer, "decidim/content_renderers/link_renderer"
end
end
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module Decidim
module ContentRenderers
# A renderer that converts URLs to links and strips attributes in anchors.
#
# Examples:
# `<a href="http://urls.net" onmouseover="alert('hello')">URLs</a>`
# Gets rendered as:
# `<a href="https://decidim.org" target="_blank" rel="noopener">https://decidim.org</a>`
# And:
# `<a href="javascript:document.cookies">click me</a>`
# Gets rendered as:
# `click me`
#
# @see BaseRenderer Examples of how to use a content renderer
class LinkRenderer < BaseRenderer
# @return [String] the content ready to display (contains HTML)
def render(options = { target: "_blank", rel: "noopener" })
Anchored::Linker.auto_link(content, options)
end
end
end
end
@@ -191,7 +191,7 @@ class Engine < ::Rails::Engine

initializer "decidim.content_processors" do |_app|
Decidim.configure do |config|
config.content_processors += [:user, :hashtag]
config.content_processors += [:user, :hashtag, :link]
end
end

@@ -43,7 +43,7 @@ def body(links: false, extras: true, strip_tags: false)
renderer = Decidim::ContentRenderers::HashtagRenderer.new(text)
text = renderer.render(links: links, extras: extras).html_safe

text = Anchored::Linker.auto_link(text, target: "_blank", rel: "noopener") if links
text = Decidim::ContentRenderers::LinkRenderer.new(text).render if links
text
end
end
@@ -59,7 +59,7 @@ def body(links: false, extras: true, strip_tags: false)
renderer = Decidim::ContentRenderers::HashtagRenderer.new(text)
text = renderer.render(links: links, extras: extras).html_safe

text = Anchored::Linker.auto_link(text, target: "_blank", rel: "noopener") if links
text = Decidim::ContentRenderers::LinkRenderer.new(text).render if links
text
end
end

0 comments on commit b0e3598

Please sign in to comment.
You can’t perform that action at this time.