From 5aa7bb0fa9be3539408d692e6c801e483b855054 Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 18 Aug 2026 13:41:05 +0800 Subject: [PATCH] Replace jquery timeago with timeago.js --- .../mvc-razor-pages/bundling-minification.md | 2 +- .../framework/ui/mvc-razor-pages/overall.md | 2 +- .../framework/ui/mvc-razor-pages/theming.md | 2 +- .../AbpAspNetCoreMvcUiPackagesModule.cs | 6 - .../Timeago/TimeagoScriptContributor.cs | 17 +- .../bootstrap/dom-event-handlers.js | 3 +- npm/packs/timeago/abp.resourcemapping.js | 6 +- npm/packs/timeago/package.json | 2 +- npm/packs/timeago/src/abp.timeago.js | 164 ++++++++++++++++++ 9 files changed, 175 insertions(+), 29 deletions(-) create mode 100644 npm/packs/timeago/src/abp.timeago.js diff --git a/docs/en/framework/ui/mvc-razor-pages/bundling-minification.md b/docs/en/framework/ui/mvc-razor-pages/bundling-minification.md index 0114361188..eb4dbf1b4b 100644 --- a/docs/en/framework/ui/mvc-razor-pages/bundling-minification.md +++ b/docs/en/framework/ui/mvc-razor-pages/bundling-minification.md @@ -386,7 +386,7 @@ Configure(options => ````html - + ```` ### External/CDN file Support diff --git a/docs/en/framework/ui/mvc-razor-pages/overall.md b/docs/en/framework/ui/mvc-razor-pages/overall.md index b029fda57c..50086c3819 100644 --- a/docs/en/framework/ui/mvc-razor-pages/overall.md +++ b/docs/en/framework/ui/mvc-razor-pages/overall.md @@ -63,7 +63,7 @@ There are a set of standard JavaScript/CSS libraries that comes pre-installed an - [JQuery Form](https://github.com/jquery-form/form) for AJAX forms. - [bootstrap-datepicker](https://github.com/uxsolutions/bootstrap-datepicker) to show date pickers. - [Select2](https://select2.org/) for better select/combo boxes. -- [Timeago](http://timeago.yarp.com/) to show automatically updating fuzzy timestamps. +- [timeago.js](https://timeago.org/) to show automatically updating fuzzy timestamps. - [malihu-custom-scrollbar-plugin](https://github.com/malihu/malihu-custom-scrollbar-plugin) for custom scrollbars. You can use these libraries directly in your applications, without needing to manually import your page. diff --git a/docs/en/framework/ui/mvc-razor-pages/theming.md b/docs/en/framework/ui/mvc-razor-pages/theming.md index 138b52e3d2..5d50252acc 100644 --- a/docs/en/framework/ui/mvc-razor-pages/theming.md +++ b/docs/en/framework/ui/mvc-razor-pages/theming.md @@ -50,7 +50,7 @@ All the themes must depend on the [@abp/aspnetcore.mvc.ui.theme.shared](https:// * [JQuery Form](https://github.com/jquery-form/form) for AJAX forms. * [bootstrap-datepicker](https://github.com/uxsolutions/bootstrap-datepicker) to show date pickers. * [Select2](https://select2.org/) for better select/combo boxes. -* [Timeago](http://timeago.yarp.com/) to show automatically updating fuzzy timestamps. +* [timeago.js](https://timeago.org/) to show automatically updating fuzzy timestamps. * [malihu-custom-scrollbar-plugin](https://github.com/malihu/malihu-custom-scrollbar-plugin) for custom scrollbars. These libraries are selected as the base libraries and available to the applications and modules. diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs index 7ba8105d43..0c4bab0b04 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs @@ -2,7 +2,6 @@ using Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Moment; -using Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago; using Volo.Abp.Localization; using Volo.Abp.Modularity; @@ -38,11 +37,6 @@ public class AbpAspNetCoreMvcUiPackagesModule : AbpModule new NameValue("zh-Hant", "zh-tw"), new NameValue("de-DE", "de")); - //Timeago - options.AddLanguageFilesMapOrUpdate(TimeagoScriptContributor.PackageName, - new NameValue("zh-Hans", "zh-CN"), - new NameValue("zh-Hant", "zh-TW")); - //JQueryValidation options.AddLanguageFilesMapOrUpdate(JQueryValidationScriptContributor.PackageName, new NameValue("zh-Hans", "zh"), diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs index 3b09dd1022..94fbd9a3b9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Timeago/TimeagoScriptContributor.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; -using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; -using Volo.Abp.Localization; using Volo.Abp.Modularity; namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago; @@ -10,20 +8,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago; [DependsOn(typeof(JQueryScriptContributor))] public class TimeagoScriptContributor : BundleContributor { - public const string PackageName = "jquery.timeago"; - public override void ConfigureBundle(BundleConfigurationContext context) { - context.Files.AddIfNotContains("/libs/timeago/jquery.timeago.js"); - } - - public override void ConfigureDynamicResources(BundleConfigurationContext context) - { - var fileName = context.LazyServiceProvider.LazyGetRequiredService>().Value.GetCurrentUICultureLanguageFilesMap(PackageName); - var filePath = $"/libs/timeago/locales/jquery.timeago.{fileName}.js"; - if (context.FileProvider.GetFileInfo(filePath).Exists) - { - context.Files.Add(filePath); - } + context.Files.AddIfNotContains("/libs/timeago/timeago.full.min.js"); + context.Files.AddIfNotContains("/libs/abp/timeago/abp.timeago.js"); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js index 3199900536..cb1b38ab8c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js @@ -72,7 +72,7 @@ } abp.dom.initializers.initializeTimeAgos = function ($timeagos) { - $timeagos.timeago(); + abp.timeago.render($timeagos.toArray()); } abp.dom.initializers.initializeAutocompleteSelects = function ($autocompleteSelects) { @@ -217,6 +217,7 @@ args.$el.findWithSelf('[data-bs-toggle="tooltip"]').each(function () { $('#' + $(this).attr('aria-describedby')).remove(); }); + abp.timeago.cancel(args.$el.findWithSelf('[timeago-id]').toArray()); }); abp.event.on('abp.configurationInitialized', function () { diff --git a/npm/packs/timeago/abp.resourcemapping.js b/npm/packs/timeago/abp.resourcemapping.js index df913e3d28..de0c3464db 100644 --- a/npm/packs/timeago/abp.resourcemapping.js +++ b/npm/packs/timeago/abp.resourcemapping.js @@ -1,6 +1,6 @@ module.exports = { mappings: { - "@node_modules/timeago/jquery.timeago.js": "@libs/timeago/", - "@node_modules/timeago/locales/*.*": "@libs/timeago/locales/" + "@node_modules/timeago.js/dist/*.js": "@libs/timeago/", + "@node_modules/@abp/timeago/src/*.*": "@libs/abp/timeago/" } -} \ No newline at end of file +} diff --git a/npm/packs/timeago/package.json b/npm/packs/timeago/package.json index 79aa378353..3c5c7a61d4 100644 --- a/npm/packs/timeago/package.json +++ b/npm/packs/timeago/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@abp/jquery": "~10.7.0-rc.2", - "timeago": "^1.6.7" + "timeago.js": "^4.0.2" }, "gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431", "homepage": "https://abp.io", diff --git a/npm/packs/timeago/src/abp.timeago.js b/npm/packs/timeago/src/abp.timeago.js new file mode 100644 index 0000000000..40693779a7 --- /dev/null +++ b/npm/packs/timeago/src/abp.timeago.js @@ -0,0 +1,164 @@ +var abp = abp || {}; +(function ($) { + + if (typeof timeago === 'undefined') { + throw "abp/timeago library requires the timeago.js library included to the page!"; + } + + abp.timeago = abp.timeago || {}; + + // ABP culture name -> timeago.js locale name (only the ones that don't match the two-letter language code) + abp.timeago.localeMap = { + 'en': 'en_US', + 'zh': 'zh_CN', + 'zh-Hans': 'zh_CN', + 'zh-Hant': 'zh_TW', + 'zh-CN': 'zh_CN', + 'zh-TW': 'zh_TW', + 'pt': 'pt_BR', + 'nb': 'nb_NO', + 'no': 'nb_NO', + 'nn': 'nn_NO', + 'hi': 'hi_IN', + 'id': 'id_ID', + 'bn': 'bn_IN' + }; + + abp.timeago.getLocale = function (cultureName) { + cultureName = cultureName || (abp.localization && abp.localization.currentCulture && abp.localization.currentCulture.cultureName) || 'en'; + + if (abp.timeago.localeMap[cultureName]) { + return abp.timeago.localeMap[cultureName]; + } + + var language = cultureName.split('-')[0]; + return abp.timeago.localeMap[language] || language; + }; + + abp.timeago.format = function (date, options) { + return timeago.format(date, abp.timeago.getLocale(), options); + }; + + var toNodeList = function (nodes) { + if (!nodes) { + return []; + } + + return Array.prototype.filter.call(nodes.nodeType ? [nodes] : nodes, function (node) { + return node && node.getAttribute; + }); + }; + + //