Merge pull request #5283 from consuldemocracy/label_links
Allow links in forms to open in new tabs
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
<%= actions.action(:show,
|
<%= actions.action(:show,
|
||||||
text: t("admin.site_customization.pages.index.see_page"),
|
text: t("admin.site_customization.pages.index.see_page"),
|
||||||
path: page.url,
|
path: page.url,
|
||||||
options: { target: "_blank" }) %>
|
target: "_blank") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -89,11 +89,7 @@
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<% unless current_user.manager? || investment.persisted? %>
|
<% unless current_user.manager? || investment.persisted? %>
|
||||||
<div>
|
<div>
|
||||||
<%= f.check_box :terms_of_service,
|
<%= render Shared::AgreeWithTermsOfServiceFieldComponent.new(f) %>
|
||||||
title: t("form.accept_terms_title"),
|
|
||||||
label: t("form.accept_terms",
|
|
||||||
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
|
|
||||||
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")) %>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
@@ -41,11 +41,7 @@
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<% if debate.new_record? %>
|
<% if debate.new_record? %>
|
||||||
<div>
|
<div>
|
||||||
<%= f.check_box :terms_of_service,
|
<%= render Shared::AgreeWithTermsOfServiceFieldComponent.new(f) %>
|
||||||
title: t("form.accept_terms_title"),
|
|
||||||
label: t("form.accept_terms",
|
|
||||||
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
|
|
||||||
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")) %>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
<%= back_link_to debates_path, t("debates.index.section_header.title") %>
|
<%= back_link_to debates_path, t("debates.index.section_header.title") %>
|
||||||
|
|
||||||
<%= header do %>
|
<%= header do %>
|
||||||
<%= link_to help_path(anchor: "debates"), title: t("shared.target_blank"), target: "_blank" do %>
|
<%= link_to t("debates.new.more_info"), help_path(anchor: "debates") %>
|
||||||
<%= t("debates.new.more_info") %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
class Debates::NewComponent < ApplicationComponent
|
class Debates::NewComponent < ApplicationComponent
|
||||||
include Header
|
include Header
|
||||||
attr_reader :debate
|
attr_reader :debate
|
||||||
|
delegate :new_window_link_to, to: :helpers
|
||||||
|
|
||||||
def initialize(debate)
|
def initialize(debate)
|
||||||
@debate = debate
|
@debate = debate
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
<p class="info">
|
<p class="info">
|
||||||
<%= sanitize(t("layouts.footer.description",
|
<%= sanitize(t("layouts.footer.description",
|
||||||
open_source: link_to(t("layouts.footer.open_source"), t("layouts.footer.open_source_url"), target: "blank", rel: "nofollow"),
|
open_source: link_to(t("layouts.footer.open_source"), t("layouts.footer.open_source_url"), target: "_blank", rel: "nofollow"),
|
||||||
consul: link_to(t("layouts.footer.consul"), t("layouts.footer.consul_url"), target: "blank", rel: "nofollow"))) %>
|
consul: link_to(t("layouts.footer.consul"), t("layouts.footer.consul_url"), target: "_blank", rel: "nofollow"))) %>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -96,11 +96,7 @@
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<% if proposal.new_record? %>
|
<% if proposal.new_record? %>
|
||||||
<div>
|
<div>
|
||||||
<%= f.check_box :terms_of_service,
|
<%= render Shared::AgreeWithTermsOfServiceFieldComponent.new(f) %>
|
||||||
title: t("form.accept_terms_title"),
|
|
||||||
label: t("form.accept_terms",
|
|
||||||
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
|
|
||||||
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")) %>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
<%= back_link_to proposals_path, t("proposals.index.section_header.title") %>
|
<%= back_link_to proposals_path, t("proposals.index.section_header.title") %>
|
||||||
|
|
||||||
<%= header do %>
|
<%= header do %>
|
||||||
<%= link_to help_path(anchor: "proposals"), title: t("shared.target_blank"), target: "_blank" do %>
|
<%= new_window_link_to t("proposals.new.more_info"), help_path(anchor: "proposals") %>
|
||||||
<%= t("proposals.new.more_info") %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
class Proposals::NewComponent < ApplicationComponent
|
class Proposals::NewComponent < ApplicationComponent
|
||||||
include Header
|
include Header
|
||||||
attr_reader :proposal
|
attr_reader :proposal
|
||||||
|
delegate :new_window_link_to, to: :helpers
|
||||||
|
|
||||||
def initialize(proposal)
|
def initialize(proposal)
|
||||||
@proposal = proposal
|
@proposal = proposal
|
||||||
|
|||||||
@@ -14,10 +14,8 @@
|
|||||||
<%= f.text_field :related_sdg_list,
|
<%= f.text_field :related_sdg_list,
|
||||||
class: "input",
|
class: "input",
|
||||||
hint: sanitize(t("sdg.related_list_selector.hint",
|
hint: sanitize(t("sdg.related_list_selector.hint",
|
||||||
link: link_to(t("sdg.related_list_selector.help.text"),
|
link: new_window_link_to(t("sdg.related_list_selector.help.text"),
|
||||||
sdg_help_path,
|
sdg_help_path)),
|
||||||
title: t("shared.target_blank"),
|
|
||||||
target: "_blank")),
|
|
||||||
attributes: %w[href title target]),
|
attributes: %w[href title target]),
|
||||||
data: { "suggestions-list": sdg_related_suggestions,
|
data: { "suggestions-list": sdg_related_suggestions,
|
||||||
"remove-tag-text": t("sdg.related_list_selector.remove_tag") } %>
|
"remove-tag-text": t("sdg.related_list_selector.remove_tag") } %>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
class SDG::RelatedListSelectorComponent < ApplicationComponent
|
class SDG::RelatedListSelectorComponent < ApplicationComponent
|
||||||
attr_reader :f
|
attr_reader :f
|
||||||
|
delegate :new_window_link_to, to: :helpers
|
||||||
|
|
||||||
def initialize(form)
|
def initialize(form)
|
||||||
@f = form
|
@f = form
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<%= form.check_box :terms_of_service, label: label %>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
class Shared::AgreeWithTermsOfServiceFieldComponent < ApplicationComponent
|
||||||
|
attr_reader :form
|
||||||
|
delegate :new_window_link_to, to: :helpers
|
||||||
|
|
||||||
|
def initialize(form)
|
||||||
|
@form = form
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def label
|
||||||
|
t("form.accept_terms",
|
||||||
|
policy: new_window_link_to(t("form.policy"), "/privacy"),
|
||||||
|
conditions: new_window_link_to(t("form.conditions"), "/conditions"))
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -30,6 +30,10 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new_window_link_to(text, path, **options)
|
||||||
|
link_to text, path, { target: "_blank", title: t("shared.target_blank") }.merge(options)
|
||||||
|
end
|
||||||
|
|
||||||
def image_path_for(filename)
|
def image_path_for(filename)
|
||||||
image = SiteCustomization::Image.image_for(filename)
|
image = SiteCustomization::Image.image_for(filename)
|
||||||
|
|
||||||
|
|||||||
@@ -62,11 +62,7 @@
|
|||||||
|
|
||||||
<div class="small-12 column">
|
<div class="small-12 column">
|
||||||
<% if @proposal.new_record? %>
|
<% if @proposal.new_record? %>
|
||||||
<%= f.check_box :terms_of_service,
|
<%= render Shared::AgreeWithTermsOfServiceFieldComponent.new(f) %>
|
||||||
title: t("form.accept_terms_title"),
|
|
||||||
label: t("form.accept_terms",
|
|
||||||
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
|
|
||||||
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")) %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -25,12 +25,9 @@
|
|||||||
label: t("devise_views.organizations.registrations.new.password_confirmation_label") %>
|
label: t("devise_views.organizations.registrations.new.password_confirmation_label") %>
|
||||||
|
|
||||||
<%= f.check_box :terms_of_service,
|
<%= f.check_box :terms_of_service,
|
||||||
title: t("devise_views.users.registrations.new.terms_title"),
|
|
||||||
label: t("devise_views.users.registrations.new.terms",
|
label: t("devise_views.users.registrations.new.terms",
|
||||||
terms: link_to(t("devise_views.users.registrations.new.terms_link"),
|
terms: new_window_link_to(t("devise_views.users.registrations.new.terms_link"),
|
||||||
"/conditions",
|
"/conditions")) %>
|
||||||
title: t("shared.target_blank"),
|
|
||||||
target: "_blank")) %>
|
|
||||||
|
|
||||||
<div class="small-12 medium-6 small-centered">
|
<div class="small-12 medium-6 small-centered">
|
||||||
<%= f.submit t("devise_views.organizations.registrations.new.submit"), class: "button expanded" %>
|
<%= f.submit t("devise_views.organizations.registrations.new.submit"), class: "button expanded" %>
|
||||||
|
|||||||
@@ -35,12 +35,9 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= f.check_box :terms_of_service,
|
<%= f.check_box :terms_of_service,
|
||||||
title: t("devise_views.users.registrations.new.terms_title"),
|
|
||||||
label: t("devise_views.users.registrations.new.terms",
|
label: t("devise_views.users.registrations.new.terms",
|
||||||
terms: link_to(t("devise_views.users.registrations.new.terms_link"),
|
terms: new_window_link_to(t("devise_views.users.registrations.new.terms_link"),
|
||||||
"/conditions",
|
"/conditions")) %>
|
||||||
title: t("shared.target_blank"),
|
|
||||||
target: "_blank")) %>
|
|
||||||
|
|
||||||
<div class="small-12 medium-6 small-centered">
|
<div class="small-12 medium-6 small-centered">
|
||||||
<%= f.submit t("devise_views.users.registrations.new.submit"), class: "button expanded" %>
|
<%= f.submit t("devise_views.users.registrations.new.submit"), class: "button expanded" %>
|
||||||
|
|||||||
@@ -69,12 +69,9 @@
|
|||||||
|
|
||||||
<div class="small-12">
|
<div class="small-12">
|
||||||
<%= f.check_box :terms_of_service,
|
<%= f.check_box :terms_of_service,
|
||||||
title: t("verification.residence.new.accept_terms_text_title"),
|
|
||||||
label: t("verification.residence.new.accept_terms_text",
|
label: t("verification.residence.new.accept_terms_text",
|
||||||
terms_url: link_to(t("verification.residence.new.terms"),
|
terms_url: new_window_link_to(t("verification.residence.new.terms"),
|
||||||
page_path("census_terms"),
|
page_path("census_terms"))) %>
|
||||||
title: t("shared.target_blank"),
|
|
||||||
target: "_blank")) %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-3 clear">
|
<div class="small-12 medium-3 clear">
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ en:
|
|||||||
submit: Register
|
submit: Register
|
||||||
terms: By registering you accept the %{terms}
|
terms: By registering you accept the %{terms}
|
||||||
terms_link: terms and conditions of use
|
terms_link: terms and conditions of use
|
||||||
terms_title: By registering you accept the terms and conditions of use
|
|
||||||
title: Register
|
title: Register
|
||||||
username_is_available: Username available
|
username_is_available: Username available
|
||||||
username_is_not_available: Username already in use
|
username_is_not_available: Username already in use
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ en:
|
|||||||
poll_ended: "Cannot be changed if voting has already ended"
|
poll_ended: "Cannot be changed if voting has already ended"
|
||||||
form:
|
form:
|
||||||
accept_terms: I agree to the %{policy} and the %{conditions}
|
accept_terms: I agree to the %{policy} and the %{conditions}
|
||||||
accept_terms_title: I agree to the Privacy Policy and the Terms and conditions of use
|
|
||||||
conditions: Terms and conditions of use
|
conditions: Terms and conditions of use
|
||||||
debate: Debate
|
debate: Debate
|
||||||
direct_message: private message
|
direct_message: private message
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ en:
|
|||||||
success: Residence verified
|
success: Residence verified
|
||||||
new:
|
new:
|
||||||
accept_terms_text: I accept %{terms_url} of the Census
|
accept_terms_text: I accept %{terms_url} of the Census
|
||||||
accept_terms_text_title: I accept the terms and conditions of access of the Census
|
|
||||||
document_number: Document number
|
document_number: Document number
|
||||||
document_number_help_title: Help
|
document_number_help_title: Help
|
||||||
document_number_help_text: "<strong>DNI</strong>: 12345678A<br> <strong>Passport</strong>: AAA000001<br> <strong>Residence card</strong>: X1234567P"
|
document_number_help_text: "<strong>DNI</strong>: 12345678A<br> <strong>Passport</strong>: AAA000001<br> <strong>Residence card</strong>: X1234567P"
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ es:
|
|||||||
submit: Registrarse
|
submit: Registrarse
|
||||||
terms: Al registrarte aceptas las %{terms}
|
terms: Al registrarte aceptas las %{terms}
|
||||||
terms_link: condiciones de uso
|
terms_link: condiciones de uso
|
||||||
terms_title: Al registrarte aceptas las condiciones de uso
|
|
||||||
title: Registrarse
|
title: Registrarse
|
||||||
username_is_available: Nombre de usuario disponible
|
username_is_available: Nombre de usuario disponible
|
||||||
username_is_not_available: Nombre de usuario ya existente
|
username_is_not_available: Nombre de usuario ya existente
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ es:
|
|||||||
poll_ended: "No puede ser cambiada si la votación ha acabado"
|
poll_ended: "No puede ser cambiada si la votación ha acabado"
|
||||||
form:
|
form:
|
||||||
accept_terms: Acepto la %{policy} y las %{conditions}
|
accept_terms: Acepto la %{policy} y las %{conditions}
|
||||||
accept_terms_title: Acepto la Política de privacidad y las Condiciones de uso
|
|
||||||
conditions: Condiciones de uso
|
conditions: Condiciones de uso
|
||||||
debate: el debate
|
debate: el debate
|
||||||
direct_message: el mensaje privado
|
direct_message: el mensaje privado
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ es:
|
|||||||
success: Residencia verificada
|
success: Residencia verificada
|
||||||
new:
|
new:
|
||||||
accept_terms_text: Acepto %{terms_url} al Padrón
|
accept_terms_text: Acepto %{terms_url} al Padrón
|
||||||
accept_terms_text_title: Acepto los términos de acceso al Padrón
|
|
||||||
document_number: Número de documento
|
document_number: Número de documento
|
||||||
document_number_help_title: Ayuda
|
document_number_help_title: Ayuda
|
||||||
document_number_help_text: "<strong>DNI</strong>: 12345678A<br> <strong>Pasaporte</strong>: AAA000001<br> <strong>Tarjeta de residencia</strong>: X1234567P"
|
document_number_help_text: "<strong>DNI</strong>: 12345678A<br> <strong>Pasaporte</strong>: AAA000001<br> <strong>Tarjeta de residencia</strong>: X1234567P"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class ConsulFormBuilder < FoundationRailsHelper::FormBuilder
|
|||||||
if options[:label] == false
|
if options[:label] == false
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
label = tag.span sanitize(label_text(attribute, options[:label])), class: "checkbox"
|
label = tag.span sanitized_label_text(attribute, options[:label]), class: "checkbox"
|
||||||
|
|
||||||
super(attribute, options.merge(
|
super(attribute, options.merge(
|
||||||
label: label,
|
label: label,
|
||||||
@@ -51,7 +51,7 @@ class ConsulFormBuilder < FoundationRailsHelper::FormBuilder
|
|||||||
if text == false
|
if text == false
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
super(attribute, sanitize(label_text(attribute, text)), options)
|
super(attribute, sanitized_label_text(attribute, text), options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -68,6 +68,14 @@ class ConsulFormBuilder < FoundationRailsHelper::FormBuilder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sanitized_label_text(attribute, text)
|
||||||
|
sanitize(label_text(attribute, text), attributes: allowed_attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_attributes
|
||||||
|
self.class.sanitized_allowed_attributes + ["target"]
|
||||||
|
end
|
||||||
|
|
||||||
def label_options_for(options)
|
def label_options_for(options)
|
||||||
label_options = options[:label_options] || {}
|
label_options = options[:label_options] || {}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Shared::AgreeWithTermsOfServiceFieldComponent do
|
||||||
|
before do
|
||||||
|
dummy_model = Class.new do
|
||||||
|
include ActiveModel::Model
|
||||||
|
attr_accessor :terms_of_service
|
||||||
|
end
|
||||||
|
|
||||||
|
stub_const("DummyModel", dummy_model)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:form) { ConsulFormBuilder.new(:dummy, DummyModel.new, ApplicationController.new.view_context, {}) }
|
||||||
|
let(:component) { Shared::AgreeWithTermsOfServiceFieldComponent.new(form) }
|
||||||
|
|
||||||
|
it "contains links that open in a new window" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page).to have_css "a[target=_blank]", count: 2
|
||||||
|
end
|
||||||
|
|
||||||
|
it "contains links indicating they open in a new window" do
|
||||||
|
render_inline component
|
||||||
|
|
||||||
|
expect(page).to have_link count: 2
|
||||||
|
expect(page).to have_link "Privacy Policy"
|
||||||
|
expect(page).to have_link "Terms and conditions of use"
|
||||||
|
expect(page).to have_link " (link opens in new window)", count: 2
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -13,6 +13,17 @@ describe ConsulFormBuilder do
|
|||||||
|
|
||||||
let(:builder) { ConsulFormBuilder.new(:dummy, DummyModel.new, ApplicationController.new.view_context, {}) }
|
let(:builder) { ConsulFormBuilder.new(:dummy, DummyModel.new, ApplicationController.new.view_context, {}) }
|
||||||
|
|
||||||
|
describe "label" do
|
||||||
|
it "accepts links that open in a new window in its content" do
|
||||||
|
render builder.text_field(:title, label: 'My <a href="/" target="_blank" title="New tab">title</a>')
|
||||||
|
|
||||||
|
expect(page).to have_link count: 1
|
||||||
|
expect(page).to have_link "title"
|
||||||
|
expect(page).to have_link "New tab"
|
||||||
|
expect(page).to have_css "a[target=_blank]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "hints" do
|
describe "hints" do
|
||||||
it "does not generate hints by default" do
|
it "does not generate hints by default" do
|
||||||
render builder.text_field(:title)
|
render builder.text_field(:title)
|
||||||
|
|||||||
@@ -164,8 +164,9 @@ describe "Residence" do
|
|||||||
login_as(create(:user))
|
login_as(create(:user))
|
||||||
|
|
||||||
visit new_residence_path
|
visit new_residence_path
|
||||||
click_link "the terms and conditions of access"
|
|
||||||
|
|
||||||
|
within_window(window_opened_by { click_link "the terms and conditions of access" }) do
|
||||||
expect(page).to have_content "Terms and conditions of access of the Census"
|
expect(page).to have_content "Terms and conditions of access of the Census"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user