From 4ee5d52ac9f1af3c17679d987327cdfad9fdd19f Mon Sep 17 00:00:00 2001 From: Penar Musaraj Date: Fri, 17 Dec 2021 11:45:12 -0500 Subject: [PATCH] DEV: Remove jQuery autoellipsis dependency (#15336) --- .../addon/components/site-text-summary.js | 1 - .../javascripts/discourse/ember-cli-build.js | 1 - .../discourse/tests/theme_qunit_vendor.js | 1 - app/assets/javascripts/vendor.js | 1 - .../stylesheets/common/admin/admin_base.scss | 24 +- lib/tasks/javascript.rake | 3 - package.json | 1 - .../javascripts/jquery.autoellipsis-1.0.10.js | 447 ------------------ yarn.lock | 4 - 9 files changed, 22 insertions(+), 461 deletions(-) delete mode 100644 vendor/assets/javascripts/jquery.autoellipsis-1.0.10.js diff --git a/app/assets/javascripts/admin/addon/components/site-text-summary.js b/app/assets/javascripts/admin/addon/components/site-text-summary.js index 071091f12b8..8f9b3f3b6c9 100644 --- a/app/assets/javascripts/admin/addon/components/site-text-summary.js +++ b/app/assets/javascripts/admin/addon/components/site-text-summary.js @@ -19,7 +19,6 @@ export default Component.extend({ } ); } - $(this.element.querySelector(".site-text-value")).ellipsis(); }, click() { diff --git a/app/assets/javascripts/discourse/ember-cli-build.js b/app/assets/javascripts/discourse/ember-cli-build.js index 1101a2b141d..60d47a3cfc2 100644 --- a/app/assets/javascripts/discourse/ember-cli-build.js +++ b/app/assets/javascripts/discourse/ember-cli-build.js @@ -44,7 +44,6 @@ module.exports = function (defaults) { app.import(vendorJs + "jquery.ui.widget.js"); app.import(vendorJs + "jquery.fileupload.js"); app.import(vendorJs + "jquery.fileupload-process.js"); - app.import(vendorJs + "jquery.autoellipsis-1.0.10.js"); app.import(vendorJs + "caret_position.js"); app.import("node_modules/ember-source/dist/ember-template-compiler.js", { type: "test", diff --git a/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js b/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js index 98d290fa09d..0c691858a11 100644 --- a/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js +++ b/app/assets/javascripts/discourse/tests/theme_qunit_vendor.js @@ -29,7 +29,6 @@ //= require rsvp.js //= require uppy.js //= require buffered-proxy -//= require jquery.autoellipsis-1.0.10 //= require virtual-dom //= require virtual-dom-amd //= require discourse-shims diff --git a/app/assets/javascripts/vendor.js b/app/assets/javascripts/vendor.js index 118281adf0e..53e9bd116b3 100644 --- a/app/assets/javascripts/vendor.js +++ b/app/assets/javascripts/vendor.js @@ -22,7 +22,6 @@ //= require rsvp.js //= require uppy.js //= require buffered-proxy -//= require jquery.autoellipsis-1.0.10 //= require virtual-dom //= require virtual-dom-amd //= require discourse-shims diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index a50348b3a20..f004e443541 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -229,13 +229,33 @@ $mobile-breakpoint: 700px; button.edit { float: right; } + + $maxHeight: 8 * 1.4em; + $gradientHeight: 2.2em; + .site-text-value { margin: 0.5em 5em 0.5em 0; - @include breakpoint(medium, min-width) { - max-height: 100px; + max-height: $maxHeight; + overflow: hidden; + position: relative; + &::after { + content: " "; + position: absolute; + background-color: red; + left: 0; + right: 0; + top: $maxHeight - $gradientHeight; + height: $gradientHeight; + background: linear-gradient( + to top, + rgba(var(--secondary-rgb), 1), + rgba(var(--secondary-rgb), 0.15) + ); } @include breakpoint(mobile-extra-large) { word-wrap: break-word; + max-width: 80vw; + margin-right: 3em; } color: var(--primary-medium); } diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake index c876449e692..2fc2fcd0e74 100644 --- a/lib/tasks/javascript.rake +++ b/lib/tasks/javascript.rake @@ -103,9 +103,6 @@ def dependencies }, { source: '@highlightjs/cdn-assets/.', destination: 'highlightjs' - }, { - source: 'jquery.autoellipsis/src/jquery.autoellipsis.js', - destination: 'jquery.autoellipsis-1.0.10.js' }, { source: 'jquery-color/dist/jquery.color.js' }, { diff --git a/package.json b/package.json index 002f521272b..8de481fca94 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "jquery": "3.5.1", "jquery-color": "3.0.0-alpha.1", "jquery-tags-input": "1.3.5", - "jquery.autoellipsis": "https://github.com/pvdspek/jquery.autoellipsis", "magnific-popup": "1.1.0", "markdown-it": "10.0.0", "moment": "2.29.1", diff --git a/vendor/assets/javascripts/jquery.autoellipsis-1.0.10.js b/vendor/assets/javascripts/jquery.autoellipsis-1.0.10.js deleted file mode 100644 index 7bd28ef0ec1..00000000000 --- a/vendor/assets/javascripts/jquery.autoellipsis-1.0.10.js +++ /dev/null @@ -1,447 +0,0 @@ -/*! - - Copyright (c) 2011 Peter van der Spek - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - */ - - -(function($) { - - /** - * Hash containing mapping of selectors to settings hashes for target selectors that should be live updated. - * - * @type {Object.} - * @private - */ - var liveUpdatingTargetSelectors = {}; - - /** - * Interval ID for live updater. Contains interval ID when the live updater interval is active, or is undefined - * otherwise. - * - * @type {number} - * @private - */ - var liveUpdaterIntervalId; - - /** - * Boolean indicating whether the live updater is running. - * - * @type {boolean} - * @private - */ - var liveUpdaterRunning = false; - - /** - * Set of default settings. - * - * @type {Object.} - * @private - */ - var defaultSettings = { - ellipsis: '...', - setTitle: 'never', - live: false - }; - - /** - * Perform ellipsis on selected elements. - * - * @param {string} selector the inner selector of elements that ellipsis may work on. Inner elements not referred to by this - * selector are left untouched. - * @param {Object.=} options optional options to override default settings. - * @return {jQuery} the current jQuery object for chaining purposes. - * @this {jQuery} the current jQuery object. - */ - $.fn.ellipsis = function(selector, options) { - var subjectElements, settings; - - subjectElements = $(this); - - // Check for options argument only. - if (typeof selector !== 'string') { - options = selector; - selector = undefined; - } - - // Create the settings from the given options and the default settings. - settings = $.extend({}, defaultSettings, options); - - // If selector is not set, work on immediate children (default behaviour). - settings.selector = selector; - - // Do ellipsis on each subject element. - subjectElements.each(function() { - var elem = $(this); - - // Do ellipsis on subject element. - ellipsisOnElement(elem, settings); - }); - - // If live option is enabled, add subject elements to live updater. Otherwise remove from live updater. - if (settings.live) { - addToLiveUpdater(subjectElements.selector, settings); - - } else { - removeFromLiveUpdater(subjectElements.selector); - } - - // Return jQuery object for chaining. - return this; - }; - - - /** - * Perform ellipsis on the given container. - * - * @param {jQuery} containerElement jQuery object containing one DOM element to perform ellipsis on. - * @param {Object.} settings the settings for this ellipsis operation. - * @private - */ - function ellipsisOnElement(containerElement, settings) { - var containerData = containerElement.data('jqae'); - if (!containerData) containerData = {}; - - // Check if wrapper div was already created and bound to the container element. - var wrapperElement = containerData.wrapperElement; - - // If not, create wrapper element. - if (!wrapperElement) { - wrapperElement = containerElement.wrapInner('
').find('>div'); - - // Wrapper div should not add extra size. - wrapperElement.css({ - margin: 0, - padding: 0, - border: 0 - }); - } - - // Check if the original wrapper element content was already bound to the wrapper element. - var wrapperElementData = wrapperElement.data('jqae'); - if (!wrapperElementData) wrapperElementData = {}; - - var wrapperOriginalContent = wrapperElementData.originalContent; - - // If so, clone the original content, re-bind the original wrapper content to the clone, and replace the - // wrapper with the clone. - if (wrapperOriginalContent) { - wrapperElement = wrapperElementData.originalContent.clone(true) - .data('jqae', {originalContent: wrapperOriginalContent}).replaceAll(wrapperElement); - - } else { - // Otherwise, clone the current wrapper element and bind it as original content to the wrapper element. - - wrapperElement.data('jqae', {originalContent: wrapperElement.clone(true)}); - } - - // Bind the wrapper element and current container width and height to the container element. Current container - // width and height are stored to detect changes to the container size. - containerElement.data('jqae', { - wrapperElement: wrapperElement, - containerWidth: containerElement.width(), - containerHeight: containerElement.height() - }); - - // Calculate with current container element height. - var containerElementHeight = containerElement.height(); - - // Calculate wrapper offset. - var wrapperOffset = (parseInt(containerElement.css('padding-top'), 10) || 0) + (parseInt(containerElement.css('border-top-width'), 10) || 0) - (wrapperElement.offset().top - containerElement.offset().top); - - // Normally the ellipsis characters are applied to the last non-empty text-node in the selected element. If the - // selected element becomes empty during ellipsis iteration, the ellipsis characters cannot be applied to that - // selected element, and must be deferred to the previous selected element. This parameter keeps track of that. - var deferAppendEllipsis = false; - - // Loop through all selected elements in reverse order. - var selectedElements = wrapperElement; - if (settings.selector) selectedElements = $(wrapperElement.find(settings.selector).get().reverse()); - - selectedElements.each(function() { - var selectedElement = $(this), - originalText = selectedElement.text(), - ellipsisApplied = false; - - // Check if we can safely remove the selected element. This saves a lot of unnecessary iterations. - if (wrapperElement.innerHeight() - selectedElement.innerHeight() > containerElementHeight + wrapperOffset) { - selectedElement.remove(); - - } else { - // Reverse recursively remove empty elements, until the element that contains a non-empty text-node. - removeLastEmptyElements(selectedElement); - - // If the selected element has not become empty, start ellipsis iterations on the selected element. - if (selectedElement.contents().length) { - - // If a deffered ellipsis is still pending, apply it now to the last text-node. - if (deferAppendEllipsis) { - getLastTextNode(selectedElement).get(0).nodeValue += settings.ellipsis; - deferAppendEllipsis = false; - } - - // Iterate until wrapper element height is less than or equal to the original container element - // height plus possible wrapperOffset. - while (wrapperElement.innerHeight() > containerElementHeight + wrapperOffset) { - // Apply ellipsis on last text node, by removing one word. - ellipsisApplied = ellipsisOnLastTextNode(selectedElement); - - // If ellipsis was succesfully applied, remove any remaining empty last elements and append the - // ellipsis characters. - if (ellipsisApplied) { - removeLastEmptyElements(selectedElement); - - // If the selected element is not empty, append the ellipsis characters. - if (selectedElement.contents().length) { - getLastTextNode(selectedElement).get(0).nodeValue += settings.ellipsis; - - } else { - // If the selected element has become empty, defer the appending of the ellipsis characters - // to the previous selected element. - deferAppendEllipsis = true; - selectedElement.remove(); - break; - } - - } else { - // If ellipsis could not be applied, defer the appending of the ellipsis characters to the - // previous selected element. - deferAppendEllipsis = true; - selectedElement.remove(); - break; - } - } - - // If the "setTitle" property is set to "onEllipsis" and the ellipsis has been applied, or if the - // property is set to "always", the add the "title" attribute with the original text. Else remove the - // "title" attribute. When the "setTitle" property is set to "never" we do not touch the "title" - // attribute. - if (((settings.setTitle == 'onEllipsis') && ellipsisApplied) || (settings.setTitle == 'always')) { - selectedElement.attr('title', originalText); - - } else if (settings.setTitle != 'never') { - selectedElement.removeAttr('title'); - } - } - } - }); - } - - /** - * Performs ellipsis on the last text node of the given element. Ellipsis is done by removing a full word. - * - * @param {jQuery} element jQuery object containing a single DOM element. - * @return {boolean} true when ellipsis has been done, false otherwise. - * @private - */ - function ellipsisOnLastTextNode(element) { - var lastTextNode = getLastTextNode(element); - - // If the last text node is found, do ellipsis on that node. - if (lastTextNode.length) { - var text = lastTextNode.get(0).nodeValue; - - // Find last space character, and remove text from there. If no space is found the full remaining text is - // removed. - var pos = text.lastIndexOf(' '); - if (pos > -1) { - text = $.trim(text.substring(0, pos)); - lastTextNode.get(0).nodeValue = text; - - } else { - lastTextNode.get(0).nodeValue = ''; - } - - return true; - } - - return false; - } - - /** - * Get last text node of the given element. - * - * @param {jQuery} element jQuery object containing a single element. - * @return {jQuery} jQuery object containing a single text node. - * @private - */ - function getLastTextNode(element) { - if (element.contents().length) { - - // Get last child node. - var contents = element.contents(); - var lastNode = contents.eq(contents.length - 1); - - // If last node is a text node, return it. - if (lastNode.filter(textNodeFilter).length) { - return lastNode; - - } else { - // Else it is an element node, and we recurse into it. - - return getLastTextNode(lastNode); - } - - } else { - // If there is no last child node, we append an empty text node and return that. Normally this should not - // happen, as we test for emptiness before calling getLastTextNode. - - element.append(''); - var contents = element.contents(); - return contents.eq(contents.length - 1); - } - } - - /** - * Remove last empty elements. This is done recursively until the last element contains a non-empty text node. - * - * @param {jQuery} element jQuery object containing a single element. - * @return {boolean} true when elements have been removed, false otherwise. - * @private - */ - function removeLastEmptyElements(element) { - if (element.contents().length) { - - // Get last child node. - var contents = element.contents(); - var lastNode = contents.eq(contents.length - 1); - - // If last child node is a text node, check for emptiness. - if (lastNode.filter(textNodeFilter).length) { - var text = lastNode.get(0).nodeValue; - text = $.trim(text); - - if (text == '') { - // If empty, remove the text node. - lastNode.remove(); - - return true; - - } else { - return false; - } - - } else { - // If the last child node is an element node, remove the last empty child nodes on that node. - while (removeLastEmptyElements(lastNode)) { - } - - // If the last child node contains no more child nodes, remove the last child node. - if (lastNode.contents().length) { - return false; - - } else { - lastNode.remove(); - - return true; - } - } - } - - return false; - } - - /** - * Filter for testing on text nodes. - * - * @return {boolean} true when this node is a text node, false otherwise. - * @this {Node} - * @private - */ - function textNodeFilter() { - return this.nodeType === 3; - } - - /** - * Add target selector to hash of target selectors. If this is the first target selector added, start the live - * updater. - * - * @param {string} targetSelector the target selector to run the live updater for. - * @param {Object.} settings the settings to apply on this target selector. - * @private - */ - function addToLiveUpdater(targetSelector, settings) { - // Store target selector with its settings. - liveUpdatingTargetSelectors[targetSelector] = settings; - - // If the live updater has not yet been started, start it now. - if (!liveUpdaterIntervalId) { - liveUpdaterIntervalId = window.setInterval(function() { - doLiveUpdater(); - }, 200); - } - } - - /** - * Remove the target selector from the hash of target selectors. It this is the last remaining target selector - * being removed, stop the live updater. - * - * @param {string} targetSelector the target selector to stop running the live updater for. - * @private - */ - function removeFromLiveUpdater(targetSelector) { - // If the hash contains the target selector, remove it. - if (liveUpdatingTargetSelectors[targetSelector]) { - delete liveUpdatingTargetSelectors[targetSelector]; - - // If no more target selectors are in the hash, stop the live updater. - if (!liveUpdatingTargetSelectors.length) { - if (liveUpdaterIntervalId) { - window.clearInterval(liveUpdaterIntervalId); - liveUpdaterIntervalId = undefined; - } - } - } - }; - - /** - * Run the live updater. The live updater is periodically run to check if its monitored target selectors require - * re-applying of the ellipsis. - * - * @private - */ - function doLiveUpdater() { - // If the live updater is already running, skip this time. We only want one instance running at a time. - if (!liveUpdaterRunning) { - liveUpdaterRunning = true; - - // Loop through target selectors. - for (var targetSelector in liveUpdatingTargetSelectors) { - $(targetSelector).each(function() { - var containerElement, containerData; - - containerElement = $(this); - containerData = containerElement.data('jqae'); - - // If container element dimensions have changed, or the container element is new, run ellipsis on - // that container element. - if ((containerData.containerWidth != containerElement.width()) || - (containerData.containerHeight != containerElement.height())) { - ellipsisOnElement(containerElement, liveUpdatingTargetSelectors[targetSelector]); - } - }); - } - - liveUpdaterRunning = false; - } - }; - -})(jQuery); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8bd50dd8cd1..e9be728e598 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2611,10 +2611,6 @@ jquery-tags-input@1.3.5: resolved "https://registry.yarnpkg.com/jquery-tags-input/-/jquery-tags-input-1.3.5.tgz#1c89cb95c61983ad14386d30a006920476b93ed7" integrity sha1-HInLlcYZg60UOG0woAaSBHa5Ptc= -"jquery.autoellipsis@https://github.com/pvdspek/jquery.autoellipsis": - version "0.0.0" - resolved "https://github.com/pvdspek/jquery.autoellipsis#756391145c09ec11ae2b88a0ca0c3b5fdf8d21a1" - jquery@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5"