Merge branch 'master' of https://github.com/biosistemika/scinote-web into zd_SCI_939

This commit is contained in:
zmagod 2017-01-27 11:15:31 +01:00
commit e59b2e039a
36 changed files with 147 additions and 208 deletions

View file

@ -5,14 +5,6 @@ GIT
sneaky-save (0.1.1)
activerecord (>= 3.2.0)
GIT
remote: https://github.com/biosistemika/quill-rails.git
revision: e765c042d9ff7ec22f8c51a0e08e39e783530f8b
ref: e765c04
specs:
quill-rails (0.1.4)
railties (>= 3.1.0, < 5.0)
GEM
remote: http://rubygems.org/
specs:
@ -79,6 +71,7 @@ GEM
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
execjs (~> 2.0)
base62 (1.0.0)
bcrypt (3.1.11)
better_errors (2.1.1)
coderay (>= 1.0.0)
@ -314,6 +307,8 @@ GEM
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.1)
tinymce-rails (4.5.2)
railties (>= 3.1.1)
turbolinks (2.5.3)
coffee-rails
tzinfo (1.2.2)
@ -347,6 +342,7 @@ DEPENDENCIES
awesome_print
aws-sdk (~> 2.2.8)
aws-sdk-v1
base62
bcrypt (~> 3.1.10)
better_errors
binding_of_caller
@ -382,7 +378,6 @@ DEPENDENCIES
paperclip (~> 4.3)
pg
puma
quill-rails!
rails (= 4.2.5)
rails_12factor
rails_autolink (~> 1.1, >= 1.1.6)
@ -392,6 +387,7 @@ DEPENDENCIES
roo (~> 2.1.0)
rubocop
ruby-graphviz (~> 1.2)
rubyzip
sass-rails (~> 5.0)
scss_lint
sdoc (~> 0.4.0)
@ -402,6 +398,7 @@ DEPENDENCIES
sneaky-save!
spinjs-rails
starscope
tinymce-rails
turbolinks
tzinfo-data
uglifier (>= 1.3.0)

View file

@ -107,7 +107,7 @@ function applyEditCallBack() {
animateSpinner(null, false);
initPreviewModal();
TinyMCE.init();
TinyMCE.refresh()
$("#new-step-checklists fieldset.nested_step_checklists ul").each(function () {
enableCheckboxSorting(this);
});
@ -254,9 +254,6 @@ function formNewAjax($form) {
initHandsOnTable($new_step);
expandStep($new_step);
toggleButtons(true);
TinyMCE.init();
TinyMCE.highlight();
SmartAnnotation.preventPropagation('.atwho-user-popover');
//Rerender tables

View file

@ -10,10 +10,8 @@ $("#new-result-text").on("ajax:success", function(e, data) {
$form.remove();
toggleResultEditButtons(true);
});
TinyMCE.init();
toggleResultEditButtons(false);
TinyMCE.refresh();
$("#result_name").focus();
});
@ -39,10 +37,8 @@ function applyEditResultTextCallback() {
applyEditResultTextCallback();
toggleResultEditButtons(true);
});
TinyMCE.init();
toggleResultEditButtons(false);
TinyMCE.refresh();
$("#result_name").focus();
});

View file

@ -162,6 +162,7 @@ function dataTableInit() {
table.on('mousedown', function() {
$('#samples-columns-dropdown').removeClass('open');
});
initHeaderTooltip();
}
});
@ -350,6 +351,34 @@ function appendSamplesIdToForm(form) {
});
}
function initHeaderTooltip() {
// Fix compatibility of fixed table header and column names modal-tooltip
$('.modal-tooltip').off();
$('.modal-tooltip').hover(function() {
var $tooltip = $(this).find('.modal-tooltiptext');
var offsetLeft = $tooltip.offset().left;
(offsetLeft + 200) > $(window).width() ? offsetLeft -= 150 : offsetLeft;
var offsetTop = $tooltip.offset().top;
$('body').append($tooltip);
$tooltip.css('background-color', '#d2d2d2');
$tooltip.css('border-radius', '6px');
$tooltip.css('color', '#333');
$tooltip.css('display', 'block');
$tooltip.css('left', offsetLeft + 'px');
$tooltip.css('padding', '5px');
$tooltip.css('position', 'absolute');
$tooltip.css('text-align', 'center');
$tooltip.css('top', offsetTop + 'px');
$tooltip.css('visibility', 'visible');
$tooltip.css('width', '200px');
$tooltip.css('word-wrap', 'break-word');
$(this).data('dropdown-tooltip', $tooltip);
}, function() {
$(this).append($(this).data('dropdown-tooltip'));
$(this).data('dropdown-tooltip').removeAttr('style');
});
}
//Show sample info
function sampleInfoListener() {
$(".sample_info").on("click", function(e){
@ -1076,6 +1105,7 @@ function changeToEditMode() {
li.removeClass('col-invisible');
column.visible(true);
table.setColumnSearchable(column.index(), true);
initHeaderTooltip();
}
// Re-filter/search if neccesary
@ -1135,6 +1165,7 @@ function changeToEditMode() {
.html(generateColumnNameTooltip(newName));
cancelEditMode();
initHeaderTooltip();
},
error: function(xhr) {
dropdownList.sortable('disable');

View file

@ -336,11 +336,11 @@ var SmartAnnotation = (function() {
{query: query},
function(data) {
if (data.users.length < 1) {
callback([{no_results: 1}]);
} else {
callback(data.users);
}
initDismissButton();
callback([{no_results: 1}]);
} else {
callback(data.users);
}
initDismissButton($('.atwho-view[style]'));
}
);
},

View file

@ -20,11 +20,15 @@ var TinyMCE = (function() {
tinyMCE.init({
selector: "textarea.tinymce",
toolbar: ["undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link | forecolor backcolor | codesample"],
plugins: "link,advlist,codesample,autolink,lists,charmap,hr,anchor,searchreplace,wordcount,visualblocks,visualchars,insertdatetime,nonbreaking,save,contextmenu,directionality,paste,textcolor,colorpicker,textpattern,imagetools,toc",
plugins: "link,advlist,codesample,autolink,lists,charmap,hr,anchor,searchreplace,wordcount,visualblocks,visualchars,insertdatetime,nonbreaking,save,contextmenu,directionality,paste,textcolor,colorpicker,textpattern,imagetools",
codesample_languages: [{"text":"R","value":"r"},{"text":"MATLAB","value":"matlab"},{"text":"Python","value":"python"},{"text":"JSON","value":"javascript"},{"text":"HTML/XML","value":"markup"},{"text":"JavaScript","value":"javascript"},{"text":"CSS","value":"css"},{"text":"PHP","value":"php"},{"text":"Ruby","value":"ruby"},{"text":"Java","value":"java"},{"text":"C","value":"c"},{"text":"C#","value":"csharp"},{"text":"C++","value":"cpp"}],
removed_menuitems: 'newdocument',
elementpath: false,
default_link_target: "_blank",
target_list: [
{title: 'New page', value: '_blank'},
{title: 'Same page', value: '_self'}
],
style_formats: [
{title: 'Headers', items: [
{title: 'Header 1', format: 'h1'},
@ -59,7 +63,7 @@ var TinyMCE = (function() {
initHighlightjsIframe($(this.iframeElement).contents());
},
setup: function(editor) {
editor.on('Change', function(e) {
editor.on('keydown', function(e) {
if(e.keyCode == 13 && $(editor.contentDocument.activeElement).atwho('isSelecting')) {
return false;
}

View file

@ -15,8 +15,9 @@ class AtWhoController < ApplicationController
user_obj['full_name'] =
user_obj['full_name']
.truncate(Constants::NAME_TRUNCATION_LENGTH_DROPDOWN)
user_obj['id'] = user_obj['id'].base62_encode
user_obj['img_url'] = avatar_path(user_obj['id'], :icon_small)
id = user_obj['id']
user_obj['id'] = id.base62_encode
user_obj['img_url'] = avatar_path(id, :icon_small)
end
respond_to do |format|

View file

@ -116,14 +116,7 @@ class MyModuleCommentsController < ApplicationController
module: @my_module.name
)
)
message = auto_link(
smart_annotation_parser(
simple_format(sanitize_input(@comment.message))
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe
message = custom_auto_link(@comment.message)
render json: { comment: message }, status: :ok
else
render json: { errors: @comment.errors.to_hash(true) },

View file

@ -113,14 +113,7 @@ class ProjectCommentsController < ApplicationController
project: @project.name
)
)
message = auto_link(
smart_annotation_parser(
simple_format(sanitize_input(@comment.message))
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe
message = custom_auto_link(@comment.message)
render json: { comment: message }, status: :ok
else
render json: { errors: @comment.errors.to_hash(true) },

View file

@ -114,14 +114,7 @@ class ResultCommentsController < ApplicationController
result: @result.name
)
)
message = auto_link(
smart_annotation_parser(
simple_format(sanitize_input(@comment.message))
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
)
message = custom_auto_link(@comment.message)
render json: { comment: message }, status: :ok
else
render json: { errors: @comment.errors.to_hash(true) },

View file

@ -11,12 +11,18 @@ class SamplesController < ApplicationController
respond_to do |format|
format.html
if can_create_samples(@team)
format.json {
render json: {
sample_groups: @team.sample_groups.as_json(only: [:id, :name, :color]),
sample_types: @team.sample_types.as_json(only: [:id, :name])
}
}
groups = @team.sample_groups.map do |g|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
end
types = @team.sample_types.map do |t|
{ id: t.id, name: sanitize_input(t.name) }
end
format.json do
render json: {
sample_groups: groups.as_json,
sample_types: types.as_json
}
end
else
format.json { render json: {}, status: :unauthorized }
end
@ -122,8 +128,12 @@ class SamplesController < ApplicationController
sample_group: @sample.sample_group.nil? ? "" : @sample.sample_group.id,
custom_fields: {}
},
sample_groups: @team.sample_groups.as_json(only: [:id, :name, :color]),
sample_types: @team.sample_types.as_json(only: [:id, :name])
sample_groups: @team.sample_groups.map do |g|
{ id: g.id, name: sanitize_input(g.name), color: g.color }
end,
sample_types: @team.sample_types.map do |t|
{ id: t.id, name: sanitize_input(t.name) }
end
}
# Add custom fields ids as key (easier lookup on js side)

View file

@ -119,14 +119,7 @@ class StepCommentsController < ApplicationController
)
)
end
message = auto_link(
smart_annotation_parser(
simple_format(sanitize_input(@comment.message))
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe
message = custom_auto_link(@comment.message)
render json: { comment: message }, status: :ok
else
render json: { errors: @comment.errors.to_hash(true) },

View file

@ -129,15 +129,9 @@ class SampleDatatable < AjaxDatatablesRails::Base
# Add custom attributes
record.sample_custom_fields.each do |scf|
sample[@cf_mappings[scf.custom_field_id]] = auto_link(
smart_annotation_parser(
simple_format(sanitize_input(scf.value)),
@team
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe
sample[@cf_mappings[scf.custom_field_id]] = custom_auto_link(scf.value,
true,
@team)
end
sample
end

View file

@ -77,7 +77,7 @@ module ApplicationHelper
if project.archived?
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to project.name,
projects_archive_path} #{t'atwho.res.archived'}"
projects_archive_path} #{I18n.t('atwho.res.archived')}"
else
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to project.name,
@ -90,7 +90,7 @@ module ApplicationHelper
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to experiment.name,
experiment_archive_project_path(experiment.project)} " \
"#{t'atwho.res.archived'}"
"#{I18n.t('atwho.res.archived')}"
else
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to experiment.name,
@ -103,7 +103,7 @@ module ApplicationHelper
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to my_module.name,
module_archive_experiment_path(my_module.experiment)} " \
"#{t'atwho.res.archived'}"
"#{I18n.t('atwho.res.archived')}"
else
"<span class='sa-type'>#{sanitize(match[2])}</span> " \
"#{link_to my_module.name,
@ -118,7 +118,7 @@ module ApplicationHelper
class: 'sample-info-link')}"
else
"<span class='glyphicon glyphicon-tint'></span> " \
"#{match[1]} #{t'atwho.res.deleted'}"
"#{match[1]} #{I18n.t('atwho.res.deleted')}"
end
end
end

View file

@ -11,7 +11,7 @@ module FormTagHelper
res << '</span>'
end
res << '</div>'
sanitize_input(res)
res.html_safe
end
end
end

View file

@ -1,9 +1,13 @@
module InputSanitizeHelper
def sanitize_input(text)
def sanitize_input(
text,
tags = [],
attributes = []
)
ActionController::Base.helpers.sanitize(
text,
tags: Constants::WHITELISTED_TAGS,
attributes: Constants::WHITELISTED_ATTRIBUTES
tags: Constants::WHITELISTED_TAGS + tags,
attributes: Constants::WHITELISTED_ATTRIBUTES + attributes
)
end
@ -11,8 +15,17 @@ module InputSanitizeHelper
ERB::Util.html_escape(text)
end
def custom_auto_link(text, args)
args[:sanitize] = false
auto_link(sanitize_input(text), args)
def custom_auto_link(text, simple_format = true, org = nil)
text = if simple_format
simple_format(sanitize_input(text))
else
sanitize_input(text)
end
auto_link(
smart_annotation_parser(text, org),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe
end
end

View file

@ -94,9 +94,9 @@ module ProtocolsExporter
checklist_xml = "<checklist id=\"#{checklist.id}\" " \
"guid=\"#{get_guid(checklist.id)}\">\n"
checklist_xml << "<name>#{checklist.name}</name>\n"
if checklist.items
if checklist.checklist_items
checklist_xml << "<items>\n"
checklist.items.each do |item|
checklist.checklist_items.each do |item|
item_xml = "<item id=\"#{item.id}\" " \
"guid=\"#{get_guid(item.id)}\" " \
"position=\"#{item.position}\">\n"

View file

@ -39,12 +39,5 @@
</div>
<strong><%= comment.user.full_name %>:</strong>
<div data-role="comment-message-container">
<div data-role="comment-message"><%= auto_link(
smart_annotation_parser(simple_format(
sanitize_input(comment.message)),
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %></div>
<div data-role="comment-message"><%= custom_auto_link(comment.message) %></div>
</div>

View file

@ -1,6 +1,5 @@
<% if @my_module.description.blank? %>
<em><%=t "experiments.canvas.popups.no_description" %></em>
<% else %>
<%= custom_auto_link(simple_format(@my_module.description),
link: :urls, html: { target: '_blank' }) %>
<%= custom_auto_link(@my_module.description) %>
<% end %>

View file

@ -39,12 +39,5 @@
</div>
<strong><%= comment.user.full_name %>:</strong>
<div data-role="comment-message-container">
<div data-role="comment-message"><%= auto_link(
smart_annotation_parser(simple_format(
sanitize_input(comment.message)),
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %></div>
<div data-role="comment-message"><%= custom_auto_link(comment.message) %></div>
</div>

View file

@ -67,14 +67,7 @@
</div>
<div class="row">
<div class="col-xs-12">
<%= auto_link(
smart_annotation_parser(
simple_format(experiment.description)
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %>
<%= custom_auto_link(experiment.description) %>
</div>
</div>
</div>

View file

@ -49,16 +49,7 @@
</span>
<% if experiment.description? %>
<div class='experiment-description'>
<%= auto_link(
smart_annotation_parser(
simple_format(
sanitize_input(experiment.description)
)
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %>
<%= custom_auto_link(experiment.description) %>
</div>
<% else %>
<span class='experiment-no-description'>

View file

@ -113,13 +113,24 @@
<% assets.each do |asset| %>
<li>
<% if can_view_or_download_step_assets(@protocol) %>
<%= link_to download_asset_path(asset), data: {no_turbolink: true, id: true, status: "asset-present"} do %>
<%= image_tag preview_asset_path(asset) if asset.is_image? %>
<p><%= truncate(asset.file_file_name,
length: Constants::FILENAME_TRUNCATION_LENGTH) %></p>
<% if asset.is_image? %>
<%= link_to download_asset_path(asset),
class: 'image-preview-link',
id: "modal_link#{asset.id}",
data: {no_turbolink: true, id: true, status: "asset-present",
description: "#{step.position + 1}. #{truncate(step.name, length: Constants::FILENAME_TRUNCATION_LENGTH)}"} do %>
<%= image_tag asset.url(:medium), data: {'preview-url': large_image_url_asset_path(asset)} %>
<p><%= truncate(asset.file_file_name,
length: Constants::FILENAME_TRUNCATION_LENGTH) %></p>
<% end %>
<% else %>
<%= link_to download_asset_path(asset), data: {no_turbolink: true} do %>
<p><%= truncate(asset.file_file_name,
length: Constants::FILENAME_TRUNCATION_LENGTH) %></p>
<% end %>
<% end %>
<% else %>
<%= image_tag preview_asset_path(asset) if asset.is_image? %>
<%= image_tag asset.url(:medium) if asset.is_image? %>
<p><%= truncate(asset.file_file_name,
length: Constants::FILENAME_TRUNCATION_LENGTH) %></p>
<% end %>

View file

@ -27,10 +27,7 @@
<div class="row">
<div class="col-xs-12">
<% if experiment.description.present? %>
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(experiment.description))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(experiment.description) %>
<% else %>
<em><%=t "projects.reports.elements.experiment.no_description" %></em>
<% end %>

View file

@ -30,8 +30,7 @@
<div class="row">
<div class="col-xs-12">
<% if my_module.description.present? %>
<%= custom_auto_link(simple_format(my_module.description),
link: :urls, html: { target: '_blank' }) %>
<%= custom_auto_link(my_module.description) %>
<% else %>
<em><%=t "projects.reports.elements.module.no_description" %></em>
<% end %>

View file

@ -31,10 +31,7 @@
</span>
<span class="comment-message">
&nbsp;
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(comment.message))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(comment.message) %>
</span>
</li>
<% end %>

View file

@ -23,10 +23,7 @@
<div class="report-element-body">
<div class="row">
<div class="col-xs-12 text-container ql-editor">
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(result_text.text))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(result_text.text, false) %>
</div>
</div>
</div>

View file

@ -8,10 +8,7 @@
<span class="glyphicon glyphicon-list"></span>
</div>
<div class="pull-left checklist-name">
<%= auto_link(smart_annotation_parser(simple_format(t 'projects.reports.elements.step_checklist.checklist_name', name: checklist.name)),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(t('projects.reports.elements.step_checklist.checklist_name', name: checklist.name)) %>
</div>
<div class="pull-left user-time">
<%=t 'projects.reports.elements.step_checklist.user_time', timestamp: l(timestamp, format: :full) %>
@ -27,10 +24,8 @@
<li>
<input type="checkbox" disabled="disabled" <%= "checked='checked'" if item.checked %>/>
<span class="<%= 'checked' if item.checked %>">
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(item.text))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %></span>
<%= custom_auto_link(item.text) %>
</span>
</li>
<% end %>
</ul>

View file

@ -31,10 +31,7 @@
</span>
<span class="comment-message">
&nbsp;
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(comment.message))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(comment.message) %>
</span>
</li>
<% end %>

View file

@ -27,10 +27,7 @@
<div class="row">
<div class="col-xs-12 ql-editor">
<% if strip_tags(step.description).present? %>
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(step.description))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(step.description, false) %>
<% else %>
<em><%=t "projects.reports.elements.step.no_description" %></em>
<% end %>

View file

@ -9,7 +9,8 @@
</head>
<body class="print-report-body">
<div class="print-report">
<%= sanitize_input(@html) %>
<% # Also whitelist <img> and <input type="checkbox"> tags %>
<%= sanitize_input(@html, ['img', 'input'], ['type', 'disabled', 'checked']) %>
</div>
</body>
</html>

View file

@ -39,12 +39,5 @@
<% end %>
</div>
<div data-role="comment-message-container">
<div data-role="comment-message"><%= auto_link(
smart_annotation_parser(simple_format(
sanitize_input(comment.message)),
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %></div>
<div data-role="comment-message"><%= custom_auto_link(comment.message) %></div>
</div>

View file

@ -1,6 +1,3 @@
<div class="ql-editor">
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(result.result_text.text))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(result.result_text.text, false) %>
</div>

View file

@ -1,4 +1,4 @@
f<div>
<div>
<strong>
<%=t "protocols.steps.comment_title", user: comment.user.full_name, time: l(comment.created_at, format: :time) %>
</strong>
@ -40,12 +40,5 @@ f<div>
<% end %>
</div>
<div data-role="comment-message-container">
<div data-role="comment-message"><%= auto_link(
smart_annotation_parser(simple_format(
sanitize_input(comment.message)),
),
link: :urls,
sanitize: false,
html: { target: '_blank' }
).html_safe %></div>
<div data-role="comment-message"><%= custom_auto_link(comment.message)%></div>
</div>

View file

@ -37,10 +37,7 @@
<em><%= t("protocols.steps.no_description") %></em>
<% else %>
<div class="ql-editor">
<%= auto_link(smart_annotation_parser(simple_format(sanitize_input(step.description))),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(step.description, false) %>
</div>
<% end %>
</div>
@ -51,7 +48,7 @@
<div class="col-xs-12">
<% step.tables.each do |table| %>
<strong>
<%= custom_auto_link(simple_format(table.name),
<%= auto_link(simple_format(table.name),
link: :urls,
html: { target: '_blank' }) %>
</strong>
@ -122,15 +119,7 @@
<% unless step.checklists.blank? then %>
<div class="col-xs-12">
<% step.checklists.each do |checklist| %>
<strong><%= auto_link(
smart_annotation_parser(
simple_format(
sanitize_input(checklist.name)
)
),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %></strong>
<strong><%= custom_auto_link(checklist.name) %></strong>
<% if checklist.checklist_items.empty? %>
</br>
<%= t("protocols.steps.empty_checklist") %>
@ -144,15 +133,7 @@
<% else %>
<input type="checkbox" value="" disabled="disabled" />
<% end %>
<%= auto_link(
smart_annotation_parser(
simple_format(
sanitize_input(checklist_item.text)
)
),
link: :urls,
sanitize: false,
html: { target: '_blank' }).html_safe %>
<%= custom_auto_link(checklist_item.text) %>
</label>
</div>
<% end %>

View file

@ -190,7 +190,7 @@ class Constants
#=============================================================================
# Application version
APP_VERSION = '1.6.1'.freeze
APP_VERSION = '1.7.1'.freeze
TEXT_EXTRACT_FILE_TYPES = [
'application/pdf',
@ -213,7 +213,7 @@ class Constants
WHITELISTED_TAGS = %w(
a b strong i em li ul ol h1 del ins h2 h3 h4 h5 h6 br sub sup p code hr div
span u s blockquote pre
span u s blockquote pre col colgroup table thead tbody th tr td
).freeze
WHITELISTED_ATTRIBUTES = %w(