Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HYC-1003 - Text Formatting for Abstracts #1123

Merged
merged 12 commits into from
Oct 22, 2024
117 changes: 117 additions & 0 deletions app/assets/javascripts/hyrax/editor.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import RelationshipsControl from 'hyrax/relationships/control'
import SaveWorkControl from 'hyrax/save_work/save_work_control'
import AdminSetWidget from 'hyrax/editor/admin_set_widget'
import ControlledVocabulary from 'hyrax/editor/controlled_vocabulary'
import Autocomplete from 'hyrax/autocomplete'
import AuthoritySelect from 'hyrax/authority_select'

export default class {
/**
* initialize the editor behaviors
* @param {jQuery} element - The form that has a data-param-key attribute
*/
constructor(element) {
this.element = element
this.paramKey = element.data('paramKey') // The work type
this.adminSetWidget = new AdminSetWidget(element.find('select[id$="_admin_set_id"]'))
this.sharingTabElement = $('#tab-share')
}

init() {
this.autocomplete()
this.controlledVocabularies()
this.sharingTab()
this.relationshipsControl()
this.saveWorkControl()
this.saveWorkFixed()
this.authoritySelect()
this.formInProgress()
}

// Immediate feedback after work creation, editing.
formInProgress() {
$('[data-behavior~=work-form]').on('submit', function(event){
$('.card-footer.save-progress').removeAttr("hidden");
});
}

// Used when you have a linked data field that can have terms from multiple
// authorities.
authoritySelect() {
$("[data-authority-select]").each(function() {
let authoritySelect = $(this).data().authoritySelect
let options = {selectBox: 'select.' + authoritySelect,
inputField: 'input.' + authoritySelect}
new AuthoritySelect(options);
})
}

// Autocomplete fields for the work edit form (based_near, subject, language, child works)
autocomplete() {
var autocomplete = new Autocomplete()

$('[data-autocomplete]').each((function() {
var elem = $(this)
autocomplete.setup(elem, elem.data('autocomplete'), elem.data('autocompleteUrl'))
elem.parents('.multi_value.form-group').manage_fields({
add: function(e, element) {
var elem = $(element)
// Don't mark an added element as readonly even if previous element was
// Enable before initializing, as otherwise LinkedData fields remain disabled
elem.attr('readonly', false)
autocomplete.setup(elem, elem.data('autocomplete'), elem.data('autocompleteUrl'))
}
})
}))
}

// initialize any controlled vocabulary widgets
controlledVocabularies() {
this.element.find('.controlled_vocabulary.form-group').each((_idx, controlled_field) =>
new ControlledVocabulary(controlled_field, this.paramKey)
)
}

// Display the sharing tab if they select an admin set that permits sharing
sharingTab() {
if(this.adminSetWidget && !this.adminSetWidget.isEmpty()) {
this.adminSetWidget.on('change', () => this.sharingTabVisiblity(this.adminSetWidget.isSharing()))
this.sharingTabVisiblity(this.adminSetWidget.isSharing())
}
}

sharingTabVisiblity(visible) {
if (visible)
this.sharingTabElement.removeAttr("hidden")
else
this.sharingTabElement.attr("hidden","")
}

relationshipsControl() {
let collections = this.element.find('[data-behavior="collection-relationships"]')
collections.each((_idx, element) =>
new RelationshipsControl(element,
collections.data('members'),
collections.data('paramKey'),
'member_of_collections_attributes',
'tmpl-collection').init())

let works = this.element.find('[data-behavior="child-relationships"]')
works.each((_idx, element) =>
new RelationshipsControl(element,
works.data('members'),
works.data('paramKey'),
'work_members_attributes',
'tmpl-child-work').init())
}
// [hyc-override] Store saveWorkControl instance in a global variable to enable tinymce to call it
// This is necessary for requirement checks to update when rich text fields are edited
saveWorkControl() {
window.saveWorkControlInstance = new SaveWorkControl(this.element.find("#form-progress"), this.adminSetWidget)
}

saveWorkFixed() {
// Fixedsticky will polyfill position:sticky
this.element.find('#savewidget').fixedsticky()
}
}
30 changes: 30 additions & 0 deletions app/renderers/hyrax/renderers/formatted_text_renderer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true
module Hyrax
module Renderers
class FormattedTextRenderer < AttributeRenderer
private
def attribute_value_to_html(value)
sanitized_value = get_sanitized_string(value)
if microdata_value_attributes(field).present?
"<span#{html_attributes(microdata_value_attributes(field))}>#{sanitized_value}</span>"
else
li_value(sanitized_value)
end
end

# Sanitize the value, allowing only safe HTML tags and attributes
def get_sanitized_string(string)
# Define allowed tags and attributes
allowed_tags = %w[strong em b i u p br small mark sub sup a ul ol li dl dt dd div span h1 h2 h3 h4 h5 h6]
allowed_attributes = %w[href]
sanitize(string, tags: allowed_tags, attributes: allowed_attributes)
end

# Same as attribute renderer override, but without escaping the value
def li_value(value)
field_value = find_language(value) || value
auto_link((field_value))
end
end
end
end
2 changes: 1 addition & 1 deletion app/views/hyrax/articles/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<%= presenter.attribute_to_html(:alternative_title, html_dl: true, label: "Alternate title") %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:translator_display, label: 'Translator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/artworks/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:description, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:note, html_dl: true) %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/hyrax/data_sets/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<%= presenter.attribute_to_html(:last_modified_date, render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:contributor_display, label: 'Contributor', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:methodology, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:methodology, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/dissertations/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<%= presenter.attribute_to_html(:date_modified, label: 'Last Modified', render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:contributor_display, label: 'Contributor', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
4 changes: 2 additions & 2 deletions app/views/hyrax/generals/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:contributor_display, label: 'Contributor', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:translator_display, label: 'Translator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:description, html_dl: true) %>
<%= presenter.attribute_to_html(:table_of_contents, html_dl: true) %>
<%= presenter.attribute_to_html(:methodology, html_dl: true) %>
<%= presenter.attribute_to_html(:methodology, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/honors_theses/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<%= presenter.attribute_to_html(:alternative_title, html_dl: true, label: 'Alternate title') %>
<%= presenter.attribute_to_html(:date_modified, label: 'Last Modified', render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/journals/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= presenter.attribute_to_html(:alternative_title, html_dl: true, label: "Alternate title") %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/masters_papers/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= presenter.attribute_to_html(:date_modified, label: 'Last Modified', render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: 'Date of publication') %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/multimeds/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= presenter.attribute_to_html(:date_modified, label: 'Last Modified', render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
<%= presenter.attribute_to_html(:subject, render_as: :faceted, html_dl: true) %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/hyrax/scholarly_works/_attribute_rows.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= presenter.attribute_to_html(:date_modified, label: 'Last Modified', render_as: :date, html_dl: true) %>
<%= presenter.attribute_to_html(:creator_display, label: 'Creator', render_as: :person, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, html_dl: true) %>
<%= presenter.attribute_to_html(:abstract, render_as: :formatted_text, html_dl: true) %>
<%= presenter.attribute_to_html(:description, html_dl: true) %>
<%= presenter.attribute_to_html(:date_issued, html_dl: true, label: "Date of publication") %>
<%= presenter.attribute_to_html(:keyword, render_as: :faceted, html_dl: true) %>
Expand Down
8 changes: 5 additions & 3 deletions app/views/records/edit_fields/_abstract.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<% if f.object.multiple? key %>
<%= f.input :abstract, as: :multi_value, input_html: { rows: '14', type: 'textarea'}, required: f.object.required?(key) %>
<%= f.input :abstract, as: :multi_value, input_html: { rows: '14', type: 'textarea', class: 'tinymce'}, required: f.object.required?(key) %>
<% else %>
<%= f.input :abstract, as: :text, input_html: { rows: '14' }, required: f.object.required?(key) %>
<% end %>
<%= f.input :abstract, as: :text, input_html: { rows: '14', class: 'tinymce' }, required: f.object.required?(key) %>
<% end %>
<!-- [hyc-override] Include JS for TinyMCE with rich_text configuration. Enables rich text editing. -->
<%= tinymce :rich_text %>
8 changes: 5 additions & 3 deletions app/views/records/edit_fields/_methodology.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<% if f.object.multiple? key %>
<%= f.input :methodology, as: :multi_value, input_html: { rows: '14', type: 'textarea'}, required: f.object.required?(key) %>
<%= f.input :methodology, as: :multi_value, input_html: { rows: '14', type: 'textarea', class: 'tinymce' }, required: f.object.required?(key) %>
<% else %>
<%= f.input :methodology, as: :text, input_html: { rows: '14' }, required: f.object.required?(key) %>
<% end %>
<%= f.input :methodology, as: :text, input_html: { rows: '14', class: 'tinymce' }, required: f.object.required?(key) %>
<% end %>
<!-- [hyc-override] Include JS for TinyMCE with rich_text configuration. Enables rich text editing. -->
<%= tinymce :rich_text %>
44 changes: 44 additions & 0 deletions config/tinymce.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,49 @@ content_block:
- table
- fullscreen
- image
rich_text:
menubar: false
toolbar:
- "undo redo | bold italic underline | alignleft aligncenter alignright | link | numlist bullist outdent indent | blockquote | code"
plugins:
- "link lists code"
style_formats:
- title: "Inline"
items:
- title: "Bold"
inline: "b"
- title: "Italic"
inline: "i"
- title: "Underline"
inline: "u"
- title: "Strikethrough"
inline: "strike"
- title: "Blocks"
items:
- title: "Paragraph"
block: "p"
- title: "Blockquote"
block: "blockquote"
- title: "Alignments"
items:
- title: "Left"
block: ""
classes: "align-left"
- title: "Center"
block: ""
classes: "align-center"
- title: "Right"
block: ""
classes: "align-right"
setup: |
function (editor) {
editor.on('change', function () {
tinymce.triggerSave();
if (window.saveWorkControlInstance) {
window.saveWorkControlInstance.validateMetadata();
}
});
}

custom:
<<: *default
5 changes: 4 additions & 1 deletion spec/features/edit_sage_ingested_works_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@
expect(page).to have_field('Creator #2', with: 'Zhang, Xi')
expect(page).to have_field('Additional affiliation (Creator #1)', with: 'Department of Family and Community Medicine, University of California, San Francisco, CA, USA')
expect(page).to have_field('ORCID (Creator #1)', with: 'https://orcid.org/0000-0001-6833-8372')
expect(page).to have_field('Abstract', with: /Efforts to increase education opportunities, provide insurance/)
# Assert content within an iframe to check the abstract. Tinymce rich text editors confuse Capybara assertions.
within_frame(find('iframe#article_abstract_ifr')) do
expect(page).to have_content('Efforts to increase education opportunities, provide insurance')
end

# Javascript execution is inconsistent in the test environment, so rather than expanding the rest
# of the form elements, checking for the remainder of the elements whether they are visible or not.
Expand Down
Loading