From 698c9b718f0d48394c4320c4e03d8ad54c8805fc Mon Sep 17 00:00:00 2001 From: Michael Heppler Date: Fri, 26 Feb 2021 16:43:57 -0500 Subject: [PATCH] Add truncation plugin to apply to html+text desc blocks [ref #6685] --- src/main/webapp/dataverse_template.xhtml | 3 +- src/main/webapp/resources/css/structure.css | 26 ++++- .../resources/js/dv_rebind_bootstrap_ui.js | 64 ++++++++++- .../webapp/resources/js/jquery.truncate.js | 103 ++++++++++++++++++ 4 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 src/main/webapp/resources/js/jquery.truncate.js diff --git a/src/main/webapp/dataverse_template.xhtml b/src/main/webapp/dataverse_template.xhtml index e461e853955..61487c0d1c0 100644 --- a/src/main/webapp/dataverse_template.xhtml +++ b/src/main/webapp/dataverse_template.xhtml @@ -84,7 +84,8 @@ - + + diff --git a/src/main/webapp/resources/css/structure.css b/src/main/webapp/resources/css/structure.css index 2603fd6ba0b..f4dea7efe7c 100644 --- a/src/main/webapp/resources/css/structure.css +++ b/src/main/webapp/resources/css/structure.css @@ -627,13 +627,37 @@ div.edit-field div.ui-message {margin:6px 0;} .metadata-container table.metadata {border-collapse:separate;margin:0 4px;width:100%;} .metadata-container table.metadata th {width:25%;vertical-align:top;padding:6px 12px;} .metadata-container table.metadata td {padding:6px 12px;vertical-align:top;} -@media(max-width:767px){ + +/* TO-DO FIX max-width:1199px FOR SUMMARY BLOCK ONLY, NOT OTHER PAGES */ +@media(max-width:1199px){ .metadata-container table.metadata th, .metadata-container table.metadata td {display:block;width:100%;} .metadata-container table.metadata th {padding-bottom:0;} .metadata-container table.metadata td {padding-left:30px;} } .panel-body.metadata-container {padding:15px 0;} .metadata-logo {max-width:180px;max-height:40px;} +.metadata-container .truncate-more-link, .metadata-container .collapse-less-link {color: #337AB7; cursor: pointer; cursor: hand;} + +/* HTML METADATA OVERWRITE */ +.metadata-container table.metadata td > div { + /* https://stackoverflow.com/a/24158056 */ + /*-moz-white-space: pre-wrap; + white-space: pre-wrap; + hyphens: auto; + -ms-word-break: break-all; + -ms-word-wrap: break-all; + -webkit-word-break: break-word; + -webkit-word-wrap: break-word; + word-break: break-word; + word-wrap: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto;*/ +} +.metadata-container pre { + white-space: pre-wrap !important; +} /* Primefaces vs Bootstrap selectOneMenu fix */ div.ui-selectonemenu.form-control {padding:0px;} diff --git a/src/main/webapp/resources/js/dv_rebind_bootstrap_ui.js b/src/main/webapp/resources/js/dv_rebind_bootstrap_ui.js index 44e86831c69..608b61ce45f 100644 --- a/src/main/webapp/resources/js/dv_rebind_bootstrap_ui.js +++ b/src/main/webapp/resources/js/dv_rebind_bootstrap_ui.js @@ -22,6 +22,12 @@ function bind_bsui_components(){ // Hide open tooltips + popovers $('.bootstrap-button-tooltip, [data-toggle="tooltip"]').tooltip("hide"); $("[data-toggle='popover']").popover("hide"); + + // Truncate content + contentTruncate(); + + // Truncate checksums + checksumTruncate(); // Tooltips + popovers bind_tooltip_popover(); @@ -29,9 +35,6 @@ function bind_bsui_components(){ // Disabled pagination links disabledLinks(); - // Truncate checksums - checksumTruncate(); - // Sharrre sharrre(); @@ -157,7 +160,62 @@ function sharrre(){ } }); } + +/* + * Truncate any metadata content + */ +function contentTruncate(){ + // jquery.truncate.js + // HTML-safe truncation + // https://github.com/pathable/truncate + + // WHAT ARE WE TRUNCATING + // TO-DO IS THERE A MORE SCALABLE SELECTOR METHOD THAN THIS? ADD TRUNCATE CLASS TO OBJECTS? e.g. span.checksum-truncate + $('#dsDescription td div').each(function () { + + // GET THE DESC TEXT AND HTML + var truncateThis = $(this).html(); + + // TO-DO TRUNCATE BTN LABEL TEXT FROM BUNDLE + var readMoreBtn = '... '; + var readLessBtn = ''; + + if ($(this).hasClass('thisWasTruncated')) { + // DO NOTHING + } + else { + + // TO-DO PUT THE ORIGINAL FULL DESCRIPTION SOMEWHERE + // $('#dsDescription td div').attr({'data-html':'true', 'data-original-text':truncateThis}); + + var thisWasTruncated = jQuery.truncate(truncateThis, { + length: 500, + words: true, + keepFirstWord: true, + ellipsis: readMoreBtn, + finishBlock: true + }); + + // ... add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!! + $(this).toggleClass('thisWasTruncated').html(thisWasTruncated).find('img').attr('class', 'img-responsive'); + + // Return full description on Read More link click ++ add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!! + $(document).on('click', 'button.truncate-more-link', function() { + $(this).tooltip('hide').parent('div').toggleClass('thisWasTruncated').html(truncateThis).append(readLessBtn).find('img').attr('class', 'img-responsive'); + $('button.collapse-less-link').tooltip(); + }); + // ... add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!! + $(document).on('click', 'button.collapse-less-link', function() { + $(this).tooltip('hide').parent('div').toggleClass('thisWasTruncated').html(thisWasTruncated).find('img').attr('class', 'img-responsive'); + $('button.truncate-more-link').tooltip(); + }); + + } + + }); +} + /* * Truncate file checksums */ diff --git a/src/main/webapp/resources/js/jquery.truncate.js b/src/main/webapp/resources/js/jquery.truncate.js new file mode 100644 index 00000000000..e43d4134ae1 --- /dev/null +++ b/src/main/webapp/resources/js/jquery.truncate.js @@ -0,0 +1,103 @@ +(function($) { + + // Matches trailing non-space characters. + var chop = /(\s*\S+|\s)$/; + + // Matches the first word in the string. + var start = /^(\S*)/; + + // Return a truncated html string. Delegates to $.fn.truncate. + $.truncate = function(html, options) { + return $('
').append(html).truncate(options).html(); + }; + + // Truncate the contents of an element in place. + $.fn.truncate = function(options) { + if ($.isNumeric(options)) options = {length: options}; + var o = $.extend({}, $.truncate.defaults, options); + + return this.each(function() { + var self = $(this); + + if (o.noBreaks) self.find('br').replaceWith(' '); + + var text = self.text(); + var excess = text.length - o.length; + + if (o.stripTags) self.text(text); + + // Chop off any partial words if appropriate. + if (o.words && excess > 0) { + var truncated = text.slice(0, o.length).replace(chop, '').length; + + if (o.keepFirstWord && truncated === 0) { + excess = text.length - start.exec(text)[0].length - 1; + } else { + excess = text.length - truncated - 1; + } + } + + if (excess < 0 || !excess && !o.truncated) return; + + // Iterate over each child node in reverse, removing excess text. + $.each(self.contents().get().reverse(), function(i, el) { + var $el = $(el); + var text = $el.text(); + var length = text.length; + + // If the text is longer than the excess, remove the node and continue. + if (length <= excess) { + o.truncated = true; + excess -= length; + $el.remove(); + return; + } + + // Remove the excess text and append the ellipsis. + if (el.nodeType === 3) { + // should we finish the block anyway? + if (o.finishBlock) { + $(el.splitText(length)).replaceWith(o.ellipsis); + } else { + $(el.splitText(length - excess - 1)).replaceWith(o.ellipsis); + } + return false; + } + + // Recursively truncate child nodes. + $el.truncate($.extend(o, {length: length - excess})); + return false; + }); + }); + }; + + $.truncate.defaults = { + + // Strip all html elements, leaving only plain text. + stripTags: false, + + // Only truncate at word boundaries. + words: false, + + // When 'words' is active, keeps the first word in the string + // even if it's longer than a target length. + keepFirstWord: false, + + // Replace instances of
with a single space. + noBreaks: false, + + // if true always truncate the content at the end of the block. + finishBlock: false, + + // The maximum length of the truncated html. + length: Infinity, + + // The character to use as the ellipsis. The word joiner (U+2060) can be + // used to prevent a hanging ellipsis, but displays incorrectly in Chrome + // on Windows 7. + // http://code.google.com/p/chromium/issues/detail?id=68323 + ellipsis: '\u2026' // '\u2060\u2026' + + }; + +})(jQuery);