diff --git a/abp_io/src/Volo.AbpWebSite.Web/wwwroot/assets/abp_nupkg.png b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/assets/abp_nupkg.png new file mode 100644 index 0000000000..76547ba44c Binary files /dev/null and b/abp_io/src/Volo.AbpWebSite.Web/wwwroot/assets/abp_nupkg.png differ diff --git a/common.props b/common.props index cf57442f42..15df803252 100644 --- a/common.props +++ b/common.props @@ -1,13 +1,13 @@ latest - 0.8.0 + 0.9.0 $(NoWarn);CS1591 - http://www.aspnetboilerplate.com/images/abp_nupkg.png - http://abp.io - https://github.com/volosoft/abp/blob/master/LICENSE + https://abp.io/assets/abp_nupkg.png + https://abp.io + https://github.com/abpframework/abp/blob/master/LICENSE git - https://github.com/volosoft/abp/ + https://github.com/abpframework/abp/ diff --git a/docs/en/AspNetCore/Bundling-Minification.md b/docs/en/AspNetCore/Bundling-Minification.md index af92d91243..b8d70d8624 100644 --- a/docs/en/AspNetCore/Bundling-Minification.md +++ b/docs/en/AspNetCore/Bundling-Minification.md @@ -114,7 +114,7 @@ public class MyWebModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options .ScriptBundles @@ -152,7 +152,7 @@ public class MyWebExtensionModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options .ScriptBundles diff --git a/docs/en/Localization.md b/docs/en/Localization.md index ba7bf04238..b6d27cc9ce 100644 --- a/docs/en/Localization.md +++ b/docs/en/Localization.md @@ -46,12 +46,12 @@ public class MyModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") diff --git a/docs/en/Module-Development-Basics.md b/docs/en/Module-Development-Basics.md index bb193b613e..6e1c724669 100644 --- a/docs/en/Module-Development-Basics.md +++ b/docs/en/Module-Development-Basics.md @@ -42,7 +42,7 @@ public class BlogModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { //Configure default connection string for the application - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = "......"; }); diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 6697e10124..d8c52f38fe 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -138,7 +138,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.TenantResolvers.Add(new MyCustomTenantResolver()); }); @@ -194,7 +194,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Tenants = new[] { @@ -240,7 +240,7 @@ namespace MyCompany.MyProject { var configuration = BuildConfiguration(); - context.Services.Configure(configuration); + Configure(configuration); } private static IConfigurationRoot BuildConfiguration() @@ -361,7 +361,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { //Subdomain format: {0}.mydomain.com (adding as the highest priority resolver) options.TenantResolvers.Insert(0, new DomainTenantResolver("{0}.mydomain.com")); diff --git a/docs/en/Virtual-File-System.md b/docs/en/Virtual-File-System.md index 9ee0e106d4..9a27f3c426 100644 --- a/docs/en/Virtual-File-System.md +++ b/docs/en/Virtual-File-System.md @@ -58,7 +58,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { //Register all embedded files of this assembly to the virtual file system options.FileSets.AddEmbedded(); @@ -122,7 +122,7 @@ public class MyWebAppModule : AbpModule if (hostingEnvironment.IsDevelopment()) //only for development time { - context.Services.Configure(options => + Configure(options => { //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project options.FileSets.ReplaceEmbeddedByPyhsical( diff --git a/docs/zh-Hans/AspNetCore/Bundling-Minification.md b/docs/zh-Hans/AspNetCore/Bundling-Minification.md index 4dc6d69c35..7454bd3c17 100644 --- a/docs/zh-Hans/AspNetCore/Bundling-Minification.md +++ b/docs/zh-Hans/AspNetCore/Bundling-Minification.md @@ -115,7 +115,7 @@ public class MyWebModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options .ScriptBundles @@ -153,7 +153,7 @@ public class MyWebExtensionModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options .ScriptBundles diff --git a/docs/zh-Hans/Localization.md b/docs/zh-Hans/Localization.md index b98163b66d..d47d353f2d 100644 --- a/docs/zh-Hans/Localization.md +++ b/docs/zh-Hans/Localization.md @@ -46,12 +46,12 @@ public class MyModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") diff --git a/docs/zh-Hans/Module-Development-Basics.md b/docs/zh-Hans/Module-Development-Basics.md index 5c9d8b11a3..044016e17a 100644 --- a/docs/zh-Hans/Module-Development-Basics.md +++ b/docs/zh-Hans/Module-Development-Basics.md @@ -42,7 +42,7 @@ public class BlogModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { //为应用程序配置默认的连接字符串 - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = "......"; }); diff --git a/docs/zh-Hans/Multi-Tenancy.md b/docs/zh-Hans/Multi-Tenancy.md index a28b2e7fad..11b729e79f 100644 --- a/docs/zh-Hans/Multi-Tenancy.md +++ b/docs/zh-Hans/Multi-Tenancy.md @@ -139,7 +139,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.TenantResolvers.Add(new MyCustomTenantResolver()); }); @@ -194,7 +194,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Tenants = new[] { @@ -240,7 +240,7 @@ namespace MyCompany.MyProject { var configuration = BuildConfiguration(); - context.Services.Configure(configuration); + Configure(configuration); } private static IConfigurationRoot BuildConfiguration() @@ -362,7 +362,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { //子域名格式: {0}.mydomain.com (作为最高优先级解析器添加) options.TenantResolvers.Insert(0, new DomainTenantResolver("{0}.mydomain.com")); diff --git a/docs/zh-Hans/Virtual-File-System.md b/docs/zh-Hans/Virtual-File-System.md index 9207940952..e25d7f61b4 100644 --- a/docs/zh-Hans/Virtual-File-System.md +++ b/docs/zh-Hans/Virtual-File-System.md @@ -59,7 +59,7 @@ namespace MyCompany.MyProject { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { //Register all embedded files of this assembly to the virtual file system options.FileSets.AddEmbedded(); @@ -123,7 +123,7 @@ public class MyWebAppModule : AbpModule if (hostingEnvironment.IsDevelopment()) //only for development time { - context.Services.Configure(options => + Configure(options => { //ReplaceEmbeddedByPyhsical gets the root folder of the MyModule project options.FileSets.ReplaceEmbeddedByPyhsical( diff --git a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs index bb9d7bac7c..7f00a58069 100644 --- a/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.TenantResolvers.Add(new QueryStringTenantResolveContributer()); options.TenantResolvers.Add(new RouteTenantResolveContributer()); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs index bc0171a7d5..44a00808f8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp.AspNetCore.Mvc.UI.Bootstrap"); }); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs index 3e7ed57376..4b281770fd 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs @@ -31,7 +31,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form } } - // ReSharper disable once AssignNullToNotNullAttribute var selectItems = (properties.First().Model as IEnumerable).ToList(); return selectItems; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Anchor/AnchorJsScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Anchor/AnchorJsScriptBundleContributor.cs new file mode 100644 index 0000000000..e08a0c555a --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Anchor/AnchorJsScriptBundleContributor.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor +{ + [DependsOn(typeof(JQueryScriptContributor))] + public class AnchorJsScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/anchor-js/anchor.js"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs new file mode 100644 index 0000000000..4a0cc30100 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Clipboard/ClipboardScriptBundleContributor.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard +{ + public class ClipboardScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/clipboard/clipboard.js"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginScriptBundleContributor.cs new file mode 100644 index 0000000000..328299c36e --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginScriptBundleContributor.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar +{ + public class MalihuCustomScrollbarPluginScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginStyleBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginStyleBundleContributor.cs new file mode 100644 index 0000000000..3bf00dba84 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/MalihuCustomScrollbar/MalihuCustomScrollbarPluginStyleBundleContributor.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar +{ + public class MalihuCustomScrollbarPluginStyleBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.css"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Popper/PopperJsScriptBundleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Popper/PopperJsScriptBundleContributor.cs new file mode 100644 index 0000000000..bc9a6c4a6d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Popper/PopperJsScriptBundleContributor.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper +{ + public class PopperJsScriptBundleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/popper.js/popper.min.js"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs index 3cbb2d1030..f68df35d1f 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Themes.Add(); @@ -28,17 +28,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic } }); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic"); }); - context.Services.Configure(options => + Configure(options => { options.Contributors.Add(new BasicThemeMainTopToolbarContributor()); }); - context.Services.Configure(options => + Configure(options => { options .StyleBundles diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs index 4cf742b699..57a03d0d75 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs @@ -16,12 +16,12 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared"); }); - context.Services.Configure(options => + Configure(options => { options .StyleBundles diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs index 2d35d82ff6..10354b37d0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs @@ -1,10 +1,14 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard; using Volo.Abp.AspNetCore.Mvc.UI.Packages.DatatablesNetBs4; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Lodash; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2; using Volo.Abp.AspNetCore.Mvc.UI.Packages.SweetAlert; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Timeago; diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs index f9a07ac3a4..df5d127d98 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcModule.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.DependencyInjection; @@ -56,14 +57,14 @@ namespace Volo.Abp.AspNetCore.Mvc ) ); - context.Services.Configure(options => + Configure(options => { options.IgnoredInterfaces.AddIfNotContains(typeof(IAsyncActionFilter)); options.IgnoredInterfaces.AddIfNotContains(typeof(IFilterMetadata)); options.IgnoredInterfaces.AddIfNotContains(typeof(IActionFilter)); }); - context.Services.Configure(options => + Configure(options => { options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcModule).Assembly, o => { @@ -105,7 +106,7 @@ namespace Volo.Abp.AspNetCore.Mvc partManager.FeatureProviders.Add(new AbpConventionalControllerFeatureProvider(application)); - context.Services.Configure(mvcOptions => + Configure(mvcOptions => { mvcOptions.AddAbp(context.Services); }); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs index 2202e70cd1..e9e535c4be 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Aspects; +using Volo.Abp.AspNetCore.Mvc.Validation; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectMapping; @@ -31,8 +32,15 @@ namespace Volo.Abp.AspNetCore.Mvc public IClock Clock { get; set; } + public IModelStateValidator ModelValidator { get; set; } + public List AppliedCrossCuttingConcerns { get; } = new List(); + protected virtual void ValidateModel() + { + ModelValidator?.Validate(ModelState); + } + protected ILogger Logger => _lazyLogger.Value; private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index 7bd3cf8267..7bf8d305b3 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -32,7 +32,7 @@ namespace Volo.Abp.AspNetCore { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Contributors.Add(new AspNetCoreAuditLogContributor()); }); diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/DependencyInjection/HttpContextServiceScopeFactory.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/DependencyInjection/HttpContextServiceScopeFactory.cs new file mode 100644 index 0000000000..64952c3f97 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/DependencyInjection/HttpContextServiceScopeFactory.cs @@ -0,0 +1,53 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.DependencyInjection +{ + [ExposeServices( + typeof(IHybridServiceScopeFactory), + typeof(HttpContextServiceScopeFactory) + )] + [Dependency(ReplaceServices = true)] + public class HttpContextServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency + { + protected IHttpContextAccessor HttpContextAccessor { get; } + + protected IServiceScopeFactory ServiceScopeFactory { get; } + + public HttpContextServiceScopeFactory( + IHttpContextAccessor httpContextAccessor, + IServiceScopeFactory serviceScopeFactory) + { + HttpContextAccessor = httpContextAccessor; + ServiceScopeFactory = serviceScopeFactory; + } + + public virtual IServiceScope CreateScope() + { + var httpContext = HttpContextAccessor.HttpContext; + if (httpContext == null) + { + return ServiceScopeFactory.CreateScope(); + } + + return new NonDisposedHttpContextServiceScope(httpContext.RequestServices); + } + + protected class NonDisposedHttpContextServiceScope : IServiceScope + { + public IServiceProvider ServiceProvider { get; } + + public NonDisposedHttpContextServiceScope(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public void Dispose() + { + + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs index 51150244e7..5649503563 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.Authorization context.Services.AddSingleton(); - context.Services.Configure(options => + Configure(options => { options.ValueProviders.Add(); options.ValueProviders.Add(); diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs index fb66702186..59352bc892 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs @@ -1,8 +1,7 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; +using System; using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs @@ -11,14 +10,10 @@ namespace Volo.Abp.BackgroundJobs { public ILogger Logger { protected get; set; } - protected IServiceProvider ServiceProvider { get; } protected BackgroundJobOptions Options { get; } - public BackgroundJobExecuter( - IServiceProvider serviceProvider, - IOptions options) + public BackgroundJobExecuter(IOptions options) { - ServiceProvider = serviceProvider; Options = options.Value; Logger = NullLogger.Instance; @@ -26,34 +21,31 @@ namespace Volo.Abp.BackgroundJobs public virtual void Execute(JobExecutionContext context) { - using (var scope = ServiceProvider.CreateScope()) + var job = context.ServiceProvider.GetService(context.JobType); + if (job == null) { - var job = scope.ServiceProvider.GetService(context.JobType); - if (job == null) - { - throw new AbpException("The job type is not registered to DI: " + context.JobType); - } + throw new AbpException("The job type is not registered to DI: " + context.JobType); + } - var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob.Execute)); - if (jobExecuteMethod == null) - { - throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType); - } - - try - { - jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); - } - catch (Exception ex) + var jobExecuteMethod = context.JobType.GetMethod(nameof(IBackgroundJob.Execute)); + if (jobExecuteMethod == null) + { + throw new AbpException($"Given job type does not implement {typeof(IBackgroundJob<>).Name}. The job type was: " + context.JobType); + } + + try + { + jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); + } + catch (Exception ex) + { + Logger.LogException(ex); + + throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex) { - Logger.LogException(ex); - - throw new BackgroundJobExecutionException("A background job execution is failed. See inner exception for details.", ex) - { - JobType = context.JobType.AssemblyQualifiedName, - JobArgs = context.JobArgs - }; - } + JobType = context.JobType.AssemblyQualifiedName, + JobArgs = context.JobArgs + }; } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs index 7cdeed85bf..0f00b2ca36 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs @@ -1,15 +1,19 @@ using System; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs { - public class JobExecutionContext + public class JobExecutionContext : IServiceProviderAccessor { + public IServiceProvider ServiceProvider { get; } + public Type JobType { get; } public object JobArgs { get; } - public JobExecutionContext(Type jobType, object jobArgs) + public JobExecutionContext(IServiceProvider serviceProvider, Type jobType, object jobArgs) { + ServiceProvider = serviceProvider; JobType = jobType; JobArgs = jobArgs; } diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs index 2813aa92a1..48b2dea666 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs @@ -13,11 +13,20 @@ namespace Volo.Abp.BackgroundJobs.Hangfire { if (!delay.HasValue) { - return Task.FromResult(BackgroundJob.Enqueue>(adapter => adapter.Execute(args))); + return Task.FromResult( + BackgroundJob.Enqueue>( + adapter => adapter.Execute(args) + ) + ); } else { - return Task.FromResult(BackgroundJob.Schedule>(adapter => adapter.Execute(args), delay.Value)); + return Task.FromResult( + BackgroundJob.Schedule>( + adapter => adapter.Execute(args), + delay.Value + ) + ); } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs index c1858dc2b7..96c3b1ee0b 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs @@ -1,23 +1,32 @@ -using Microsoft.Extensions.Options; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; namespace Volo.Abp.BackgroundJobs.Hangfire { public class HangfireJobExecutionAdapter { protected BackgroundJobOptions Options { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } protected IBackgroundJobExecuter JobExecuter { get; } - public HangfireJobExecutionAdapter(IOptions options, IBackgroundJobExecuter jobExecuter) + public HangfireJobExecutionAdapter( + IOptions options, + IBackgroundJobExecuter jobExecuter, + IServiceScopeFactory serviceScopeFactory) { JobExecuter = jobExecuter; + ServiceScopeFactory = serviceScopeFactory; Options = options.Value; } public void Execute(TArgs args) { - var jobType = Options.GetJob(typeof(TArgs)).JobType; - var context = new JobExecutionContext(jobType, args); - JobExecuter.Execute(context); + using (var scope = ServiceScopeFactory.CreateScope()) + { + var jobType = Options.GetJob(typeof(TArgs)).JobType; + var context = new JobExecutionContext(scope.ServiceProvider, jobType, args); + JobExecuter.Execute(context); + } } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs index 38a9b2a121..e1f5da512c 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/JobQueue.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -28,6 +29,7 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ protected IChannelPool ChannelPool { get; } protected IRabbitMqSerializer Serializer { get; } protected IBackgroundJobExecuter JobExecuter { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } protected AsyncLock SyncObj = new AsyncLock(); protected bool IsDiposed { get; private set; } @@ -37,12 +39,14 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ IOptions rabbitMqBackgroundJobOptions, IChannelPool channelPool, IRabbitMqSerializer serializer, - IBackgroundJobExecuter jobExecuter) + IBackgroundJobExecuter jobExecuter, + IServiceScopeFactory serviceScopeFactory) { BackgroundJobOptions = backgroundJobOptions.Value; RabbitMqBackgroundJobOptions = rabbitMqBackgroundJobOptions.Value; Serializer = serializer; JobExecuter = jobExecuter; + ServiceScopeFactory = serviceScopeFactory; ChannelPool = channelPool; JobConfiguration = BackgroundJobOptions.GetJob(typeof(TArgs)); @@ -167,25 +171,29 @@ namespace Volo.Abp.BackgroundJobs.RabbitMQ protected virtual void MessageReceived(object sender, BasicDeliverEventArgs ea) { - var context = new JobExecutionContext( - JobConfiguration.JobType, - Serializer.Deserialize(ea.Body, typeof(TArgs)) - ); - - try - { - JobExecuter.Execute(context); - ChannelAccessor.Channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); - } - catch (BackgroundJobExecutionException) + using (var scope = ServiceScopeFactory.CreateScope()) { - //TODO: Reject like that? - ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true); - } - catch (Exception) - { - //TODO: Reject like that? - ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: false); + var context = new JobExecutionContext( + scope.ServiceProvider, + JobConfiguration.JobType, + Serializer.Deserialize(ea.Body, typeof(TArgs)) + ); + + try + { + JobExecuter.Execute(context); + ChannelAccessor.Channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); + } + catch (BackgroundJobExecutionException) + { + //TODO: Reject like that? + ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: true); + } + catch (Exception) + { + //TODO: Reject like that? + ChannelAccessor.Channel.BasicReject(deliveryTag: ea.DeliveryTag, requeue: false); + } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs index 964f076714..6aeead724d 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp.BackgroundWorkers; @@ -11,26 +12,26 @@ namespace Volo.Abp.BackgroundJobs public class BackgroundJobWorker : PeriodicBackgroundWorkerBase, IBackgroundJobWorker, ISingletonDependency { protected IBackgroundJobExecuter JobExecuter { get; } - protected IBackgroundJobStore Store { get; } protected BackgroundJobOptions JobOptions { get; } protected BackgroundJobWorkerOptions WorkerOptions { get; } protected IClock Clock { get; } protected IBackgroundJobSerializer Serializer { get; } + protected IServiceScopeFactory ServiceScopeFactory { get; } public BackgroundJobWorker( - IBackgroundJobStore store, AbpTimer timer, IBackgroundJobExecuter jobExecuter, IBackgroundJobSerializer serializer, IOptions jobOptions, IOptions workerOptions, - IClock clock) + IClock clock, + IServiceScopeFactory serviceScopeFactory) : base(timer) { JobExecuter = jobExecuter; Serializer = serializer; Clock = clock; - Store = store; + ServiceScopeFactory = serviceScopeFactory; WorkerOptions = workerOptions.Value; JobOptions = jobOptions.Value; Timer.Period = WorkerOptions.JobPollPeriod; @@ -38,53 +39,60 @@ namespace Volo.Abp.BackgroundJobs protected override void DoWork() { - var waitingJobs = AsyncHelper.RunSync(() => Store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount)); - - foreach (var jobInfo in waitingJobs) + using (var scope = ServiceScopeFactory.CreateScope()) { - jobInfo.TryCount++; - jobInfo.LastTryTime = Clock.Now; + var store = scope.ServiceProvider.GetRequiredService(); + + var waitingJobs = AsyncHelper.RunSync( + () => store.GetWaitingJobsAsync(WorkerOptions.MaxJobFetchCount) + ); - try + foreach (var jobInfo in waitingJobs) { - var jobConfiguration = JobOptions.GetJob(jobInfo.JobName); - var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType); - var context = new JobExecutionContext(jobConfiguration.JobType, jobArgs); + jobInfo.TryCount++; + jobInfo.LastTryTime = Clock.Now; try { - JobExecuter.Execute(context); - AsyncHelper.RunSync(() => Store.DeleteAsync(jobInfo.Id)); - } - catch (BackgroundJobExecutionException) - { - var nextTryTime = CalculateNextTryTime(jobInfo); - if (nextTryTime.HasValue) + var jobConfiguration = JobOptions.GetJob(jobInfo.JobName); + var jobArgs = Serializer.Deserialize(jobInfo.JobArgs, jobConfiguration.ArgsType); + var context = new JobExecutionContext(scope.ServiceProvider, jobConfiguration.JobType, jobArgs); + + try { - jobInfo.NextTryTime = nextTryTime.Value; + JobExecuter.Execute(context); + AsyncHelper.RunSync(() => store.DeleteAsync(jobInfo.Id)); } - else + catch (BackgroundJobExecutionException) { - jobInfo.IsAbandoned = true; - } + var nextTryTime = CalculateNextTryTime(jobInfo); + if (nextTryTime.HasValue) + { + jobInfo.NextTryTime = nextTryTime.Value; + } + else + { + jobInfo.IsAbandoned = true; + } - TryUpdate(jobInfo); + TryUpdate(store, jobInfo); + } + } + catch (Exception ex) + { + Logger.LogException(ex); + jobInfo.IsAbandoned = true; + TryUpdate(store, jobInfo); } - } - catch (Exception ex) - { - Logger.LogException(ex); - jobInfo.IsAbandoned = true; - TryUpdate(jobInfo); } } } - protected virtual void TryUpdate(BackgroundJobInfo jobInfo) + protected virtual void TryUpdate(IBackgroundJobStore store, BackgroundJobInfo jobInfo) { try { - Store.UpdateAsync(jobInfo); + store.UpdateAsync(jobInfo); } catch (Exception updateEx) { diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs index b8b897068f..c897a20e3a 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/DistributedCache.cs @@ -63,7 +63,10 @@ namespace Volo.Abp.Caching return ObjectSerializer.Deserialize(cachedBytes); } - public TCacheItem GetOrAdd(string key, Func factory) + public TCacheItem GetOrAdd( + string key, + Func factory, + Func optionsFactory = null) { var value = Get(key); if (value != null) @@ -80,14 +83,17 @@ namespace Volo.Abp.Caching } value = factory(); - Set(key, value); - + Set(key, value, optionsFactory?.Invoke()); } return value; } - public async Task GetOrAddAsync(string key, Func> factory, CancellationToken token = default) + public async Task GetOrAddAsync( + string key, + Func> factory, + Func optionsFactory = null, + CancellationToken token = default) { var value = await GetAsync(key, token); if (value != null) @@ -104,7 +110,7 @@ namespace Volo.Abp.Caching } value = await factory(); - await SetAsync(key, value, token: token); + await SetAsync(key, value, optionsFactory?.Invoke(), token); } return value; diff --git a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs index 5fd6d2d84f..1e21d3a3a6 100644 --- a/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs +++ b/framework/src/Volo.Abp.Caching/Volo/Abp/Caching/IDistributedCache.cs @@ -20,12 +20,14 @@ namespace Volo.Abp.Caching TCacheItem GetOrAdd( string key, - Func factory + Func factory, + Func optionsFactory = null ); Task GetOrAddAsync( [NotNull] string key, Func> factory, + Func optionsFactory = null, CancellationToken token = default ); diff --git a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs b/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs index 3fb7573858..a7cf7c763e 100644 --- a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs @@ -192,6 +192,19 @@ namespace System return str; } + public static string ReplaceFirst(this string str, string search, string replace, StringComparison comparisonType = StringComparison.Ordinal) + { + Check.NotNull(str, nameof(str)); + + var pos = str.IndexOf(search, comparisonType); + if (pos < 0) + { + return str; + } + + return str.Substring(0, pos) + replace + str.Substring(pos + search.Length); + } + /// /// Gets a substring of a string from end of the string. /// diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/DefaultServiceScopeFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/DefaultServiceScopeFactory.cs new file mode 100644 index 0000000000..36af7a210a --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/DefaultServiceScopeFactory.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.DependencyInjection +{ + [ExposeServices( + typeof(IHybridServiceScopeFactory), + typeof(DefaultServiceScopeFactory) + )] + public class DefaultServiceScopeFactory : IHybridServiceScopeFactory, ITransientDependency + { + protected IServiceScopeFactory Factory { get; } + + public DefaultServiceScopeFactory(IServiceScopeFactory factory) + { + Factory = factory; + } + + public IServiceScope CreateScope() + { + return Factory.CreateScope(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IHybridServiceScopeFactory.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IHybridServiceScopeFactory.cs new file mode 100644 index 0000000000..207d7d33c2 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IHybridServiceScopeFactory.cs @@ -0,0 +1,9 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Volo.Abp.DependencyInjection +{ + public interface IHybridServiceScopeFactory : IServiceScopeFactory + { + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs index 766507b840..0f4514a066 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/IO/FileHelper.cs @@ -1,4 +1,5 @@ using System.IO; +using JetBrains.Annotations; namespace Volo.Abp.IO { @@ -18,5 +19,27 @@ namespace Volo.Abp.IO File.Delete(filePath); } } + + /// + /// Gets extension of a file. + /// + /// + /// + /// Returns extension without dot. + /// Returns null if given does not include dot. + /// + [CanBeNull] + public static string GetExtension([NotNull] string fileNameWithExtension) + { + Check.NotNull(fileNameWithExtension, nameof(fileNameWithExtension)); + + var lastDotIndex = fileNameWithExtension.LastIndexOf('.'); + if (lastDotIndex < 0) + { + return null; + } + + return fileNameWithExtension.Substring(lastDotIndex + 1); + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs index bf26793a01..838050c067 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/AbpDddApplicationModule.cs @@ -23,7 +23,7 @@ namespace Volo.Abp.Application { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.IgnoredInterfaces.AddIfNotContains(typeof(IRemoteService)); options.IgnoredInterfaces.AddIfNotContains(typeof(IApplicationService)); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs index b236e6f7e4..dc4edea364 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Entities/Events/EntityChangeEventHelper.cs @@ -126,7 +126,7 @@ namespace Volo.Abp.Domain.Entities.Events } } - protected virtual async Task TriggerEventWithEntity(IEventPublisher eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork) + protected virtual async Task TriggerEventWithEntity(IEventBus eventPublisher, Type genericEventType, object entity, bool triggerInCurrentUnitOfWork) { var entityType = ProxyHelper.UnProxy(entity).GetType(); var eventType = genericEventType.MakeGenericType(entityType); diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs index 629052f631..4a23ecae9a 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs @@ -19,12 +19,12 @@ namespace Volo.Abp.Emailing { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.Add(); }); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); @@ -34,7 +34,7 @@ namespace Volo.Abp.Emailing options.AddJob(); }); - context.Services.Configure(options => + Configure(options => { options.Templates .Add( diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 87c9ec6153..b5860824cc 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -84,12 +84,8 @@ namespace Volo.Abp.EntityFrameworkCore //TODO: Reduce duplications with SaveChangesAsync //TODO: Instead of adding entity changes to audit log, write them to uow and add to audit log only if uow succeed - ChangeTracker.DetectChanges(); - try { - ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed? - var auditLog = AuditingManager?.Current?.Log; List entityChangeList = null; @@ -124,12 +120,8 @@ namespace Volo.Abp.EntityFrameworkCore public override async Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { - ChangeTracker.DetectChanges(); - try { - ChangeTracker.AutoDetectChangesEnabled = false; //TODO: Why this is needed? - var auditLog = AuditingManager?.Current?.Log; List entityChangeList = null; diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs index 8616b2ca64..d6efe467bc 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.EntityFrameworkCore { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.PreConfigure(abpDbContextConfigurationContext => { diff --git a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs index 3cd7cfbe03..99173ee333 100644 --- a/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Distributed.RabbitMQ/Volo/Abp/EventBus/Distributed/RabbitMq/RabbitMqDistributedEventBus.cs @@ -30,18 +30,18 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq protected ConcurrentDictionary> HandlerFactories { get; } //TODO: Accessing to the List may not be thread-safe! protected ConcurrentDictionary EventTypes { get; } protected IModel ConsumerChannel; - protected IServiceProvider ServiceProvider { get; } + protected IHybridServiceScopeFactory ServiceScopeFactory { get; } public RabbitMqDistributedEventBus( IOptions options, IConnectionPool connectionPool, IRabbitMqSerializer serializer, - IServiceProvider serviceProvider, + IHybridServiceScopeFactory serviceScopeFactory, IOptions distributedEventBusOptions) { ConnectionPool = connectionPool; Serializer = serializer; - ServiceProvider = serviceProvider; + ServiceScopeFactory = serviceScopeFactory; DistributedEventBusOptions = distributedEventBusOptions.Value; RabbitMqDistributedEventBusOptions = options.Value; @@ -67,7 +67,7 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { - Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler)); + Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); } } } @@ -124,6 +124,11 @@ namespace Volo.Abp.EventBus.Distributed.RabbitMq channel.BasicAck(ea.DeliveryTag, multiple: false); } + public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class + { + return Subscribe(typeof(TEvent), handler); + } + public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) { var handlerFactories = GetOrCreateHandlerFactories(eventType); diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs index f17fd05446..3729b48b61 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/AbpEventBusModule.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; -using System.Linq; using Volo.Abp.EventBus.Distributed; using Volo.Abp.EventBus.Local; using Volo.Abp.Modularity; @@ -23,15 +22,14 @@ namespace Volo.Abp.EventBus services.OnRegistred(context => { - if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IEventHandler<>))) + if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(ILocalEventHandler<>))) { localHandlers.Add(context.ImplementationType); } - //TODO: Distrbiuted event bus is disabled since it's not properly working yet for v0.8 release - //else if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IDistributedEventHandler<>))) - //{ - // distributedHandlers.Add(context.ImplementationType); - //} + else if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(IDistributedEventHandler<>))) + { + distributedHandlers.Add(context.ImplementationType); + } }); services.Configure(options => diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs index 995ce39356..a8763edd89 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/ActionEventHandler.cs @@ -5,11 +5,11 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.EventBus { /// - /// This event handler is an adapter to be able to use an action as implementation. + /// This event handler is an adapter to be able to use an action as implementation. /// /// Event type public class ActionEventHandler : - IEventHandler, + ILocalEventHandler, ITransientDependency { /// diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalEventBusOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusOptions.cs similarity index 100% rename from framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalEventBusOptions.cs rename to framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusOptions.cs diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs index 88cbf721b3..e406f7069b 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IDistributedEventBus.cs @@ -1,7 +1,16 @@ -namespace Volo.Abp.EventBus.Distributed +using System; + +namespace Volo.Abp.EventBus.Distributed { public interface IDistributedEventBus : IEventBus { - + /// + /// Registers to an event. + /// Same (given) instance of the handler is used for all event occurrences. + /// + /// Event type + /// Object to handle the event + IDisposable Subscribe(IDistributedEventHandler handler) + where TEvent : class; } } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs index 30278c6b21..ab23119642 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus.cs @@ -10,19 +10,19 @@ namespace Volo.Abp.EventBus.Distributed { [Dependency(TryRegister = true)] [ExposeServices(typeof(IDistributedEventBus), typeof(LocalDistributedEventBus))] - public class LocalDistributedEventBus : IDistributedEventBus, ITransientDependency + public class LocalDistributedEventBus : IDistributedEventBus, ISingletonDependency { private readonly ILocalEventBus _localEventBus; - protected IServiceProvider ServiceProvider { get; } + protected IHybridServiceScopeFactory ServiceScopeFactory { get; } protected DistributedEventBusOptions DistributedEventBusOptions { get; } public LocalDistributedEventBus( - ILocalEventBus localEventBus, - IServiceProvider serviceProvider, + ILocalEventBus localEventBus, + IHybridServiceScopeFactory serviceScopeFactory, IOptions distributedEventBusOptions) { _localEventBus = localEventBus; - ServiceProvider = serviceProvider; + ServiceScopeFactory = serviceScopeFactory; DistributedEventBusOptions = distributedEventBusOptions.Value; Subscribe(distributedEventBusOptions.Value.Handlers); } @@ -42,18 +42,24 @@ namespace Volo.Abp.EventBus.Distributed var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { - Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler)); + Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); } } } } + /// + public virtual IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class + { + return Subscribe(typeof(TEvent), handler); + } + public IDisposable Subscribe(Func action) where TEvent : class { return _localEventBus.Subscribe(action); } - public IDisposable Subscribe(IEventHandler handler) where TEvent : class + public IDisposable Subscribe(ILocalEventHandler handler) where TEvent : class { return _localEventBus.Subscribe(handler); } @@ -83,7 +89,7 @@ namespace Volo.Abp.EventBus.Distributed _localEventBus.Unsubscribe(action); } - public void Unsubscribe(IEventHandler handler) where TEvent : class + public void Unsubscribe(ILocalEventHandler handler) where TEvent : class { _localEventBus.Unsubscribe(handler); } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullLocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullDistributedEventBus.cs similarity index 92% rename from framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullLocalEventBus.cs rename to framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullDistributedEventBus.cs index cc59b9a24b..cfec832893 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullLocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/NullDistributedEventBus.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.EventBus.Distributed return NullDisposable.Instance; } - public IDisposable Subscribe(IEventHandler handler) where TEvent : class + public IDisposable Subscribe(IDistributedEventHandler handler) where TEvent : class { return NullDisposable.Instance; } @@ -47,7 +47,7 @@ namespace Volo.Abp.EventBus.Distributed } - public void Unsubscribe(IEventHandler handler) where TEvent : class + public void Unsubscribe(ILocalEventHandler handler) where TEvent : class { } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs index e0c0340f15..c700f46532 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Reflection; -namespace Volo.Abp.EventBus.Local +namespace Volo.Abp.EventBus { public abstract class EventBusBase : IEventBus { @@ -18,12 +18,6 @@ namespace Volo.Abp.EventBus.Local return Subscribe(typeof(TEvent), new ActionEventHandler(action)); } - /// - public virtual IDisposable Subscribe(IEventHandler handler) where TEvent : class - { - return Subscribe(typeof(TEvent), handler); - } - /// public virtual IDisposable Subscribe() where TEvent : class @@ -49,7 +43,7 @@ namespace Volo.Abp.EventBus.Local public abstract void Unsubscribe(Func action) where TEvent : class; /// - public virtual void Unsubscribe(IEventHandler handler) where TEvent : class + public virtual void Unsubscribe(ILocalEventHandler handler) where TEvent : class { Unsubscribe(typeof(TEvent), handler); } @@ -138,12 +132,12 @@ namespace Volo.Abp.EventBus.Local { var handlerType = eventHandlerWrapper.EventHandler.GetType(); - if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IEventHandler<>))) + if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(ILocalEventHandler<>))) { - var method = typeof(IEventHandler<>) //TODO: to a static field + var method = typeof(ILocalEventHandler<>) .MakeGenericType(eventType) .GetMethod( - nameof(IEventHandler.HandleEventAsync), + nameof(ILocalEventHandler.HandleEventAsync), new[] { eventType } ); @@ -151,7 +145,7 @@ namespace Volo.Abp.EventBus.Local } else if (ReflectionHelper.IsAssignableToGenericType(handlerType, typeof(IDistributedEventHandler<>))) { - var method = typeof(IDistributedEventHandler<>) //TODO: to a static field + var method = typeof(IDistributedEventHandler<>) .MakeGenericType(eventType) .GetMethod( nameof(IDistributedEventHandler.HandleEventAsync), diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs index a5d1c27a15..4526c1f3b4 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs @@ -1,7 +1,119 @@ +using System; +using System.Threading.Tasks; + namespace Volo.Abp.EventBus { - public interface IEventBus : IEventSubscriber, IEventPublisher + public interface IEventBus { + /// + /// Triggers an event asynchronously. + /// + /// Event type + /// Related data for the event + /// The task to handle async operation + Task PublishAsync(TEvent eventData) + where TEvent : class; + + /// + /// Triggers an event asynchronously. + /// + /// Event type + /// Related data for the event + /// The task to handle async operation + Task PublishAsync(Type eventType, object eventData); + + /// + /// Registers to an event. + /// Given action is called for all event occurrences. + /// + /// Action to handle events + /// Event type + IDisposable Subscribe(Func action) + where TEvent : class; + + /// + /// Registers to an event. + /// A new instance of object is created for every event occurrence. + /// + /// Event type + /// Type of the event handler + IDisposable Subscribe() + where TEvent : class + where THandler : IEventHandler, new(); + + /// + /// Registers to an event. + /// Same (given) instance of the handler is used for all event occurrences. + /// + /// Event type + /// Object to handle the event + IDisposable Subscribe(Type eventType, IEventHandler handler); + + /// + /// Registers to an event. + /// Given factory is used to create/release handlers + /// + /// Event type + /// A factory to create/release handlers + IDisposable Subscribe(IEventHandlerFactory factory) + where TEvent : class; + + /// + /// Registers to an event. + /// + /// Event type + /// A factory to create/release handlers + IDisposable Subscribe(Type eventType, IEventHandlerFactory factory); + + /// + /// Unregisters from an event. + /// + /// Event type + /// + void Unsubscribe(Func action) + where TEvent : class; + + /// + /// Unregisters from an event. + /// + /// Event type + /// Handler object that is registered before + void Unsubscribe(ILocalEventHandler handler) + where TEvent : class; + + /// + /// Unregisters from an event. + /// + /// Event type + /// Handler object that is registered before + void Unsubscribe(Type eventType, IEventHandler handler); + + /// + /// Unregisters from an event. + /// + /// Event type + /// Factory object that is registered before + void Unsubscribe(IEventHandlerFactory factory) + where TEvent : class; + + /// + /// Unregisters from an event. + /// + /// Event type + /// Factory object that is registered before + void Unsubscribe(Type eventType, IEventHandlerFactory factory); + + /// + /// Unregisters all event handlers of given event type. + /// + /// Event type + void UnsubscribeAll() + where TEvent : class; + /// + /// Unregisters all event handlers of given event type. + /// + /// Event type + void UnsubscribeAll(Type eventType); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs index ca3993c6bc..6397813637 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventHandler.cs @@ -1,26 +1,13 @@ -using System.Threading.Tasks; +using Volo.Abp.EventBus.Distributed; namespace Volo.Abp.EventBus { /// /// Undirect base interface for all event handlers. - /// Implement instead of this one. + /// Implement or instead of this one. /// public interface IEventHandler { } - - /// - /// Defines an interface of a class that handles events asynchrounously of type . - /// - /// Event type to handle - public interface IEventHandler : IEventHandler - { - /// - /// Handler handles the event by implementing this method. - /// - /// Event data - Task HandleEventAsync(TEvent eventData); - } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventPublisher.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventPublisher.cs deleted file mode 100644 index 0192522304..0000000000 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventPublisher.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Volo.Abp.EventBus -{ - public interface IEventPublisher - { - /// - /// Triggers an event asynchronously. - /// - /// Event type - /// Related data for the event - /// The task to handle async operation - Task PublishAsync(TEvent eventData) - where TEvent : class; - - /// - /// Triggers an event asynchronously. - /// - /// Event type - /// Related data for the event - /// The task to handle async operation - Task PublishAsync(Type eventType, object eventData); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventSubscriber.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventSubscriber.cs deleted file mode 100644 index 86330433ea..0000000000 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventSubscriber.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace Volo.Abp.EventBus -{ - public interface IEventSubscriber - { - /// - /// Registers to an event. - /// Given action is called for all event occurrences. - /// - /// Action to handle events - /// Event type - IDisposable Subscribe(Func action) - where TEvent : class; - - /// - /// Registers to an event. - /// Same (given) instance of the handler is used for all event occurrences. - /// - /// Event type - /// Object to handle the event - IDisposable Subscribe(IEventHandler handler) - where TEvent : class; - - /// - /// Registers to an event. - /// A new instance of object is created for every event occurrence. - /// - /// Event type - /// Type of the event handler - IDisposable Subscribe() - where TEvent : class - where THandler : IEventHandler, new(); - - /// - /// Registers to an event. - /// Same (given) instance of the handler is used for all event occurrences. - /// - /// Event type - /// Object to handle the event - IDisposable Subscribe(Type eventType, IEventHandler handler); - - /// - /// Registers to an event. - /// Given factory is used to create/release handlers - /// - /// Event type - /// A factory to create/release handlers - IDisposable Subscribe(IEventHandlerFactory factory) - where TEvent : class; - - /// - /// Registers to an event. - /// - /// Event type - /// A factory to create/release handlers - IDisposable Subscribe(Type eventType, IEventHandlerFactory factory); - - /// - /// Unregisters from an event. - /// - /// Event type - /// - void Unsubscribe(Func action) - where TEvent : class; - - /// - /// Unregisters from an event. - /// - /// Event type - /// Handler object that is registered before - void Unsubscribe(IEventHandler handler) - where TEvent : class; - - /// - /// Unregisters from an event. - /// - /// Event type - /// Handler object that is registered before - void Unsubscribe(Type eventType, IEventHandler handler); - - /// - /// Unregisters from an event. - /// - /// Event type - /// Factory object that is registered before - void Unsubscribe(IEventHandlerFactory factory) - where TEvent : class; - - /// - /// Unregisters from an event. - /// - /// Event type - /// Factory object that is registered before - void Unsubscribe(Type eventType, IEventHandlerFactory factory); - - /// - /// Unregisters all event handlers of given event type. - /// - /// Event type - void UnsubscribeAll() - where TEvent : class; - - /// - /// Unregisters all event handlers of given event type. - /// - /// Event type - void UnsubscribeAll(Type eventType); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs index 9d388bae74..d944afae42 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IocEventHandlerFactory.cs @@ -1,5 +1,6 @@ using System; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.EventBus { @@ -13,13 +14,10 @@ namespace Volo.Abp.EventBus protected IServiceScope ServiceScope { get; } - //TODO: Consider to inject IServiceScopeFactory instead - public IocEventHandlerFactory(IServiceProvider serviceProvider, Type handlerType) + public IocEventHandlerFactory(IHybridServiceScopeFactory scopeFactory, Type handlerType) { HandlerType = handlerType; - ServiceScope = serviceProvider - .GetRequiredService() - .CreateScope(); + ServiceScope = scopeFactory.CreateScope(); } /// diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs index 7e81a363af..5640a4c17b 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventBus.cs @@ -1,3 +1,5 @@ +using System; + namespace Volo.Abp.EventBus.Local { /// @@ -5,6 +7,13 @@ namespace Volo.Abp.EventBus.Local /// public interface ILocalEventBus : IEventBus { - + /// + /// Registers to an event. + /// Same (given) instance of the handler is used for all event occurrences. + /// + /// Event type + /// Object to handle the event + IDisposable Subscribe(ILocalEventHandler handler) + where TEvent : class; } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventHandler.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventHandler.cs new file mode 100644 index 0000000000..e3501294be --- /dev/null +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/ILocalEventHandler.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.EventBus +{ + public interface ILocalEventHandler : IEventHandler + { + /// + /// Handler handles the event by implementing this method. + /// + /// Event data + Task HandleEventAsync(TEvent eventData); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs index 07a9e609e5..ae1041c9e2 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/LocalEventBus.cs @@ -28,13 +28,13 @@ namespace Volo.Abp.EventBus.Local protected ConcurrentDictionary> HandlerFactories { get; } - protected IServiceProvider ServiceProvider { get; } + protected IHybridServiceScopeFactory ServiceScopeFactory { get; } public LocalEventBus( IOptions options, - IServiceProvider serviceProvider) + IHybridServiceScopeFactory serviceScopeFactory) { - ServiceProvider = serviceProvider; + ServiceScopeFactory = serviceScopeFactory; Options = options.Value; Logger = NullLogger.Instance; @@ -57,12 +57,18 @@ namespace Volo.Abp.EventBus.Local var genericArgs = @interface.GetGenericArguments(); if (genericArgs.Length == 1) { - Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceProvider, handler)); + Subscribe(genericArgs[0], new IocEventHandlerFactory(ServiceScopeFactory, handler)); } } } } + /// + public virtual IDisposable Subscribe(ILocalEventHandler handler) where TEvent : class + { + return Subscribe(typeof(TEvent), handler); + } + /// public override IDisposable Subscribe(Type eventType, IEventHandlerFactory factory) { diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs index 494db3edd1..5c74af2195 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Local/NullLocalEventBus.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.EventBus.Local return NullDisposable.Instance; } - public IDisposable Subscribe(IEventHandler handler) where TEvent : class + public IDisposable Subscribe(ILocalEventHandler handler) where TEvent : class { return NullDisposable.Instance; } @@ -47,7 +47,7 @@ namespace Volo.Abp.EventBus.Local } - public void Unsubscribe(IEventHandler handler) where TEvent : class + public void Unsubscribe(ILocalEventHandler handler) where TEvent : class { } diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs index fe5bf8892e..6cacc3522d 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/TransientEventHandlerFactory.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.EventBus /// /// This class always creates a new transient instance of handler. /// - internal class TransientEventHandlerFactory : IEventHandlerFactory + public class TransientEventHandlerFactory : IEventHandlerFactory where THandler : IEventHandler, new() { /// diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs index 689980f03f..3f53ccbb1c 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/AbpHttpModule.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.Http { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Generators[JQueryProxyScriptGenerator.Name] = typeof(JQueryProxyScriptGenerator); }); diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs index bb58cdaecf..850a070c8f 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/MimeTypes.cs @@ -1,4 +1,6 @@ -namespace Volo.Abp.Http +using System; + +namespace Volo.Abp.Http { /* Taken from https://gist.github.com/markwhitaker/b29c0142360714688a7cf863ab33e5c9 */ @@ -83,5 +85,26 @@ public const string Quicktime = "video/quicktime"; public const string Webm = "video/webm"; } + + public static string GetByExtension(string extension) + { + extension = extension.RemovePreFix(".").ToLowerInvariant(); + + switch (extension) + { + case "png": + return Image.Png; + case "gif": + return Image.Gif; + case "jpg": + case "jpeg": + return Image.Jpeg; + + //TODO: Add other extensions too.. + + default: + return Application.OctetStream; + } + } } } diff --git a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj index 239e6df688..0acdb08627 100644 --- a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj +++ b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj @@ -17,10 +17,6 @@ - - - - diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs index ede10efaf1..c94d881030 100644 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs @@ -16,19 +16,19 @@ namespace Volo.Abp.Localization { AbpStringLocalizerFactory.Replace(context.Services); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp", "Volo/Abp"); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") .AddVirtualJson("/Localization/Resources/AbpValidation"); }); - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.Add(); }); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs index f68440da9f..05fc338c67 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/AbpMultiTenancyAbstractionsModule.cs @@ -11,7 +11,7 @@ namespace Volo.Abp.MultiTenancy { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.ValueProviders.Add(); }); diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs index ac969fd06b..587d0d52db 100644 --- a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpIntegratedTest.cs @@ -4,6 +4,8 @@ using Volo.Abp.Modularity; namespace Volo.Abp { + //TODO: Move to "Testing" namespace + public abstract class AbpIntegratedTest : AbpTestBaseWithServiceProvider, IDisposable where TStartupModule : IAbpModule { diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs index d956149842..fc262f5447 100644 --- a/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/AbpTestBaseModule.cs @@ -1,13 +1,9 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Modularity; +using Volo.Abp.Modularity; namespace Volo.Abp { public class AbpTestBaseModule : AbpModule { - public override void ConfigureServices(ServiceConfigurationContext context) - { - - } + } } diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/ITestCounter.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/ITestCounter.cs new file mode 100644 index 0000000000..2764dcb24e --- /dev/null +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/ITestCounter.cs @@ -0,0 +1,13 @@ +namespace Volo.Abp.Testing.Utils +{ + public interface ITestCounter + { + int Add(string name, int count); + + int Decrement(string name); + + int Increment(string name); + + int GetValue(string name); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/TestCounter.cs b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/TestCounter.cs new file mode 100644 index 0000000000..651a16836e --- /dev/null +++ b/framework/src/Volo.Abp.TestBase/Volo/Abp/Testing/Utils/TestCounter.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Testing.Utils +{ + public class TestCounter : ITestCounter, ISingletonDependency + { + private readonly Dictionary _values; + + public TestCounter() + { + _values = new Dictionary(); + } + + public int Increment(string name) + { + return Add(name, 1); + } + + public int Decrement(string name) + { + return Add(name, -1); + } + + public int Add(string name, int count) + { + lock (_values) + { + var newValue = _values.GetOrDefault(name) + count; + _values[name] = newValue; + return newValue; + } + } + + public int GetValue(string name) + { + lock (_values) + { + return _values.GetOrDefault(name); + } + } + } +} diff --git a/framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj b/framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj index a13fca4acd..1a7ab915c9 100644 --- a/framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj +++ b/framework/src/Volo.Abp.UI/Volo.Abp.UI.csproj @@ -16,10 +16,6 @@ - - - - diff --git a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs index 9198e6be6c..fb173ee882 100644 --- a/framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs +++ b/framework/src/Volo.Abp.UI/Volo/Abp/Ui/AbpUiModule.cs @@ -13,12 +13,12 @@ namespace Volo.Abp.UI { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources.Add("en").AddVirtualJson("/Localization/Resources/AbpUi"); }); diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs index d46893d590..508fb1db4f 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/ChildUnitOfWork.cs @@ -15,6 +15,10 @@ namespace Volo.Abp.Uow public bool IsReserved => _parent.IsReserved; + public bool IsDisposed => _parent.IsDisposed; + + public bool IsCompleted => _parent.IsCompleted; + public string ReservationName => _parent.ReservationName; public event EventHandler Failed; diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs index 6fe2546965..cdf1a505b8 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWork.cs @@ -20,6 +20,10 @@ namespace Volo.Abp.Uow bool IsReserved { get; } + bool IsDisposed { get; } + + bool IsCompleted { get; } + string ReservationName { get; } void SetOuter([CanBeNull] IUnitOfWork outer); diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs index 3f5a9cebf7..f6501ae833 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs @@ -18,6 +18,10 @@ namespace Volo.Abp.Uow public bool IsReserved { get; set; } + public bool IsDisposed { get; private set; } + + public bool IsCompleted { get; private set; } + public string ReservationName { get; set; } protected List> CompletedHandlers { get; } = new List>(); @@ -32,8 +36,7 @@ namespace Volo.Abp.Uow private readonly UnitOfWorkDefaultOptions _defaultOptions; private Exception _exception; - private bool _isCompleted; - private bool _isDisposed; + private bool _isCompleting; private bool _isRolledback; public UnitOfWork(IServiceProvider serviceProvider, IOptions options) @@ -101,8 +104,10 @@ namespace Volo.Abp.Uow try { + _isCompleting = true; SaveChanges(); CommitTransactions(); + IsCompleted = true; OnCompleted(); } catch (Exception ex) @@ -123,8 +128,10 @@ namespace Volo.Abp.Uow try { + _isCompleting = true; await SaveChangesAsync(cancellationToken); await CommitTransactionsAsync(); + IsCompleted = true; await OnCompletedAsync(); } catch (Exception ex) @@ -250,16 +257,16 @@ namespace Volo.Abp.Uow public virtual void Dispose() { - if (_isDisposed) + if (IsDisposed) { return; } - _isDisposed = true; + IsDisposed = true; DisposeTransactions(); - if (!_isCompleted || _exception != null) + if (!IsCompleted || _exception != null) { OnFailed(); } @@ -283,15 +290,12 @@ namespace Volo.Abp.Uow private void PreventMultipleComplete() { - if (_isCompleted) + if (IsCompleted || _isCompleting) { throw new AbpException("Complete is called before!"); } - - _isCompleted = true; } - protected virtual void RollbackAll() { foreach (var databaseApi in _databaseApis.Values) diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs index 447a6c182e..4523f8f8f7 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkManager.cs @@ -23,9 +23,10 @@ namespace Volo.Abp.Uow { Check.NotNull(options, nameof(options)); - if (!requiresNew && _ambientUnitOfWork.UnitOfWork != null && !_ambientUnitOfWork.UnitOfWork.IsReserved) + var currentUow = Current; + if (currentUow != null && !requiresNew) { - return new ChildUnitOfWork(_ambientUnitOfWork.UnitOfWork); + return new ChildUnitOfWork(currentUow); } var unitOfWork = CreateNewUnitOfWork(); @@ -86,7 +87,7 @@ namespace Volo.Abp.Uow var uow = _ambientUnitOfWork.UnitOfWork; //Skip reserved unit of work - while (uow != null && uow.IsReserved) + while (uow != null && (uow.IsReserved || uow.IsDisposed || uow.IsCompleted)) { uow = uow.Outer; } diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs index 57d4202aa2..8ef50ce9f7 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/AbpValidationException.cs @@ -20,7 +20,7 @@ namespace Volo.Abp.Validation /// /// Detailed list of validation errors for this exception. /// - public IList ValidationErrors { get; set; } + public IList ValidationErrors { get; } /// /// Exception severity. diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs index 67cbbc908d..f7d4b2fe92 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/IHasValidationErrors.cs @@ -5,6 +5,6 @@ namespace Volo.Abp.Validation { public interface IHasValidationErrors { - IList ValidationErrors { get; set; } + IList ValidationErrors { get; } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs index ccdb332aef..ffc03b5ff2 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/App/AppModule.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.App { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.AddDomainTenantResolver("{0}.abp.io"); }); diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index 66b23b058a..07509841f1 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -19,10 +19,6 @@ - - - - diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs index 65595b1b48..94e020a365 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs @@ -1,4 +1,5 @@ using System; +using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Modularity; @@ -9,9 +10,11 @@ using Volo.Abp.AspNetCore.TestBase; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Autofac; using Volo.Abp.Localization; +using Volo.Abp.Localization.Resources.AbpValidation; using Volo.Abp.MemoryDb; using Volo.Abp.Modularity; using Volo.Abp.TestApp; +using Volo.Abp.UI; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.AspNetCore.Mvc @@ -45,7 +48,7 @@ namespace Volo.Abp.AspNetCore.Mvc }); }); - context.Services.Configure(options => + Configure(options => { options.ConventionalControllers.Create(typeof(TestAppModule).Assembly, opts => { @@ -56,21 +59,24 @@ namespace Volo.Abp.AspNetCore.Mvc }); }); - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.Add(); }); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") - .AddVirtualJson("/Volo/Abp/AspNetCore/Mvc/Localization/Resource"); + .AddBaseTypes( + typeof(AbpUiResource), + typeof(AbpValidationResource) + ).AddVirtualJson("/Volo/Abp/AspNetCore/Mvc/Localization/Resource"); }); } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json index fb353b16d6..2451c1b294 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/en.json @@ -1,6 +1,7 @@ { "culture": "en", "texts": { - "BirthDate": "Birth date" + "BirthDate": "Birth date", + "Value1": "Value One" } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json index 21c274bd42..546e672ede 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/tr.json @@ -1,6 +1,7 @@ { "culture": "tr", "texts": { - "BirthDate": "Dogum gunu" + "BirthDate": "Dogum gunu", + "Value1": "Değer Bir" } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs index fb9381babc..19a4bcd608 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Validation/ValidationTestController_Tests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Shouldly; using Volo.Abp.Http; +using Volo.Abp.Localization; using Xunit; namespace Volo.Abp.AspNetCore.Mvc.Validation @@ -22,6 +23,17 @@ namespace Volo.Abp.AspNetCore.Mvc.Validation result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); } + [Fact] + public async Task Should_Return_Localized_Validation_Errors() + { + using (AbpCultureHelper.Use("tr")) + { + var result = await GetResponseAsObjectAsync("/api/validation-test/object-result-action?value1=a", HttpStatusCode.BadRequest); //value1 has min length of 2 chars. + result.Error.ValidationErrors.Length.ShouldBeGreaterThan(0); + result.Error.ValidationErrors[0].Message.ShouldBe("Değer Bir alanı en az '2' uzunluğunda bir metin ya da dizi olmalıdır."); + } + } + [Fact] public async Task Should_Not_Validate_Action_Result_Success() { diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json index 1797133380..e3b8137a6f 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/publish-ignore.json @@ -1,3 +1,3 @@ { - -} + "app_offline.htm": {} +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs index 1c0f3feea6..2a4a399d28 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo/Abp/AspNetCore/Mvc/Versioning/AbpAspNetCoreMvcVersioningTestModule.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { //2.0 Version options.ConventionalControllers.Create(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly, opts => @@ -49,7 +49,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Versioning context.Services.AddHttpClientProxies(typeof(AbpAspNetCoreMvcVersioningTestModule).Assembly); - context.Services.Configure(options => + Configure(options => { options.RemoteServices.Default = new RemoteServiceConfiguration("/"); }); diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs index 5f563e8384..9b539e85be 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs @@ -23,7 +23,7 @@ namespace Volo.Abp.Authorization public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.TryAdd(); }); diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs index 76861a5389..b0ecff941a 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_ConfigurationValidation_Tests.cs @@ -28,7 +28,7 @@ namespace Volo.Abp.AutoMapper { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.UseStaticMapper = false; diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs index 19bb8aa5c8..86eade5db8 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.AutoMapper { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.UseStaticMapper = false; }); diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs index 2affc47d97..566c69c318 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs @@ -25,6 +25,7 @@ namespace Volo.Abp.BackgroundJobs _backgroundJobExecuter.Execute( new JobExecutionContext( + ServiceProvider, typeof(MyJob), new MyJobArgs("42") ) diff --git a/framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs b/framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs index 503abf7156..8a818a75cb 100644 --- a/framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/System/StringExtensions_Tests.cs @@ -187,6 +187,14 @@ namespace System "Https://abp.io".RemovePreFix(StringComparison.OrdinalIgnoreCase, "https://").ShouldBe("abp.io"); } + [Fact] + public void ReplaceFirst_Tests() + { + "Test string".ReplaceFirst("s", "X").ShouldBe("TeXt string"); + "Test test test".ReplaceFirst("test", "XX").ShouldBe("Test XX test"); + "Test test test".ReplaceFirst("test", "XX", StringComparison.OrdinalIgnoreCase).ShouldBe("XX test test"); + } + [Fact] public void ToEnum_Test() { diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs new file mode 100644 index 0000000000..42bb7bb800 --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/DependencyInjection/HybridServiceScopeFactory_Tests.cs @@ -0,0 +1,41 @@ +using System; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.DependencyInjection +{ + public class HybridServiceScopeFactory_Tests + { + [Fact] + public void Should_Use_Default_ServiceScopeFactory_By_Default() + { + using (var application = AbpApplicationFactory.Create()) + { + application.Services.AddType(typeof(MyService)); + + application.Initialize(); + + var serviceScopeFactory = application.ServiceProvider.GetRequiredService(); + + using (var scope = serviceScopeFactory.CreateScope()) + { + scope.ServiceProvider.GetRequiredService(); + } + + MyService.DisposeCount.ShouldBe(1); + } + } + + private class MyService : ITransientDependency, IDisposable + { + public static int DisposeCount { get; private set; } + + public void Dispose() + { + ++DisposeCount; + } + } + } +} diff --git a/framework/test/Volo.Abp.Core.Tests/Volo/Abp/IO/FileHelper_Tests.cs b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/IO/FileHelper_Tests.cs new file mode 100644 index 0000000000..50ac75138a --- /dev/null +++ b/framework/test/Volo.Abp.Core.Tests/Volo/Abp/IO/FileHelper_Tests.cs @@ -0,0 +1,15 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.IO +{ + public class FileHelper_Tests + { + [Fact] + public void GetExtension() + { + FileHelper.GetExtension("test").ShouldBeNull(); + FileHelper.GetExtension("te.st").ShouldBe("st"); + } + } +} diff --git a/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs b/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs index 023e8d2e97..82a00d8edc 100644 --- a/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs +++ b/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs @@ -42,7 +42,7 @@ namespace Volo.Abp.Data { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = DefaultConnString; options.ConnectionStrings[Database1Name] = Database1ConnString; diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs index d45fab7d32..a36c664e8a 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs @@ -13,12 +13,12 @@ namespace Volo.Abp.Emailing { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Templates["template1"] = new EmailTemplateDefinition("template1") diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs index f955a7fa14..b1b92ab5b2 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreTestModule.cs @@ -34,7 +34,7 @@ namespace Volo.Abp.EntityFrameworkCore var sqliteConnection = CreateDatabaseAndGetConnection(); - context.Services.Configure(options => + Configure(options => { options.Configure(abpDbContextConfigurationContext => { diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs index 17480a6f48..87bd7cfc28 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/EntityFrameworkCoreTestBase.cs @@ -1,9 +1,4 @@ -using System; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Uow; - -namespace Volo.Abp.EntityFrameworkCore +namespace Volo.Abp.EntityFrameworkCore { public abstract class EntityFrameworkCoreTestBase : AbpIntegratedTest { diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs new file mode 100644 index 0000000000..f7e5019467 --- /dev/null +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Uow/Uow_Completed_Tests.cs @@ -0,0 +1,9 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.EntityFrameworkCore.Uow +{ + public class Uow_Completed_Tests : Uow_Completed_Tests + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBusTestBase.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBusTestBase.cs index 45671715a3..d4e8df71aa 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBusTestBase.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBusTestBase.cs @@ -2,11 +2,11 @@ namespace Volo.Abp.EventBus.Distributed { public abstract class LocalDistributedEventBusTestBase : AbpIntegratedTest { - protected LocalDistributedEventBus LocalEventBus; + protected IDistributedEventBus DistributedEventBus; protected LocalDistributedEventBusTestBase() { - LocalEventBus = GetRequiredService(); + DistributedEventBus = GetRequiredService(); } protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs index 24dfbf357f..47649ad3c3 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Distributed/LocalDistributedEventBus_Test.cs @@ -8,11 +8,11 @@ namespace Volo.Abp.EventBus.Distributed [Fact] public async Task Should_Call_Handler_AndDispose() { - LocalEventBus.Subscribe(); + DistributedEventBus.Subscribe(); - await LocalEventBus.PublishAsync(new MySimpleEventData(1)); - await LocalEventBus.PublishAsync(new MySimpleEventData(2)); - await LocalEventBus.PublishAsync(new MySimpleEventData(3)); + await DistributedEventBus.PublishAsync(new MySimpleEventData(1)); + await DistributedEventBus.PublishAsync(new MySimpleEventData(2)); + await DistributedEventBus.PublishAsync(new MySimpleEventData(3)); Assert.Equal(3, MySimpleDistributedTransientEventHandler.HandleCount); Assert.Equal(3, MySimpleDistributedTransientEventHandler.DisposeCount); diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_MultipleHandle_Test.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_MultipleHandle_Test.cs index b8dfe43e17..d20692fa01 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_MultipleHandle_Test.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/EventBus_MultipleHandle_Test.cs @@ -31,8 +31,8 @@ namespace Volo.Abp.EventBus.Local } public class MyEventHandler : - IEventHandler>, - IEventHandler> + ILocalEventHandler>, + ILocalEventHandler> { public int EntityChangedEventCount { get; set; } public int EntityCreatedEventCount { get; set; } diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleEventDataHandler.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleEventDataHandler.cs index ac725f2ae3..66a48a60bb 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleEventDataHandler.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleEventDataHandler.cs @@ -3,7 +3,7 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.EventBus.Local { - public class MySimpleEventDataHandler : IEventHandler, ISingletonDependency + public class MySimpleEventDataHandler : ILocalEventHandler, ISingletonDependency { public int TotalData { get; private set; } diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleTransientEventHandler.cs b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleTransientEventHandler.cs index 6adf34b51b..2c33c8e32c 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleTransientEventHandler.cs +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo/Abp/EventBus/Local/MySimpleTransientEventHandler.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; namespace Volo.Abp.EventBus.Local { - public class MySimpleTransientEventHandler : IEventHandler, IDisposable + public class MySimpleTransientEventHandler : ILocalEventHandler, IDisposable { public static int HandleCount { get; set; } diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpTestModule.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpTestModule.cs index b6237a12ad..4ee13e7dc7 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpTestModule.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/AbpHttpTestModule.cs @@ -15,7 +15,7 @@ namespace Volo.Abp.Http context.Services.AddHttpClientProxies(typeof(TestAppModule).Assembly); context.Services.AddHttpClientProxy(); - context.Services.Configure(options => + Configure(options => { options.RemoteServices.Default = new RemoteServiceConfiguration("/"); }); diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj index b36cfc9b02..b28d93e5db 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj +++ b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj @@ -15,13 +15,6 @@ - - - - - - - diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs index 70f3531754..ea6ce3e242 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/AbpLocalization_Tests.cs @@ -110,12 +110,12 @@ namespace Volo.Abp.Localization { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources.Add("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/Validation"); options.Resources.Add("en").AddVirtualJson("/Volo/Abp/Localization/TestResources/Base/CountryNames"); diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs index 2f8fd66726..9b2366119b 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs @@ -45,12 +45,12 @@ namespace Volo.Abp.Localization { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pt-BR.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pt-BR.json index a55b5f0237..39122588cd 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pt-BR.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pt-BR.json @@ -1,7 +1,7 @@ { - "culture": "pt", + "culture": "pt-BR", "texts": { "USA": "Estados Unidos da América", "Brazil": "Brasil" } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pt-BR.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pt-BR.json index 16a0cdbc2d..d30db38152 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pt-BR.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pt-BR.json @@ -1,7 +1,7 @@ { - "culture": "pt", + "culture": "pt-BR", "texts": { "ThisFieldIsRequired": "Este campo é obrigatório", "MaxLenghtErrorMessage": "Este campo pode ser no máximo de '{0}' caracteres" } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pt-BR.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pt-BR.json index ff89fdb9ea..65b1f69a03 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pt-BR.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pt-BR.json @@ -1,5 +1,5 @@ { - "culture": "pt", + "culture": "pt-BR", "texts": { "Hello {0}.": "Olá {0}.", "Car": "Carro", @@ -7,4 +7,4 @@ "MaxLenghtErrorMessage": "O comprimento deste campo pode ser no máximo de '{0}' caracteres", "Universe": "Universo" } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pt-BR.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pt-BR.json index ca17b637f0..495fb6e0ef 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pt-BR.json +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pt-BR.json @@ -1,6 +1,6 @@ { - "culture": "pt", + "culture": "pt-BR", "texts": { "SeeYou": "Até logo" } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs index e9527a3763..c7f5d38bbe 100644 --- a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs +++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs @@ -19,7 +19,7 @@ namespace Volo.Abp.MemoryDb { var connStr = Guid.NewGuid().ToString(); - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = connStr; }); diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs index e1cbefa59f..7e50a930df 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/AbpMongoDbTestModule.cs @@ -20,7 +20,7 @@ namespace Volo.Abp.MongoDB { _mongoDbRunner = MongoDbRunner.Start(); - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = _mongoDbRunner.ConnectionString; }); diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs new file mode 100644 index 0000000000..4773644885 --- /dev/null +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Uow/Uow_Completed_Tests.cs @@ -0,0 +1,9 @@ +using Volo.Abp.TestApp.Testing; + +namespace Volo.Abp.MongoDB.Uow +{ + public class Uow_Completed_Tests : Uow_Completed_Tests + { + + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Uow_Completed_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Uow_Completed_Tests.cs new file mode 100644 index 0000000000..1b169bbe97 --- /dev/null +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Uow_Completed_Tests.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Modularity; +using Volo.Abp.TestApp.Domain; +using Volo.Abp.Uow; +using Xunit; + +namespace Volo.Abp.TestApp.Testing +{ + public abstract class Uow_Completed_Tests : TestAppTestBase + where TStartupModule : IAbpModule + { + private readonly IUnitOfWorkManager _unitOfWorkManager; + private readonly ICityRepository _cityRepository; + + protected Uow_Completed_Tests() + { + _unitOfWorkManager = GetRequiredService(); + _cityRepository = GetRequiredService(); + } + + [Fact] + public async Task Should_Be_Able_To_Perform_Database_Operation_On_Uow_Complete() + { + using (var uow = _unitOfWorkManager.Begin()) + { + //Perform an arbitrary database operation + await _cityRepository.InsertAsync(new City(Guid.NewGuid(), Guid.NewGuid().ToString())); + + uow.OnCompleted(async () => + { + //Perform another database operation inside the OnCompleted handler + await _cityRepository.InsertAsync(new City(Guid.NewGuid(), Guid.NewGuid().ToString())); + }); + + await uow.CompleteAsync(); + } + } + } +} diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs index 7b49fc9971..8b06afd001 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.UI.Navigation { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.MenuContributors.Add(new TestMenuContributer1()); options.MenuContributors.Add(new TestMenuContributer2()); diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs index de05114301..2c853e3a19 100644 --- a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo/Abp/VirtualFileSystem/VirtualFileProvider_Tests.cs @@ -37,7 +37,7 @@ namespace Volo.Abp.VirtualFileSystem { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp.VirtualFileSystem.MyResources"); }); diff --git a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs index c54cbf8e00..a6c597aa3e 100644 --- a/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs +++ b/modules/account/src/Volo.Abp.Account.Web/AbpAccountWebModule.cs @@ -29,22 +29,22 @@ namespace Volo.Abp.Account.Web public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.Add(); }); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded("Volo.Abp.Account.Web"); }); - context.Services.Configure(options => + Configure(options => { options.MenuContributors.Add(new AbpAccountUserMenuContributor()); }); - context.Services.Configure(options => + Configure(options => { options.Resources .Add("en") @@ -52,7 +52,7 @@ namespace Volo.Abp.Account.Web .AddBaseTypes(typeof(AbpUiResource), typeof(AbpValidationResource)); }); - context.Services.Configure(options => + Configure(options => { options.Contributors.Add(new AccountModuleToolbarContributor()); }); diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs index 4d6c2d93a9..efa043efd1 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs @@ -9,7 +9,7 @@ namespace Volo.Abp.AuditLogging { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Resources.Add("en"); }); diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs index c050853021..442aa50c8e 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore { var sqliteConnection = CreateDatabaseAndGetConnection(); - context.Services.Configure(options => + Configure(options => { options.Configure(abpDbContextConfigurationContext => { diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs index 546f9b274e..dcfc69866e 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.AuditLogging.MongoDB { _mongoDbRunner = MongoDbRunner.Start(); - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = _mongoDbRunner.ConnectionString; }); diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs index acdba328a3..4f01d40c70 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs @@ -25,12 +25,12 @@ namespace Volo.Abp.BackgroundJobs.DemoApp context.Services.SetConfiguration(configuration); - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = configuration.GetConnectionString("Default"); }); - context.Services.Configure(options => + Configure(options => { options.Configure(opts => { @@ -38,7 +38,7 @@ namespace Volo.Abp.BackgroundJobs.DemoApp }); }); - context.Services.Configure(options => + Configure(options => { //Configure for fast running options.JobPollPeriod = 1000; diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobsDomainModule.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobsDomainModule.cs index 61ec4ceb88..2ef1477d87 100644 --- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobsDomainModule.cs +++ b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.Domain/Volo/Abp/BackgroundJobs/BackgroundJobsDomainModule.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.BackgroundJobs { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.AddProfile(validate: true); }); diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsEntityFrameworkCoreTestModule.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsEntityFrameworkCoreTestModule.cs index 876dc20810..70318c1e7a 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsEntityFrameworkCoreTestModule.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsEntityFrameworkCoreTestModule.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore { var sqliteConnection = CreateDatabaseAndGetConnection(); - context.Services.Configure(options => + Configure(options => { options.Configure(abpDbContextConfigurationContext => { diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbTestModule.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbTestModule.cs index a1ec5d8be7..bcbc591a0f 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbTestModule.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo/Abp/BackgroundJobs/MongoDB/BackgroundJobsMongoDbTestModule.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.BackgroundJobs.MongoDB { _mongoDbRunner = MongoDbRunner.Start(); - context.Services.Configure(options => + Configure(options => { options.ConnectionStrings.Default = _mongoDbRunner.ConnectionString; }); diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo/Abp/BackgroundJobs/BackgroundJobsTestBaseModule.cs b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo/Abp/BackgroundJobs/BackgroundJobsTestBaseModule.cs index 30ba72c427..d38b3ceac5 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo/Abp/BackgroundJobs/BackgroundJobsTestBaseModule.cs +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo/Abp/BackgroundJobs/BackgroundJobsTestBaseModule.cs @@ -13,7 +13,7 @@ namespace Volo.Abp.BackgroundJobs { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.IsJobExecutionEnabled = false; }); diff --git a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs index 9b0f17cf11..b6c69741b7 100644 --- a/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs +++ b/modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs @@ -55,7 +55,7 @@ namespace Volo.BloggingTestApp var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.BuildConfiguration(); - context.Services.Configure(options => + Configure(options => { #if MONGODB const string connStringName = "MongoDb"; @@ -66,14 +66,14 @@ namespace Volo.BloggingTestApp }); #if !MONGODB - context.Services.Configure(options => + Configure(options => { options.UseSqlServer(); }); #endif if (hostingEnvironment.IsDevelopment()) { - context.Services.Configure(options => + Configure(options => { options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -93,14 +93,14 @@ namespace Volo.BloggingTestApp }); var cultures = new List { new CultureInfo("en"), new CultureInfo("tr") }; - context.Services.Configure(options => + Configure(options => { options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = cultures; options.SupportedUICultures = cultures; }); - context.Services.Configure(options => + Configure(options => { options.DefaultThemeName = BasicTheme.Name; }); diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs index 83f66a2278..29deef3457 100644 --- a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/BloggingApplicationContractsModule.cs @@ -12,12 +12,12 @@ namespace Volo.Blogging { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.DefinitionProviders.Add(); }); - context.Services.Configure(options => + Configure(options => { options.FileSets.AddEmbedded(); }); diff --git a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs index fd956ebc67..460f573d1d 100644 --- a/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs +++ b/modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/BloggingApplicationModule.cs @@ -17,14 +17,14 @@ namespace Volo.Blogging { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.AddProfile(validate: true); }); - context.Services.Configure(options => + Configure(options => { //TODO: Rename UpdatePolicy/DeletePolicy since it's candidate to conflicts with other modules! options.AddPolicy("BloggingUpdatePolicy", policy => policy.Requirements.Add(CommonOperations.Update)); diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/BloggingDomainSharedModule.cs b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/BloggingDomainSharedModule.cs index 5061ce3b59..7fd98515a2 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/BloggingDomainSharedModule.cs +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/BloggingDomainSharedModule.cs @@ -10,7 +10,7 @@ namespace Volo.Blogging { public override void ConfigureServices(ServiceConfigurationContext context) { - context.Services.Configure(options => + Configure(options => { options.Resources.Add("en"); }); diff --git a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs index ef8986bfc6..67c5f7ce8b 100644 --- a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs +++ b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs @@ -21,7 +21,7 @@ namespace Volo.Blogging.EntityFrameworkCore { _sqliteConnection = CreateDatabaseAndGetConnection(); - context.Services.Configure(options => + Configure(options => { options.Configure(abpDbContextConfigurationContext => { diff --git a/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.Designer.cs b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.Designer.cs new file mode 100644 index 0000000000..5a94075bd6 --- /dev/null +++ b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.Designer.cs @@ -0,0 +1,66 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.DocsTestApp.EntityFrameworkCore; + +namespace Volo.DocsTestApp.EntityFrameworkCore.Migrations +{ + [DbContext(typeof(DocsTestAppDbContext))] + [Migration("20181205154143_Removed_GoogleCustomSearchId")] + partial class Removed_GoogleCustomSearchId + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.1.1-rtm-30846") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Volo.Docs.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("DefaultDocumentName") + .IsRequired() + .HasMaxLength(128); + + b.Property("DocumentStoreType"); + + b.Property("ExtraProperties") + .HasColumnName("ExtraProperties"); + + b.Property("Format"); + + b.Property("LatestVersionBranchName") + .HasMaxLength(128); + + b.Property("MainWebsiteUrl"); + + b.Property("MinimumVersion"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128); + + b.Property("NavigationDocumentName") + .IsRequired() + .HasMaxLength(128); + + b.Property("ShortName") + .IsRequired() + .HasMaxLength(32); + + b.HasKey("Id"); + + b.ToTable("DocsProjects"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.cs b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.cs new file mode 100644 index 0000000000..577b28bda1 --- /dev/null +++ b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/20181205154143_Removed_GoogleCustomSearchId.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.DocsTestApp.EntityFrameworkCore.Migrations +{ + public partial class Removed_GoogleCustomSearchId : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "GoogleCustomSearchId", + table: "DocsProjects"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GoogleCustomSearchId", + table: "DocsProjects", + nullable: true); + } + } +} diff --git a/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/DocsTestAppDbContextModelSnapshot.cs b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/DocsTestAppDbContextModelSnapshot.cs index eea0c9b857..9c1f4f448c 100644 --- a/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/DocsTestAppDbContextModelSnapshot.cs +++ b/modules/docs/app/Volo.DocsTestApp.EntityFrameworkCore/Migrations/DocsTestAppDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace Volo.DocsTestApp.EntityFrameworkCore.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.1.4-rtm-31024") + .HasAnnotation("ProductVersion", "2.1.1-rtm-30846") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); @@ -35,8 +35,6 @@ namespace Volo.DocsTestApp.EntityFrameworkCore.Migrations b.Property("Format"); - b.Property("GoogleCustomSearchId"); - b.Property("LatestVersionBranchName") .HasMaxLength(128); diff --git a/modules/docs/app/Volo.DocsTestApp/DocsTestAppModule.cs b/modules/docs/app/Volo.DocsTestApp/DocsTestAppModule.cs index 407e8543b5..4458a443ec 100644 --- a/modules/docs/app/Volo.DocsTestApp/DocsTestAppModule.cs +++ b/modules/docs/app/Volo.DocsTestApp/DocsTestAppModule.cs @@ -40,20 +40,20 @@ namespace Volo.DocsTestApp var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - context.Services.Configure(options => + Configure(options => { const string connStringName = "SqlServer"; options.ConnectionStrings.Default = configuration.GetConnectionString(connStringName); }); - context.Services.Configure(options => + Configure(options => { options.UseSqlServer(); }); if (hostingEnvironment.IsDevelopment()) { - context.Services.Configure(options => + Configure(options => { options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPyhsical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -74,14 +74,14 @@ namespace Volo.DocsTestApp var cultures = new List { new CultureInfo("en"), new CultureInfo("tr") }; - context.Services.Configure(options => + Configure(options => { options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = cultures; options.SupportedUICultures = cultures; }); - context.Services.Configure(options => + Configure(options => { options.DefaultThemeName = BasicTheme.Name; }); diff --git a/modules/docs/app/Volo.DocsTestApp/abp.resourcemapping.js b/modules/docs/app/Volo.DocsTestApp/abp.resourcemapping.js index 77e84daf41..8fda0db7d4 100644 --- a/modules/docs/app/Volo.DocsTestApp/abp.resourcemapping.js +++ b/modules/docs/app/Volo.DocsTestApp/abp.resourcemapping.js @@ -7,6 +7,6 @@ "@libs" ], mappings: { - + } -} \ No newline at end of file +}; diff --git a/modules/docs/app/Volo.DocsTestApp/package.json b/modules/docs/app/Volo.DocsTestApp/package.json index 0e962af8da..de62543964 100644 --- a/modules/docs/app/Volo.DocsTestApp/package.json +++ b/modules/docs/app/Volo.DocsTestApp/package.json @@ -3,6 +3,7 @@ "name": "volo.docstestapp", "private": true, "dependencies": { - "@abp/aspnetcore.mvc.ui.theme.basic": "^0.4.3" + "@abp/aspnetcore.mvc.ui.theme.basic": "^0.4.9", + "@abp/docs": "^0.5.1" } } diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/anchor-js/anchor.js similarity index 99% rename from modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.js rename to modules/docs/app/Volo.DocsTestApp/wwwroot/libs/anchor-js/anchor.js index 5813b98ed0..38a3b62a66 100644 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.js +++ b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/anchor-js/anchor.js @@ -220,8 +220,8 @@ * @return {String} - hyphen-delimited text for use in IDs and URLs. */ this.urlify = function(text) { - // Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\ - var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\]/g, + // Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\ (newlines, tabs, backspace, & vertical tabs) + var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\\n\t\b\v]/g, urlText; // The reason we include this _applyRemainingDefaultOptions is so urlify can be called independently, diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.js deleted file mode 100644 index 790b25e3dc..0000000000 --- a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.js +++ /dev/null @@ -1,159 +0,0 @@ -/*! - * Bootstrap Table of Contents v1.0.0 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ -(function($) { - 'use strict'; - - window.Toc = { - helpers: { - // return all matching elements in the set, or their descendants - findOrFilter: function($el, selector) { - // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ - // http://stackoverflow.com/a/12731439/358804 - var $descendants = $el.find(selector); - return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); - }, - - generateUniqueIdBase: function(el) { - var text = $(el).text(); - var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); - return anchor || el.tagName.toLowerCase(); - }, - - generateUniqueId: function(el) { - var anchorBase = this.generateUniqueIdBase(el); - for (var i = 0; ; i++) { - var anchor = anchorBase; - if (i > 0) { - // add suffix - anchor += '-' + i; - } - // check if ID already exists - if (!document.getElementById(anchor)) { - return anchor; - } - } - }, - - generateAnchor: function(el) { - if (el.id) { - return el.id; - } else { - var anchor = this.generateUniqueId(el); - el.id = anchor; - return anchor; - } - }, - - createNavList: function() { - return $(''); - }, - - createChildNavList: function($parent) { - var $childList = this.createNavList(); - $parent.append($childList); - return $childList; - }, - - generateNavEl: function(anchor, text) { - var $a = $(''); - $a.attr('href', '#' + anchor); - $a.text(text); - var $li = $('
  • '); - $li.append($a); - return $li; - }, - - generateNavItem: function(headingEl) { - var anchor = this.generateAnchor(headingEl); - var $heading = $(headingEl); - var text = $heading.data('toc-text') || $heading.text(); - return this.generateNavEl(anchor, text); - }, - - // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). - getTopLevel: function($scope) { - for (var i = 1; i <= 6; i++) { - var $headings = this.findOrFilter($scope, 'h' + i); - if ($headings.length > 1) { - return i; - } - } - - return 1; - }, - - // returns the elements for the top level, and the next below it - getHeadings: function($scope, topLevel) { - var topSelector = 'h' + topLevel; - - var secondaryLevel = topLevel + 1; - var secondarySelector = 'h' + secondaryLevel; - - return this.findOrFilter($scope, topSelector + ',' + secondarySelector); - }, - - getNavLevel: function(el) { - return parseInt(el.tagName.charAt(1), 10); - }, - - populateNav: function($topContext, topLevel, $headings) { - var $context = $topContext; - var $prevNav; - - var helpers = this; - $headings.each(function(i, el) { - var $newNav = helpers.generateNavItem(el); - var navLevel = helpers.getNavLevel(el); - - // determine the proper $context - if (navLevel === topLevel) { - // use top level - $context = $topContext; - } else if ($prevNav && $context === $topContext) { - // create a new level of the tree and switch to it - $context = helpers.createChildNavList($prevNav); - } // else use the current $context - - $context.append($newNav); - - $prevNav = $newNav; - }); - }, - - parseOps: function(arg) { - var opts; - if (arg.jquery) { - opts = { - $nav: arg - }; - } else { - opts = arg; - } - opts.$scope = opts.$scope || $(document.body); - return opts; - } - }, - - // accepts a jQuery object, or an options object - init: function(opts) { - opts = this.helpers.parseOps(opts); - - // ensure that the data attribute is in place for styling - opts.$nav.attr('data-toggle', 'toc'); - - var $topContext = this.helpers.createChildNavList(opts.$nav); - var topLevel = this.helpers.getTopLevel(opts.$scope); - var $headings = this.helpers.getHeadings(opts.$scope, topLevel); - this.helpers.populateNav($topContext, topLevel, $headings); - } - }; - - $(function() { - $('nav[data-toggle="toc"]').each(function(i, el) { - var $nav = $(el); - Toc.init($nav); - }); - }); -})(jQuery); diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.css b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.css deleted file mode 100644 index 7bfd3288b6..0000000000 --- a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Bootstrap Table of Contents v1.0.0 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */nav[data-toggle=toc] .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{padding-left:19px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}nav[data-toggle=toc] .nav-link.active,nav[data-toggle=toc] .nav-link.active:focus,nav[data-toggle=toc] .nav-link.active:hover{padding-left:18px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}nav[data-toggle=toc] .nav-link+ul{display:none;padding-bottom:10px}nav[data-toggle=toc] .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{padding-left:29px}nav[data-toggle=toc] .nav .nav>li>.active,nav[data-toggle=toc] .nav .nav>li>.active:focus,nav[data-toggle=toc] .nav .nav>li>.active:hover{padding-left:28px;font-weight:500}nav[data-toggle=toc] .nav-link.active+ul{display:block} \ No newline at end of file diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.js deleted file mode 100644 index f72df76668..0000000000 --- a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap Table of Contents v1.0.0 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ -!function(e){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var n=e.find(t);return e.filter(t).add(n).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(t){var n=e(t).text(),r=n.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g,"-");return r||t.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),n=0;;n++){var r=t;if(n>0&&(r+="-"+n),!document.getElementById(r))return r}},generateAnchor:function(e){if(e.id)return e.id;var t=this.generateUniqueId(e);return e.id=t,t},createNavList:function(){return e('')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(t,n){var r=e('');r.attr("href","#"+t),r.text(n);var a=e("
  • ");return a.append(r),a},generateNavItem:function(t){var n=this.generateAnchor(t),r=e(t),a=r.data("toc-text")||r.text();return this.generateNavEl(n,a)},getTopLevel:function(e){for(var t=1;t<=6;t++){var n=this.findOrFilter(e,"h"+t);if(n.length>1)return t}return 1},getHeadings:function(e,t){var n="h"+t,r=t+1,a="h"+r;return this.findOrFilter(e,n+","+a)},getNavLevel:function(e){return parseInt(e.tagName.charAt(1),10)},populateNav:function(e,t,n){var r,a=e,i=this;n.each(function(n,o){var s=i.generateNavItem(o),u=i.getNavLevel(o);u===t?a=e:r&&a===e&&(a=i.createChildNavList(r)),a.append(s),r=s})},parseOps:function(t){var n;return n=t.jquery?{$nav:t}:t,n.$scope=n.$scope||e(document.body),n}},init:function(e){e=this.helpers.parseOps(e),e.$nav.attr("data-toggle","toc");var t=this.helpers.createChildNavList(e.$nav),n=this.helpers.getTopLevel(e.$scope),r=this.helpers.getHeadings(e.$scope,n);this.helpers.populateNav(t,n,r)}},e(function(){e('nav[data-toggle="toc"]').each(function(t,n){var r=e(n);Toc.init(r)})})}(jQuery); \ No newline at end of file diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.js new file mode 100644 index 0000000000..14cb08654f --- /dev/null +++ b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.js @@ -0,0 +1,978 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["ClipboardJS"] = factory(); + else + root["ClipboardJS"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _clipboardAction = __webpack_require__(1); + +var _clipboardAction2 = _interopRequireDefault(_clipboardAction); + +var _tinyEmitter = __webpack_require__(3); + +var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); + +var _goodListener = __webpack_require__(4); + +var _goodListener2 = _interopRequireDefault(_goodListener); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * Base class which takes one or more elements, adds event listeners to them, + * and instantiates a new `ClipboardAction` on each click. + */ +var Clipboard = function (_Emitter) { + _inherits(Clipboard, _Emitter); + + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + _classCallCheck(this, Clipboard); + + var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); + + _this.resolveOptions(options); + _this.listenClick(trigger); + return _this; + } + + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ + + + _createClass(Clipboard, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + this.container = _typeof(options.container) === 'object' ? options.container : document.body; + } + + /** + * Adds a click event listener to the passed trigger. + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + */ + + }, { + key: 'listenClick', + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + + /** + * Defines a new `ClipboardAction` on each click event. + * @param {Event} e + */ + + }, { + key: 'onClick', + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + + if (this.clipboardAction) { + this.clipboardAction = null; + } + + this.clipboardAction = new _clipboardAction2.default({ + action: this.action(trigger), + target: this.target(trigger), + text: this.text(trigger), + container: this.container, + trigger: trigger, + emitter: this + }); + } + + /** + * Default `action` lookup function. + * @param {Element} trigger + */ + + }, { + key: 'defaultAction', + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + + /** + * Default `target` lookup function. + * @param {Element} trigger + */ + + }, { + key: 'defaultTarget', + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + + /** + * Returns the support of the given action, or all actions if no action is + * given. + * @param {String} [action] + */ + + }, { + key: 'defaultText', + + + /** + * Default `text` lookup function. + * @param {Element} trigger + */ + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + + /** + * Destroy lifecycle. + */ + + }, { + key: 'destroy', + value: function destroy() { + this.listener.destroy(); + + if (this.clipboardAction) { + this.clipboardAction.destroy(); + this.clipboardAction = null; + } + } + }], [{ + key: 'isSupported', + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; + + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + + return support; + } + }]); + + return Clipboard; +}(_tinyEmitter2.default); + +/** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + + +function getAttributeValue(suffix, element) { + var attribute = 'data-clipboard-' + suffix; + + if (!element.hasAttribute(attribute)) { + return; + } + + return element.getAttribute(attribute); +} + +module.exports = Clipboard; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _select = __webpack_require__(2); + +var _select2 = _interopRequireDefault(_select); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Inner class which performs selection from either `text` or `target` + * properties and then executes copy or cut operations. + */ +var ClipboardAction = function () { + /** + * @param {Object} options + */ + function ClipboardAction(options) { + _classCallCheck(this, ClipboardAction); + + this.resolveOptions(options); + this.initSelection(); + } + + /** + * Defines base properties passed from constructor. + * @param {Object} options + */ + + + _createClass(ClipboardAction, [{ + key: 'resolveOptions', + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + this.action = options.action; + this.container = options.container; + this.emitter = options.emitter; + this.target = options.target; + this.text = options.text; + this.trigger = options.trigger; + + this.selectedText = ''; + } + + /** + * Decides which selection strategy is going to be applied based + * on the existence of `text` and `target` properties. + */ + + }, { + key: 'initSelection', + value: function initSelection() { + if (this.text) { + this.selectFake(); + } else if (this.target) { + this.selectTarget(); + } + } + + /** + * Creates a fake textarea element, sets its value from `text` property, + * and makes a selection on it. + */ + + }, { + key: 'selectFake', + value: function selectFake() { + var _this = this; + + var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; + + this.removeFake(); + + this.fakeHandlerCallback = function () { + return _this.removeFake(); + }; + this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true; + + this.fakeElem = document.createElement('textarea'); + // Prevent zooming on iOS + this.fakeElem.style.fontSize = '12pt'; + // Reset box model + this.fakeElem.style.border = '0'; + this.fakeElem.style.padding = '0'; + this.fakeElem.style.margin = '0'; + // Move element out of screen horizontally + this.fakeElem.style.position = 'absolute'; + this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; + // Move element to the same position vertically + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = yPosition + 'px'; + + this.fakeElem.setAttribute('readonly', ''); + this.fakeElem.value = this.text; + + this.container.appendChild(this.fakeElem); + + this.selectedText = (0, _select2.default)(this.fakeElem); + this.copyText(); + } + + /** + * Only removes the fake element after another click event, that way + * a user can hit `Ctrl+C` to copy because selection still exists. + */ + + }, { + key: 'removeFake', + value: function removeFake() { + if (this.fakeHandler) { + this.container.removeEventListener('click', this.fakeHandlerCallback); + this.fakeHandler = null; + this.fakeHandlerCallback = null; + } + + if (this.fakeElem) { + this.container.removeChild(this.fakeElem); + this.fakeElem = null; + } + } + + /** + * Selects the content from element passed on `target` property. + */ + + }, { + key: 'selectTarget', + value: function selectTarget() { + this.selectedText = (0, _select2.default)(this.target); + this.copyText(); + } + + /** + * Executes the copy operation based on the current selection. + */ + + }, { + key: 'copyText', + value: function copyText() { + var succeeded = void 0; + + try { + succeeded = document.execCommand(this.action); + } catch (err) { + succeeded = false; + } + + this.handleResult(succeeded); + } + + /** + * Fires an event based on the copy operation result. + * @param {Boolean} succeeded + */ + + }, { + key: 'handleResult', + value: function handleResult(succeeded) { + this.emitter.emit(succeeded ? 'success' : 'error', { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }); + } + + /** + * Moves focus away from `target` and back to the trigger, removes current selection. + */ + + }, { + key: 'clearSelection', + value: function clearSelection() { + if (this.trigger) { + this.trigger.focus(); + } + + window.getSelection().removeAllRanges(); + } + + /** + * Sets the `action` to be performed which can be either 'copy' or 'cut'. + * @param {String} action + */ + + }, { + key: 'destroy', + + + /** + * Destroy lifecycle. + */ + value: function destroy() { + this.removeFake(); + } + }, { + key: 'action', + set: function set() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; + + this._action = action; + + if (this._action !== 'copy' && this._action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } + } + + /** + * Gets the `action` property. + * @return {String} + */ + , + get: function get() { + return this._action; + } + + /** + * Sets the `target` property using an element + * that will be have its content copied. + * @param {Element} target + */ + + }, { + key: 'target', + set: function set(target) { + if (target !== undefined) { + if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { + if (this.action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + + this._target = target; + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } + } + + /** + * Gets the `target` property. + * @return {String|HTMLElement} + */ + , + get: function get() { + return this._target; + } + }]); + + return ClipboardAction; +}(); + +module.exports = ClipboardAction; + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + +function select(element) { + var selectedText; + + if (element.nodeName === 'SELECT') { + element.focus(); + + selectedText = element.value; + } + else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') { + var isReadOnly = element.hasAttribute('readonly'); + + if (!isReadOnly) { + element.setAttribute('readonly', ''); + } + + element.select(); + element.setSelectionRange(0, element.value.length); + + if (!isReadOnly) { + element.removeAttribute('readonly'); + } + + selectedText = element.value; + } + else { + if (element.hasAttribute('contenteditable')) { + element.focus(); + } + + var selection = window.getSelection(); + var range = document.createRange(); + + range.selectNodeContents(element); + selection.removeAllRanges(); + selection.addRange(range); + + selectedText = selection.toString(); + } + + return selectedText; +} + +module.exports = select; + + +/***/ }), +/* 3 */ +/***/ (function(module, exports) { + +function E () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +} + +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx + }); + + return this; + }, + + once: function (name, callback, ctx) { + var self = this; + function listener () { + self.off(name, listener); + callback.apply(ctx, arguments); + }; + + listener._ = callback + return this.on(name, listener, ctx); + }, + + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + + return this; + }, + + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + + (liveEvents.length) + ? e[name] = liveEvents + : delete e[name]; + + return this; + } +}; + +module.exports = E; + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +var is = __webpack_require__(5); +var delegate = __webpack_require__(6); + +/** + * Validates all params and calls the right + * listener function based on its target type. + * + * @param {String|HTMLElement|HTMLCollection|NodeList} target + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listen(target, type, callback) { + if (!target && !type && !callback) { + throw new Error('Missing required arguments'); + } + + if (!is.string(type)) { + throw new TypeError('Second argument must be a String'); + } + + if (!is.fn(callback)) { + throw new TypeError('Third argument must be a Function'); + } + + if (is.node(target)) { + return listenNode(target, type, callback); + } + else if (is.nodeList(target)) { + return listenNodeList(target, type, callback); + } + else if (is.string(target)) { + return listenSelector(target, type, callback); + } + else { + throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); + } +} + +/** + * Adds an event listener to a HTML element + * and returns a remove listener function. + * + * @param {HTMLElement} node + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenNode(node, type, callback) { + node.addEventListener(type, callback); + + return { + destroy: function() { + node.removeEventListener(type, callback); + } + } +} + +/** + * Add an event listener to a list of HTML elements + * and returns a remove listener function. + * + * @param {NodeList|HTMLCollection} nodeList + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenNodeList(nodeList, type, callback) { + Array.prototype.forEach.call(nodeList, function(node) { + node.addEventListener(type, callback); + }); + + return { + destroy: function() { + Array.prototype.forEach.call(nodeList, function(node) { + node.removeEventListener(type, callback); + }); + } + } +} + +/** + * Add an event listener to a selector + * and returns a remove listener function. + * + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenSelector(selector, type, callback) { + return delegate(document.body, selector, type, callback); +} + +module.exports = listen; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports) { + +/** + * Check if argument is a HTML element. + * + * @param {Object} value + * @return {Boolean} + */ +exports.node = function(value) { + return value !== undefined + && value instanceof HTMLElement + && value.nodeType === 1; +}; + +/** + * Check if argument is a list of HTML elements. + * + * @param {Object} value + * @return {Boolean} + */ +exports.nodeList = function(value) { + var type = Object.prototype.toString.call(value); + + return value !== undefined + && (type === '[object NodeList]' || type === '[object HTMLCollection]') + && ('length' in value) + && (value.length === 0 || exports.node(value[0])); +}; + +/** + * Check if argument is a string. + * + * @param {Object} value + * @return {Boolean} + */ +exports.string = function(value) { + return typeof value === 'string' + || value instanceof String; +}; + +/** + * Check if argument is a function. + * + * @param {Object} value + * @return {Boolean} + */ +exports.fn = function(value) { + var type = Object.prototype.toString.call(value); + + return type === '[object Function]'; +}; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +var closest = __webpack_require__(7); + +/** + * Delegates event to a selector. + * + * @param {Element} element + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @param {Boolean} useCapture + * @return {Object} + */ +function _delegate(element, selector, type, callback, useCapture) { + var listenerFn = listener.apply(this, arguments); + + element.addEventListener(type, listenerFn, useCapture); + + return { + destroy: function() { + element.removeEventListener(type, listenerFn, useCapture); + } + } +} + +/** + * Delegates event to a selector. + * + * @param {Element|String|Array} [elements] + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @param {Boolean} useCapture + * @return {Object} + */ +function delegate(elements, selector, type, callback, useCapture) { + // Handle the regular Element usage + if (typeof elements.addEventListener === 'function') { + return _delegate.apply(null, arguments); + } + + // Handle Element-less usage, it defaults to global delegation + if (typeof type === 'function') { + // Use `document` as the first parameter, then apply arguments + // This is a short way to .unshift `arguments` without running into deoptimizations + return _delegate.bind(null, document).apply(null, arguments); + } + + // Handle Selector-based usage + if (typeof elements === 'string') { + elements = document.querySelectorAll(elements); + } + + // Handle Array-like based usage + return Array.prototype.map.call(elements, function (element) { + return _delegate(element, selector, type, callback, useCapture); + }); +} + +/** + * Finds closest match and invokes callback. + * + * @param {Element} element + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @return {Function} + */ +function listener(element, selector, type, callback) { + return function(e) { + e.delegateTarget = closest(e.target, selector); + + if (e.delegateTarget) { + callback.call(element, e); + } + } +} + +module.exports = delegate; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports) { + +var DOCUMENT_NODE_TYPE = 9; + +/** + * A polyfill for Element.matches() + */ +if (typeof Element !== 'undefined' && !Element.prototype.matches) { + var proto = Element.prototype; + + proto.matches = proto.matchesSelector || + proto.mozMatchesSelector || + proto.msMatchesSelector || + proto.oMatchesSelector || + proto.webkitMatchesSelector; +} + +/** + * Finds the closest parent that matches a selector. + * + * @param {Element} element + * @param {String} selector + * @return {Function} + */ +function closest (element, selector) { + while (element && element.nodeType !== DOCUMENT_NODE_TYPE) { + if (typeof element.matches === 'function' && + element.matches(selector)) { + return element; + } + element = element.parentNode; + } +} + +module.exports = closest; + + +/***/ }) +/******/ ]); +}); \ No newline at end of file diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.min.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.min.js new file mode 100644 index 0000000000..02c549e35c --- /dev/null +++ b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n .mCSB_container{ margin-right: 30px; } + + .mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden{ margin-right: 0; } /* non-visible scrollbar */ + + .mCS-dir-rtl > .mCSB_inside > .mCSB_container{ /* RTL direction/left-side scrollbar */ + margin-right: 0; + margin-left: 30px; + } + + .mCS-dir-rtl > .mCSB_inside > .mCSB_container.mCS_no_scrollbar_y.mCS_y_hidden{ margin-left: 0; } /* RTL direction/left-side scrollbar */ + + .mCSB_scrollTools{ /* contains scrollbar markup (draggable element, dragger rail, buttons etc.) */ + position: absolute; + width: 16px; + height: auto; + left: auto; + top: 0; + right: 0; + bottom: 0; + } + + .mCSB_outside + .mCSB_scrollTools{ right: -26px; } /* scrollbar position: outside */ + + .mCS-dir-rtl > .mCSB_inside > .mCSB_scrollTools, + .mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools{ /* RTL direction/left-side scrollbar */ + right: auto; + left: 0; + } + + .mCS-dir-rtl > .mCSB_outside + .mCSB_scrollTools{ left: -26px; } /* RTL direction/left-side scrollbar (scrollbar position: outside) */ + + .mCSB_scrollTools .mCSB_draggerContainer{ /* contains the draggable element and dragger rail markup */ + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + height: auto; + } + + .mCSB_scrollTools a + .mCSB_draggerContainer{ margin: 20px 0; } + + .mCSB_scrollTools .mCSB_draggerRail{ + width: 2px; + height: 100%; + margin: 0 auto; + -webkit-border-radius: 16px; -moz-border-radius: 16px; border-radius: 16px; + } + + .mCSB_scrollTools .mCSB_dragger{ /* the draggable element */ + cursor: pointer; + width: 100%; + height: 30px; /* minimum dragger height */ + z-index: 1; + } + + .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ /* the dragger element */ + position: relative; + width: 4px; + height: 100%; + margin: 0 auto; + -webkit-border-radius: 16px; -moz-border-radius: 16px; border-radius: 16px; + text-align: center; + } + + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar{ width: 12px; /* auto-expanded scrollbar */ } + + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ width: 8px; /* auto-expanded scrollbar */ } + + .mCSB_scrollTools .mCSB_buttonUp, + .mCSB_scrollTools .mCSB_buttonDown{ + display: block; + position: absolute; + height: 20px; + width: 100%; + overflow: hidden; + margin: 0 auto; + cursor: pointer; + } + + .mCSB_scrollTools .mCSB_buttonDown{ bottom: 0; } + + + +/* +------------------------------------------------------------------------------------------------------------------------ +3. HORIZONTAL SCROLLBAR +x-axis +------------------------------------------------------------------------------------------------------------------------ +*/ + + .mCSB_horizontal.mCSB_inside > .mCSB_container{ + margin-right: 0; + margin-bottom: 30px; + } + + .mCSB_horizontal.mCSB_outside > .mCSB_container{ min-height: 100%; } + + .mCSB_horizontal > .mCSB_container.mCS_no_scrollbar_x.mCS_x_hidden{ margin-bottom: 0; } /* non-visible scrollbar */ + + .mCSB_scrollTools.mCSB_scrollTools_horizontal{ + width: auto; + height: 16px; + top: auto; + right: 0; + bottom: 0; + left: 0; + } + + .mCustomScrollBox + .mCSB_scrollTools.mCSB_scrollTools_horizontal, + .mCustomScrollBox + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal{ bottom: -26px; } /* scrollbar position: outside */ + + .mCSB_scrollTools.mCSB_scrollTools_horizontal a + .mCSB_draggerContainer{ margin: 0 20px; } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + width: 100%; + height: 2px; + margin: 7px 0; + } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger{ + width: 30px; /* minimum dragger width */ + height: 100%; + left: 0; + } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + width: 100%; + height: 4px; + margin: 6px auto; + } + + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar{ + height: 12px; /* auto-expanded scrollbar */ + margin: 2px auto; + } + + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ + height: 8px; /* auto-expanded scrollbar */ + margin: 4px 0; + } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft, + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight{ + display: block; + position: absolute; + width: 20px; + height: 100%; + overflow: hidden; + margin: 0 auto; + cursor: pointer; + } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonLeft{ left: 0; } + + .mCSB_scrollTools.mCSB_scrollTools_horizontal .mCSB_buttonRight{ right: 0; } + + + +/* +------------------------------------------------------------------------------------------------------------------------ +4. VERTICAL AND HORIZONTAL SCROLLBARS +yx-axis +------------------------------------------------------------------------------------------------------------------------ +*/ + + .mCSB_container_wrapper{ + position: absolute; + height: auto; + width: auto; + overflow: hidden; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin-right: 30px; + margin-bottom: 30px; + } + + .mCSB_container_wrapper > .mCSB_container{ + padding-right: 30px; + padding-bottom: 30px; + -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; + } + + .mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_vertical{ bottom: 20px; } + + .mCSB_vertical_horizontal > .mCSB_scrollTools.mCSB_scrollTools_horizontal{ right: 20px; } + + /* non-visible horizontal scrollbar */ + .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden + .mCSB_scrollTools.mCSB_scrollTools_vertical{ bottom: 0; } + + /* non-visible vertical scrollbar/RTL direction/left-side scrollbar */ + .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal, + .mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal{ right: 0; } + + /* RTL direction/left-side scrollbar */ + .mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_scrollTools.mCSB_scrollTools_horizontal{ left: 20px; } + + /* non-visible scrollbar/RTL direction/left-side scrollbar */ + .mCS-dir-rtl > .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden + .mCSB_scrollTools ~ .mCSB_scrollTools.mCSB_scrollTools_horizontal{ left: 0; } + + .mCS-dir-rtl > .mCSB_inside > .mCSB_container_wrapper{ /* RTL direction/left-side scrollbar */ + margin-right: 0; + margin-left: 30px; + } + + .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden > .mCSB_container{ padding-right: 0; } + + .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden > .mCSB_container{ padding-bottom: 0; } + + .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_y.mCS_y_hidden{ + margin-right: 0; /* non-visible scrollbar */ + margin-left: 0; + } + + /* non-visible horizontal scrollbar */ + .mCustomScrollBox.mCSB_vertical_horizontal.mCSB_inside > .mCSB_container_wrapper.mCS_no_scrollbar_x.mCS_x_hidden{ margin-bottom: 0; } + + + +/* +------------------------------------------------------------------------------------------------------------------------ +5. TRANSITIONS +------------------------------------------------------------------------------------------------------------------------ +*/ + + .mCSB_scrollTools, + .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCSB_scrollTools .mCSB_buttonUp, + .mCSB_scrollTools .mCSB_buttonDown, + .mCSB_scrollTools .mCSB_buttonLeft, + .mCSB_scrollTools .mCSB_buttonRight{ + -webkit-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; + -moz-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; + -o-transition: opacity .2s ease-in-out, background-color .2s ease-in-out; + transition: opacity .2s ease-in-out, background-color .2s ease-in-out; + } + + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, /* auto-expanded scrollbar */ + .mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail, + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger_bar, + .mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerRail{ + -webkit-transition: width .2s ease-out .2s, height .2s ease-out .2s, + margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, + margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, + opacity .2s ease-in-out, background-color .2s ease-in-out; + -moz-transition: width .2s ease-out .2s, height .2s ease-out .2s, + margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, + margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, + opacity .2s ease-in-out, background-color .2s ease-in-out; + -o-transition: width .2s ease-out .2s, height .2s ease-out .2s, + margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, + margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, + opacity .2s ease-in-out, background-color .2s ease-in-out; + transition: width .2s ease-out .2s, height .2s ease-out .2s, + margin-left .2s ease-out .2s, margin-right .2s ease-out .2s, + margin-top .2s ease-out .2s, margin-bottom .2s ease-out .2s, + opacity .2s ease-in-out, background-color .2s ease-in-out; + } + + + +/* +------------------------------------------------------------------------------------------------------------------------ +6. SCROLLBAR COLORS, OPACITY AND BACKGROUNDS +------------------------------------------------------------------------------------------------------------------------ +*/ + + /* + ---------------------------------------- + 6.1 THEMES + ---------------------------------------- + */ + + /* default theme ("light") */ + + .mCSB_scrollTools{ opacity: 0.75; filter: "alpha(opacity=75)"; -ms-filter: "alpha(opacity=75)"; } + + .mCS-autoHide > .mCustomScrollBox > .mCSB_scrollTools, + .mCS-autoHide > .mCustomScrollBox ~ .mCSB_scrollTools{ opacity: 0; filter: "alpha(opacity=0)"; -ms-filter: "alpha(opacity=0)"; } + + .mCustomScrollbar > .mCustomScrollBox > .mCSB_scrollTools.mCSB_scrollTools_onDrag, + .mCustomScrollbar > .mCustomScrollBox ~ .mCSB_scrollTools.mCSB_scrollTools_onDrag, + .mCustomScrollBox:hover > .mCSB_scrollTools, + .mCustomScrollBox:hover ~ .mCSB_scrollTools, + .mCS-autoHide:hover > .mCustomScrollBox > .mCSB_scrollTools, + .mCS-autoHide:hover > .mCustomScrollBox ~ .mCSB_scrollTools{ opacity: 1; filter: "alpha(opacity=100)"; -ms-filter: "alpha(opacity=100)"; } + + .mCSB_scrollTools .mCSB_draggerRail{ + background-color: #000; background-color: rgba(0,0,0,0.4); + filter: "alpha(opacity=40)"; -ms-filter: "alpha(opacity=40)"; + } + + .mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-color: #fff; background-color: rgba(255,255,255,0.75); + filter: "alpha(opacity=75)"; -ms-filter: "alpha(opacity=75)"; + } + + .mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ + background-color: #fff; background-color: rgba(255,255,255,0.85); + filter: "alpha(opacity=85)"; -ms-filter: "alpha(opacity=85)"; + } + .mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background-color: #fff; background-color: rgba(255,255,255,0.9); + filter: "alpha(opacity=90)"; -ms-filter: "alpha(opacity=90)"; + } + + .mCSB_scrollTools .mCSB_buttonUp, + .mCSB_scrollTools .mCSB_buttonDown, + .mCSB_scrollTools .mCSB_buttonLeft, + .mCSB_scrollTools .mCSB_buttonRight{ + background-image: url(mCSB_buttons.png); /* css sprites */ + background-repeat: no-repeat; + opacity: 0.4; filter: "alpha(opacity=40)"; -ms-filter: "alpha(opacity=40)"; + } + + .mCSB_scrollTools .mCSB_buttonUp{ + background-position: 0 0; + /* + sprites locations + light: 0 0, -16px 0, -32px 0, -48px 0, 0 -72px, -16px -72px, -32px -72px + dark: -80px 0, -96px 0, -112px 0, -128px 0, -80px -72px, -96px -72px, -112px -72px + */ + } + + .mCSB_scrollTools .mCSB_buttonDown{ + background-position: 0 -20px; + /* + sprites locations + light: 0 -20px, -16px -20px, -32px -20px, -48px -20px, 0 -92px, -16px -92px, -32px -92px + dark: -80px -20px, -96px -20px, -112px -20px, -128px -20px, -80px -92px, -96px -92px, -112 -92px + */ + } + + .mCSB_scrollTools .mCSB_buttonLeft{ + background-position: 0 -40px; + /* + sprites locations + light: 0 -40px, -20px -40px, -40px -40px, -60px -40px, 0 -112px, -20px -112px, -40px -112px + dark: -80px -40px, -100px -40px, -120px -40px, -140px -40px, -80px -112px, -100px -112px, -120px -112px + */ + } + + .mCSB_scrollTools .mCSB_buttonRight{ + background-position: 0 -56px; + /* + sprites locations + light: 0 -56px, -20px -56px, -40px -56px, -60px -56px, 0 -128px, -20px -128px, -40px -128px + dark: -80px -56px, -100px -56px, -120px -56px, -140px -56px, -80px -128px, -100px -128px, -120px -128px + */ + } + + .mCSB_scrollTools .mCSB_buttonUp:hover, + .mCSB_scrollTools .mCSB_buttonDown:hover, + .mCSB_scrollTools .mCSB_buttonLeft:hover, + .mCSB_scrollTools .mCSB_buttonRight:hover{ opacity: 0.75; filter: "alpha(opacity=75)"; -ms-filter: "alpha(opacity=75)"; } + + .mCSB_scrollTools .mCSB_buttonUp:active, + .mCSB_scrollTools .mCSB_buttonDown:active, + .mCSB_scrollTools .mCSB_buttonLeft:active, + .mCSB_scrollTools .mCSB_buttonRight:active{ opacity: 0.9; filter: "alpha(opacity=90)"; -ms-filter: "alpha(opacity=90)"; } + + + /* theme: "dark" */ + + .mCS-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.15); } + + .mCS-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: rgba(0,0,0,0.85); } + + .mCS-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: rgba(0,0,0,0.9); } + + .mCS-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -80px 0; } + + .mCS-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -80px -20px; } + + .mCS-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -80px -40px; } + + .mCS-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -80px -56px; } + + /* ---------------------------------------- */ + + + + /* theme: "light-2", "dark-2" */ + + .mCS-light-2.mCSB_scrollTools .mCSB_draggerRail, + .mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail{ + width: 4px; + background-color: #fff; background-color: rgba(255,255,255,0.1); + -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; + } + + .mCS-light-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width: 4px; + background-color: #fff; background-color: rgba(255,255,255,0.75); + -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; + } + + .mCS-light-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-light-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + width: 100%; + height: 4px; + margin: 6px auto; + } + + .mCS-light-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.85); } + + .mCS-light-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-light-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.9); } + + .mCS-light-2.mCSB_scrollTools .mCSB_buttonUp{ background-position: -32px 0; } + + .mCS-light-2.mCSB_scrollTools .mCSB_buttonDown{ background-position: -32px -20px; } + + .mCS-light-2.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -40px -40px; } + + .mCS-light-2.mCSB_scrollTools .mCSB_buttonRight{ background-position: -40px -56px; } + + + /* theme: "dark-2" */ + + .mCS-dark-2.mCSB_scrollTools .mCSB_draggerRail{ + background-color: #000; background-color: rgba(0,0,0,0.1); + -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; + } + + .mCS-dark-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-color: #000; background-color: rgba(0,0,0,0.75); + -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; + } + + .mCS-dark-2.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-dark-2.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-dark-2.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-dark-2.mCSB_scrollTools .mCSB_buttonUp{ background-position: -112px 0; } + + .mCS-dark-2.mCSB_scrollTools .mCSB_buttonDown{ background-position: -112px -20px; } + + .mCS-dark-2.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -120px -40px; } + + .mCS-dark-2.mCSB_scrollTools .mCSB_buttonRight{ background-position: -120px -56px; } + + /* ---------------------------------------- */ + + + + /* theme: "light-thick", "dark-thick" */ + + .mCS-light-thick.mCSB_scrollTools .mCSB_draggerRail, + .mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail{ + width: 4px; + background-color: #fff; background-color: rgba(255,255,255,0.1); + -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + } + + .mCS-light-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width: 6px; + background-color: #fff; background-color: rgba(255,255,255,0.75); + -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + } + + .mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + width: 100%; + height: 4px; + margin: 6px 0; + } + + .mCS-light-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + width: 100%; + height: 6px; + margin: 5px auto; + } + + .mCS-light-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.85); } + + .mCS-light-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-light-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.9); } + + .mCS-light-thick.mCSB_scrollTools .mCSB_buttonUp{ background-position: -16px 0; } + + .mCS-light-thick.mCSB_scrollTools .mCSB_buttonDown{ background-position: -16px -20px; } + + .mCS-light-thick.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -20px -40px; } + + .mCS-light-thick.mCSB_scrollTools .mCSB_buttonRight{ background-position: -20px -56px; } + + + /* theme: "dark-thick" */ + + .mCS-dark-thick.mCSB_scrollTools .mCSB_draggerRail{ + background-color: #000; background-color: rgba(0,0,0,0.1); + -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-color: #000; background-color: rgba(0,0,0,0.75); + -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; + } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-dark-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_buttonUp{ background-position: -96px 0; } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_buttonDown{ background-position: -96px -20px; } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -100px -40px; } + + .mCS-dark-thick.mCSB_scrollTools .mCSB_buttonRight{ background-position: -100px -56px; } + + /* ---------------------------------------- */ + + + + /* theme: "light-thin", "dark-thin" */ + + .mCS-light-thin.mCSB_scrollTools .mCSB_draggerRail{ background-color: #fff; background-color: rgba(255,255,255,0.1); } + + .mCS-light-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ width: 2px; } + + .mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_draggerRail{ width: 100%; } + + .mCS-light-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-thin.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + width: 100%; + height: 2px; + margin: 7px auto; + } + + + /* theme "dark-thin" */ + + .mCS-dark-thin.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.15); } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-dark-thin.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_buttonUp{ background-position: -80px 0; } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_buttonDown{ background-position: -80px -20px; } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -80px -40px; } + + .mCS-dark-thin.mCSB_scrollTools .mCSB_buttonRight{ background-position: -80px -56px; } + + /* ---------------------------------------- */ + + + + /* theme "rounded", "rounded-dark", "rounded-dots", "rounded-dots-dark" */ + + .mCS-rounded.mCSB_scrollTools .mCSB_draggerRail{ background-color: #fff; background-color: rgba(255,255,255,0.15); } + + .mCS-rounded.mCSB_scrollTools .mCSB_dragger, + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger, + .mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger{ height: 14px; } + + .mCS-rounded.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dots.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width: 14px; + margin: 0 1px; + } + + .mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger, + .mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger, + .mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger, + .mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger{ width: 14px; } + + .mCS-rounded.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + height: 14px; + margin: 1px 0; + } + + .mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar{ + width: 16px; /* auto-expanded scrollbar */ + height: 16px; + margin: -1px 0; + } + + .mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-rounded.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, + .mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-rounded-dark.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ width: 4px; /* auto-expanded scrollbar */ } + + .mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_dragger .mCSB_dragger_bar{ + height: 16px; /* auto-expanded scrollbar */ + width: 16px; + margin: 0 -1px; + } + + .mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-rounded.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, + .mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-rounded-dark.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ + height: 4px; /* auto-expanded scrollbar */ + margin: 6px 0; + } + + .mCS-rounded.mCSB_scrollTools .mCSB_buttonUp{ background-position: 0 -72px; } + + .mCS-rounded.mCSB_scrollTools .mCSB_buttonDown{ background-position: 0 -92px; } + + .mCS-rounded.mCSB_scrollTools .mCSB_buttonLeft{ background-position: 0 -112px; } + + .mCS-rounded.mCSB_scrollTools .mCSB_buttonRight{ background-position: 0 -128px; } + + + /* theme "rounded-dark", "rounded-dots-dark" */ + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.15); } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-rounded-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -80px -72px; } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -80px -92px; } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -80px -112px; } + + .mCS-rounded-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -80px -128px; } + + + /* theme "rounded-dots", "rounded-dots-dark" */ + + .mCS-rounded-dots.mCSB_scrollTools_vertical .mCSB_draggerRail, + .mCS-rounded-dots-dark.mCSB_scrollTools_vertical .mCSB_draggerRail{ width: 4px; } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + background-color: transparent; + background-position: center; + } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_draggerRail, + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail{ + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAANElEQVQYV2NkIAAYiVbw//9/Y6DiM1ANJoyMjGdBbLgJQAX/kU0DKgDLkaQAvxW4HEvQFwCRcxIJK1XznAAAAABJRU5ErkJggg=="); + background-repeat: repeat-y; + opacity: 0.3; + filter: "alpha(opacity=30)"; -ms-filter: "alpha(opacity=30)"; + } + + .mCS-rounded-dots.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-rounded-dots-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + height: 4px; + margin: 6px 0; + background-repeat: repeat-x; + } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonUp{ background-position: -16px -72px; } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonDown{ background-position: -16px -92px; } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -20px -112px; } + + .mCS-rounded-dots.mCSB_scrollTools .mCSB_buttonRight{ background-position: -20px -128px; } + + + /* theme "rounded-dots-dark" */ + + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_draggerRail{ + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAALElEQVQYV2NkIAAYSVFgDFR8BqrBBEifBbGRTfiPZhpYjiQFBK3A6l6CvgAAE9kGCd1mvgEAAAAASUVORK5CYII="); + } + + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -96px -72px; } + + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -96px -92px; } + + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -100px -112px; } + + .mCS-rounded-dots-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -100px -128px; } + + /* ---------------------------------------- */ + + + + /* theme "3d", "3d-dark", "3d-thick", "3d-thick-dark" */ + + .mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-repeat: repeat-y; + background-image: -moz-linear-gradient(left, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 100%); + background-image: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0.5)), color-stop(100%,rgba(255,255,255,0))); + background-image: -webkit-linear-gradient(left, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: -o-linear-gradient(left, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: -ms-linear-gradient(left, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: linear-gradient(to right, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + } + + .mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + background-repeat: repeat-x; + background-image: -moz-linear-gradient(top, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 100%); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.5)), color-stop(100%,rgba(255,255,255,0))); + background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: -o-linear-gradient(top, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: -ms-linear-gradient(top, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + background-image: linear-gradient(to bottom, rgba(255,255,255,0.5) 0%,rgba(255,255,255,0) 100%); + } + + + /* theme "3d", "3d-dark" */ + + .mCS-3d.mCSB_scrollTools_vertical .mCSB_dragger, + .mCS-3d-dark.mCSB_scrollTools_vertical .mCSB_dragger{ height: 70px; } + + .mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger, + .mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger{ width: 70px; } + + .mCS-3d.mCSB_scrollTools, + .mCS-3d-dark.mCSB_scrollTools{ + opacity: 1; + filter: "alpha(opacity=30)"; -ms-filter: "alpha(opacity=30)"; + } + + .mCS-3d.mCSB_scrollTools .mCSB_draggerRail, + .mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ -webkit-border-radius: 16px; -moz-border-radius: 16px; border-radius: 16px; } + + .mCS-3d.mCSB_scrollTools .mCSB_draggerRail, + .mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail{ + width: 8px; + background-color: #000; background-color: rgba(0,0,0,0.2); + box-shadow: inset 1px 0 1px rgba(0,0,0,0.5), inset -1px 0 1px rgba(255,255,255,0.2); + } + + .mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-3d.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-3d.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #555; } + + .mCS-3d.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ width: 8px; } + + .mCS-3d.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + width: 100%; + height: 8px; + margin: 4px 0; + box-shadow: inset 0 1px 1px rgba(0,0,0,0.5), inset 0 -1px 1px rgba(255,255,255,0.2); + } + + .mCS-3d.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + width: 100%; + height: 8px; + margin: 4px auto; + } + + .mCS-3d.mCSB_scrollTools .mCSB_buttonUp{ background-position: -32px -72px; } + + .mCS-3d.mCSB_scrollTools .mCSB_buttonDown{ background-position: -32px -92px; } + + .mCS-3d.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -40px -112px; } + + .mCS-3d.mCSB_scrollTools .mCSB_buttonRight{ background-position: -40px -128px; } + + + /* theme "3d-dark" */ + + .mCS-3d-dark.mCSB_scrollTools .mCSB_draggerRail{ + background-color: #000; background-color: rgba(0,0,0,0.1); + box-shadow: inset 1px 0 1px rgba(0,0,0,0.1); + } + + .mCS-3d-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail{ box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); } + + .mCS-3d-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -112px -72px; } + + .mCS-3d-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -112px -92px; } + + .mCS-3d-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -120px -112px; } + + .mCS-3d-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -120px -128px; } + + /* ---------------------------------------- */ + + + + /* theme: "3d-thick", "3d-thick-dark" */ + + .mCS-3d-thick.mCSB_scrollTools, + .mCS-3d-thick-dark.mCSB_scrollTools{ + opacity: 1; + filter: "alpha(opacity=30)"; -ms-filter: "alpha(opacity=30)"; + } + + .mCS-3d-thick.mCSB_scrollTools, + .mCS-3d-thick-dark.mCSB_scrollTools, + .mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer{ -webkit-border-radius: 7px; -moz-border-radius: 7px; border-radius: 7px; } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; } + + .mCSB_inside + .mCS-3d-thick.mCSB_scrollTools_vertical, + .mCSB_inside + .mCS-3d-thick-dark.mCSB_scrollTools_vertical{ right: 1px; } + + .mCS-3d-thick.mCSB_scrollTools_vertical, + .mCS-3d-thick-dark.mCSB_scrollTools_vertical{ box-shadow: inset 1px 0 1px rgba(0,0,0,0.1), inset 0 0 14px rgba(0,0,0,0.5); } + + .mCS-3d-thick.mCSB_scrollTools_horizontal, + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal{ + bottom: 1px; + box-shadow: inset 0 1px 1px rgba(0,0,0,0.1), inset 0 0 14px rgba(0,0,0,0.5); + } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + box-shadow: inset 1px 0 0 rgba(255,255,255,0.4); + width: 12px; + margin: 2px; + position: absolute; + height: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ box-shadow: inset 0 1px 0 rgba(255,255,255,0.4); } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-3d-thick.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #555; } + + .mCS-3d-thick.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + height: 12px; + width: auto; + } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_draggerContainer{ + background-color: #000; background-color: rgba(0,0,0,0.05); + box-shadow: inset 1px 1px 16px rgba(0,0,0,0.1); + } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_draggerRail{ background-color: transparent; } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_buttonUp{ background-position: -32px -72px; } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_buttonDown{ background-position: -32px -92px; } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -40px -112px; } + + .mCS-3d-thick.mCSB_scrollTools .mCSB_buttonRight{ background-position: -40px -128px; } + + + /* theme: "3d-thick-dark" */ + + .mCS-3d-thick-dark.mCSB_scrollTools{ box-shadow: inset 0 0 14px rgba(0,0,0,0.2); } + + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal{ box-shadow: inset 0 1px 1px rgba(0,0,0,0.1), inset 0 0 14px rgba(0,0,0,0.2); } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ box-shadow: inset 1px 0 0 rgba(255,255,255,0.4), inset -1px 0 0 rgba(0,0,0,0.2); } + + .mCS-3d-thick-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -1px 0 rgba(0,0,0,0.2); } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #777; } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerContainer{ + background-color: #fff; background-color: rgba(0,0,0,0.05); + box-shadow: inset 1px 1px 16px rgba(0,0,0,0.1); + } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: transparent; } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -112px -72px; } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -112px -92px; } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -120px -112px; } + + .mCS-3d-thick-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -120px -128px; } + + /* ---------------------------------------- */ + + + + /* theme: "minimal", "minimal-dark" */ + + .mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, + .mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical{ + right: 0; + margin: 12px 0; + } + + .mCustomScrollBox.mCS-minimal + .mCSB_scrollTools.mCSB_scrollTools_horizontal, + .mCustomScrollBox.mCS-minimal + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal, + .mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools.mCSB_scrollTools_horizontal, + .mCustomScrollBox.mCS-minimal-dark + .mCSB_scrollTools + .mCSB_scrollTools.mCSB_scrollTools_horizontal{ + bottom: 0; + margin: 0 12px; + } + + /* RTL direction/left-side scrollbar */ + .mCS-dir-rtl > .mCSB_outside + .mCS-minimal.mCSB_scrollTools_vertical, + .mCS-dir-rtl > .mCSB_outside + .mCS-minimal-dark.mCSB_scrollTools_vertical{ + left: 0; + right: auto; + } + + .mCS-minimal.mCSB_scrollTools .mCSB_draggerRail, + .mCS-minimal-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: transparent; } + + .mCS-minimal.mCSB_scrollTools_vertical .mCSB_dragger, + .mCS-minimal-dark.mCSB_scrollTools_vertical .mCSB_dragger{ height: 50px; } + + .mCS-minimal.mCSB_scrollTools_horizontal .mCSB_dragger, + .mCS-minimal-dark.mCSB_scrollTools_horizontal .mCSB_dragger{ width: 50px; } + + .mCS-minimal.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-color: #fff; background-color: rgba(255,255,255,0.2); + filter: "alpha(opacity=20)"; -ms-filter: "alpha(opacity=20)"; + } + + .mCS-minimal.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-minimal.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background-color: #fff; background-color: rgba(255,255,255,0.5); + filter: "alpha(opacity=50)"; -ms-filter: "alpha(opacity=50)"; + } + + + /* theme: "minimal-dark" */ + + .mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + background-color: #000; background-color: rgba(0,0,0,0.2); + filter: "alpha(opacity=20)"; -ms-filter: "alpha(opacity=20)"; + } + + .mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-minimal-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ + background-color: #000; background-color: rgba(0,0,0,0.5); + filter: "alpha(opacity=50)"; -ms-filter: "alpha(opacity=50)"; + } + + /* ---------------------------------------- */ + + + + /* theme "light-3", "dark-3" */ + + .mCS-light-3.mCSB_scrollTools .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail{ + width: 6px; + background-color: #000; background-color: rgba(0,0,0,0.2); + } + + .mCS-light-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ width: 6px; } + + .mCS-light-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-light-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + width: 100%; + height: 6px; + margin: 5px 0; + } + + .mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-light-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools_vertical.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ + width: 12px; + } + + .mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-light-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_dragger.mCSB_dragger_onDrag_expanded + .mCSB_draggerRail, + .mCS-dark-3.mCSB_scrollTools_horizontal.mCSB_scrollTools_onDrag_expand .mCSB_draggerContainer:hover .mCSB_draggerRail{ + height: 12px; + margin: 2px 0; + } + + .mCS-light-3.mCSB_scrollTools .mCSB_buttonUp{ background-position: -32px -72px; } + + .mCS-light-3.mCSB_scrollTools .mCSB_buttonDown{ background-position: -32px -92px; } + + .mCS-light-3.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -40px -112px; } + + .mCS-light-3.mCSB_scrollTools .mCSB_buttonRight{ background-position: -40px -128px; } + + + /* theme "dark-3" */ + + .mCS-dark-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-dark-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-dark-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-dark-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-dark-3.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.1); } + + .mCS-dark-3.mCSB_scrollTools .mCSB_buttonUp{ background-position: -112px -72px; } + + .mCS-dark-3.mCSB_scrollTools .mCSB_buttonDown{ background-position: -112px -92px; } + + .mCS-dark-3.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -120px -112px; } + + .mCS-dark-3.mCSB_scrollTools .mCSB_buttonRight{ background-position: -120px -128px; } + + /* ---------------------------------------- */ + + + + /* theme "inset", "inset-dark", "inset-2", "inset-2-dark", "inset-3", "inset-3-dark" */ + + .mCS-inset.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail{ + width: 12px; + background-color: #000; background-color: rgba(0,0,0,0.2); + } + + .mCS-inset.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-2.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ + width: 6px; + margin: 3px 5px; + position: absolute; + height: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .mCS-inset.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_dragger .mCSB_dragger_bar{ + height: 6px; + margin: 5px 3px; + position: absolute; + width: auto; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .mCS-inset.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-inset-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-inset-2.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-inset-2-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-inset-3.mCSB_scrollTools_horizontal .mCSB_draggerRail, + .mCS-inset-3-dark.mCSB_scrollTools_horizontal .mCSB_draggerRail{ + width: 100%; + height: 12px; + margin: 2px 0; + } + + .mCS-inset.mCSB_scrollTools .mCSB_buttonUp, + .mCS-inset-2.mCSB_scrollTools .mCSB_buttonUp, + .mCS-inset-3.mCSB_scrollTools .mCSB_buttonUp{ background-position: -32px -72px; } + + .mCS-inset.mCSB_scrollTools .mCSB_buttonDown, + .mCS-inset-2.mCSB_scrollTools .mCSB_buttonDown, + .mCS-inset-3.mCSB_scrollTools .mCSB_buttonDown{ background-position: -32px -92px; } + + .mCS-inset.mCSB_scrollTools .mCSB_buttonLeft, + .mCS-inset-2.mCSB_scrollTools .mCSB_buttonLeft, + .mCS-inset-3.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -40px -112px; } + + .mCS-inset.mCSB_scrollTools .mCSB_buttonRight, + .mCS-inset-2.mCSB_scrollTools .mCSB_buttonRight, + .mCS-inset-3.mCSB_scrollTools .mCSB_buttonRight{ background-position: -40px -128px; } + + + /* theme "inset-dark", "inset-2-dark", "inset-3-dark" */ + + .mCS-inset-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-inset-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.1); } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_buttonUp, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonUp, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonUp{ background-position: -112px -72px; } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_buttonDown, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonDown, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonDown{ background-position: -112px -92px; } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_buttonLeft, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonLeft, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonLeft{ background-position: -120px -112px; } + + .mCS-inset-dark.mCSB_scrollTools .mCSB_buttonRight, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_buttonRight, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_buttonRight{ background-position: -120px -128px; } + + + /* theme "inset-2", "inset-2-dark" */ + + .mCS-inset-2.mCSB_scrollTools .mCSB_draggerRail, + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail{ + background-color: transparent; + border-width: 1px; + border-style: solid; + border-color: #fff; + border-color: rgba(255,255,255,0.2); + -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; + } + + .mCS-inset-2-dark.mCSB_scrollTools .mCSB_draggerRail{ border-color: #000; border-color: rgba(0,0,0,0.2); } + + + /* theme "inset-3", "inset-3-dark" */ + + .mCS-inset-3.mCSB_scrollTools .mCSB_draggerRail{ background-color: #fff; background-color: rgba(255,255,255,0.6); } + + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_draggerRail{ background-color: #000; background-color: rgba(0,0,0,0.6); } + + .mCS-inset-3.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.75); } + + .mCS-inset-3.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.85); } + + .mCS-inset-3.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-inset-3.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #000; background-color: rgba(0,0,0,0.9); } + + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.75); } + + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:hover .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.85); } + + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger:active .mCSB_dragger_bar, + .mCS-inset-3-dark.mCSB_scrollTools .mCSB_dragger.mCSB_dragger_onDrag .mCSB_dragger_bar{ background-color: #fff; background-color: rgba(255,255,255,0.9); } + + /* ---------------------------------------- */ diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js new file mode 100644 index 0000000000..4c9a0b2e52 --- /dev/null +++ b/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.js @@ -0,0 +1,2458 @@ +/* +== malihu jquery custom scrollbar plugin == +Version: 3.1.5 +Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller +Author: malihu +Author URI: http://manos.malihu.gr +License: MIT License (MIT) +*/ + +/* +Copyright Manos Malihutsakis (email: manos@malihu.gr) + +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. +*/ + +/* +The code below is fairly long, fully commented and should be normally used in development. +For production, use either the minified jquery.mCustomScrollbar.min.js script or +the production-ready jquery.mCustomScrollbar.concat.min.js which contains the plugin +and dependencies (minified). +*/ + +(function(factory){ + if(typeof define==="function" && define.amd){ + define(["jquery"],factory); + }else if(typeof module!=="undefined" && module.exports){ + module.exports=factory; + }else{ + factory(jQuery,window,document); + } +}(function($){ +(function(init){ + var _rjs=typeof define==="function" && define.amd, /* RequireJS */ + _njs=typeof module !== "undefined" && module.exports, /* NodeJS */ + _dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */ + _url="cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"; + if(!_rjs){ + if(_njs){ + require("jquery-mousewheel")($); + }else{ + /* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS + (works when mCustomScrollbar fn is called on window load) */ + $.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E")); + } + } + init(); +}(function(){ + + /* + ---------------------------------------- + PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) + ---------------------------------------- + */ + + var pluginNS="mCustomScrollbar", + pluginPfx="mCS", + defaultSelector=".mCustomScrollbar", + + + + + + /* + ---------------------------------------- + DEFAULT OPTIONS + ---------------------------------------- + */ + + defaults={ + /* + set element/content width/height programmatically + values: boolean, pixels, percentage + option default + ------------------------------------- + setWidth false + setHeight false + */ + /* + set the initial css top property of content + values: string (e.g. "-100px", "10%" etc.) + */ + setTop:0, + /* + set the initial css left property of content + values: string (e.g. "-100px", "10%" etc.) + */ + setLeft:0, + /* + scrollbar axis (vertical and/or horizontal scrollbars) + values (string): "y", "x", "yx" + */ + axis:"y", + /* + position of scrollbar relative to content + values (string): "inside", "outside" ("outside" requires elements with position:relative) + */ + scrollbarPosition:"inside", + /* + scrolling inertia + values: integer (milliseconds) + */ + scrollInertia:950, + /* + auto-adjust scrollbar dragger length + values: boolean + */ + autoDraggerLength:true, + /* + auto-hide scrollbar when idle + values: boolean + option default + ------------------------------------- + autoHideScrollbar false + */ + /* + auto-expands scrollbar on mouse-over and dragging + values: boolean + option default + ------------------------------------- + autoExpandScrollbar false + */ + /* + always show scrollbar, even when there's nothing to scroll + values: integer (0=disable, 1=always show dragger rail and buttons, 2=always show dragger rail, dragger and buttons), boolean + */ + alwaysShowScrollbar:0, + /* + scrolling always snaps to a multiple of this number in pixels + values: integer, array ([y,x]) + option default + ------------------------------------- + snapAmount null + */ + /* + when snapping, snap with this number in pixels as an offset + values: integer + */ + snapOffset:0, + /* + mouse-wheel scrolling + */ + mouseWheel:{ + /* + enable mouse-wheel scrolling + values: boolean + */ + enable:true, + /* + scrolling amount in pixels + values: "auto", integer + */ + scrollAmount:"auto", + /* + mouse-wheel scrolling axis + the default scrolling direction when both vertical and horizontal scrollbars are present + values (string): "y", "x" + */ + axis:"y", + /* + prevent the default behaviour which automatically scrolls the parent element(s) when end of scrolling is reached + values: boolean + option default + ------------------------------------- + preventDefault null + */ + /* + the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls. + values: "auto", integer + "auto" uses the default OS/browser value + */ + deltaFactor:"auto", + /* + normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration) + values: boolean + option default + ------------------------------------- + normalizeDelta null + */ + /* + invert mouse-wheel scrolling direction + values: boolean + option default + ------------------------------------- + invert null + */ + /* + the tags that disable mouse-wheel when cursor is over them + */ + disableOver:["select","option","keygen","datalist","textarea"] + }, + /* + scrollbar buttons + */ + scrollButtons:{ + /* + enable scrollbar buttons + values: boolean + option default + ------------------------------------- + enable null + */ + /* + scrollbar buttons scrolling type + values (string): "stepless", "stepped" + */ + scrollType:"stepless", + /* + scrolling amount in pixels + values: "auto", integer + */ + scrollAmount:"auto" + /* + tabindex of the scrollbar buttons + values: false, integer + option default + ------------------------------------- + tabindex null + */ + }, + /* + keyboard scrolling + */ + keyboard:{ + /* + enable scrolling via keyboard + values: boolean + */ + enable:true, + /* + keyboard scrolling type + values (string): "stepless", "stepped" + */ + scrollType:"stepless", + /* + scrolling amount in pixels + values: "auto", integer + */ + scrollAmount:"auto" + }, + /* + enable content touch-swipe scrolling + values: boolean, integer, string (number) + integer values define the axis-specific minimum amount required for scrolling momentum + */ + contentTouchScroll:25, + /* + enable/disable document (default) touch-swipe scrolling + */ + documentTouchScroll:true, + /* + advanced option parameters + */ + advanced:{ + /* + auto-expand content horizontally (for "x" or "yx" axis) + values: boolean, integer (the value 2 forces the non scrollHeight/scrollWidth method, the value 3 forces the scrollHeight/scrollWidth method) + option default + ------------------------------------- + autoExpandHorizontalScroll null + */ + /* + auto-scroll to elements with focus + */ + autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']", + /* + auto-update scrollbars on content, element or viewport resize + should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. + values: boolean + */ + updateOnContentResize:true, + /* + auto-update scrollbars each time each image inside the element is fully loaded + values: "auto", boolean + */ + updateOnImageLoad:"auto", + /* + auto-update scrollbars based on the amount and size changes of specific selectors + useful when you need to update the scrollbar(s) automatically, each time a type of element is added, removed or changes its size + values: boolean, string (e.g. "ul li" will auto-update scrollbars each time list-items inside the element are changed) + a value of true (boolean) will auto-update scrollbars each time any element is changed + option default + ------------------------------------- + updateOnSelectorChange null + */ + /* + extra selectors that'll allow scrollbar dragging upon mousemove/up, pointermove/up, touchend etc. (e.g. "selector-1, selector-2") + option default + ------------------------------------- + extraDraggableSelectors null + */ + /* + extra selectors that'll release scrollbar dragging upon mouseup, pointerup, touchend etc. (e.g. "selector-1, selector-2") + option default + ------------------------------------- + releaseDraggableSelectors null + */ + /* + auto-update timeout + values: integer (milliseconds) + */ + autoUpdateTimeout:60 + }, + /* + scrollbar theme + values: string (see CSS/plugin URI for a list of ready-to-use themes) + */ + theme:"light", + /* + user defined callback functions + */ + callbacks:{ + /* + Available callbacks: + callback default + ------------------------------------- + onCreate null + onInit null + onScrollStart null + onScroll null + onTotalScroll null + onTotalScrollBack null + whileScrolling null + onOverflowY null + onOverflowX null + onOverflowYNone null + onOverflowXNone null + onImageLoad null + onSelectorChange null + onBeforeUpdate null + onUpdate null + */ + onTotalScrollOffset:0, + onTotalScrollBackOffset:0, + alwaysTriggerOffsets:true + } + /* + add scrollbar(s) on all elements matching the current selector, now and in the future + values: boolean, string + string values: "on" (enable), "once" (disable after first invocation), "off" (disable) + liveSelector values: string (selector) + option default + ------------------------------------- + live false + liveSelector null + */ + }, + + + + + + /* + ---------------------------------------- + VARS, CONSTANTS + ---------------------------------------- + */ + + totalInstances=0, /* plugin instances amount */ + liveTimers={}, /* live option timers */ + oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */ + touchActive=false,touchable, /* global touch vars (for touch and pointer events) */ + /* general plugin classes */ + classes=[ + "mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar", + "mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer", + "mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight" + ], + + + + + + /* + ---------------------------------------- + METHODS + ---------------------------------------- + */ + + methods={ + + /* + plugin initialization method + creates the scrollbar(s), plugin data object and options + ---------------------------------------- + */ + + init:function(options){ + + var options=$.extend(true,{},defaults,options), + selector=_selector.call(this); /* validate selector */ + + /* + if live option is enabled, monitor for elements matching the current selector and + apply scrollbar(s) when found (now and in the future) + */ + if(options.live){ + var liveSelector=options.liveSelector || this.selector || defaultSelector, /* live selector(s) */ + $liveSelector=$(liveSelector); /* live selector(s) as jquery object */ + if(options.live==="off"){ + /* + disable live if requested + usage: $(selector).mCustomScrollbar({live:"off"}); + */ + removeLiveTimers(liveSelector); + return; + } + liveTimers[liveSelector]=setTimeout(function(){ + /* call mCustomScrollbar fn on live selector(s) every half-second */ + $liveSelector.mCustomScrollbar(options); + if(options.live==="once" && $liveSelector.length){ + /* disable live after first invocation */ + removeLiveTimers(liveSelector); + } + },500); + }else{ + removeLiveTimers(liveSelector); + } + + /* options backward compatibility (for versions < 3.0.0) and normalization */ + options.setWidth=(options.set_width) ? options.set_width : options.setWidth; + options.setHeight=(options.set_height) ? options.set_height : options.setHeight; + options.axis=(options.horizontalScroll) ? "x" : _findAxis(options.axis); + options.scrollInertia=options.scrollInertia>0 && options.scrollInertia<17 ? 17 : options.scrollInertia; + if(typeof options.mouseWheel!=="object" && options.mouseWheel==true){ /* old school mouseWheel option (non-object) */ + options.mouseWheel={enable:true,scrollAmount:"auto",axis:"y",preventDefault:false,deltaFactor:"auto",normalizeDelta:false,invert:false} + } + options.mouseWheel.scrollAmount=!options.mouseWheelPixels ? options.mouseWheel.scrollAmount : options.mouseWheelPixels; + options.mouseWheel.normalizeDelta=!options.advanced.normalizeMouseWheelDelta ? options.mouseWheel.normalizeDelta : options.advanced.normalizeMouseWheelDelta; + options.scrollButtons.scrollType=_findScrollButtonsType(options.scrollButtons.scrollType); + + _theme(options); /* theme-specific options */ + + /* plugin constructor */ + return $(selector).each(function(){ + + var $this=$(this); + + if(!$this.data(pluginPfx)){ /* prevent multiple instantiations */ + + /* store options and create objects in jquery data */ + $this.data(pluginPfx,{ + idx:++totalInstances, /* instance index */ + opt:options, /* options */ + scrollRatio:{y:null,x:null}, /* scrollbar to content ratio */ + overflowed:null, /* overflowed axis */ + contentReset:{y:null,x:null}, /* object to check when content resets */ + bindEvents:false, /* object to check if events are bound */ + tweenRunning:false, /* object to check if tween is running */ + sequential:{}, /* sequential scrolling object */ + langDir:$this.css("direction"), /* detect/store direction (ltr or rtl) */ + cbOffsets:null, /* object to check whether callback offsets always trigger */ + /* + object to check how scrolling events where last triggered + "internal" (default - triggered by this script), "external" (triggered by other scripts, e.g. via scrollTo method) + usage: object.data("mCS").trigger + */ + trigger:null, + /* + object to check for changes in elements in order to call the update method automatically + */ + poll:{size:{o:0,n:0},img:{o:0,n:0},change:{o:0,n:0}} + }); + + var d=$this.data(pluginPfx),o=d.opt, + /* HTML data attributes */ + htmlDataAxis=$this.data("mcs-axis"),htmlDataSbPos=$this.data("mcs-scrollbar-position"),htmlDataTheme=$this.data("mcs-theme"); + + if(htmlDataAxis){o.axis=htmlDataAxis;} /* usage example: data-mcs-axis="y" */ + if(htmlDataSbPos){o.scrollbarPosition=htmlDataSbPos;} /* usage example: data-mcs-scrollbar-position="outside" */ + if(htmlDataTheme){ /* usage example: data-mcs-theme="minimal" */ + o.theme=htmlDataTheme; + _theme(o); /* theme-specific options */ + } + + _pluginMarkup.call(this); /* add plugin markup */ + + if(d && o.callbacks.onCreate && typeof o.callbacks.onCreate==="function"){o.callbacks.onCreate.call(this);} /* callbacks: onCreate */ + + $("#mCSB_"+d.idx+"_container img:not(."+classes[2]+")").addClass(classes[2]); /* flag loaded images */ + + methods.update.call(null,$this); /* call the update method */ + + } + + }); + + }, + /* ---------------------------------------- */ + + + + /* + plugin update method + updates content and scrollbar(s) values, events and status + ---------------------------------------- + usage: $(selector).mCustomScrollbar("update"); + */ + + update:function(el,cb){ + + var selector=el || _selector.call(this); /* validate selector */ + + return $(selector).each(function(){ + + var $this=$(this); + + if($this.data(pluginPfx)){ /* check if plugin has initialized */ + + var d=$this.data(pluginPfx),o=d.opt, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; + + if(!mCSB_container.length){return;} + + if(d.tweenRunning){_stop($this);} /* stop any running tweens while updating */ + + if(cb && d && o.callbacks.onBeforeUpdate && typeof o.callbacks.onBeforeUpdate==="function"){o.callbacks.onBeforeUpdate.call(this);} /* callbacks: onBeforeUpdate */ + + /* if element was disabled or destroyed, remove class(es) */ + if($this.hasClass(classes[3])){$this.removeClass(classes[3]);} + if($this.hasClass(classes[4])){$this.removeClass(classes[4]);} + + /* css flexbox fix, detect/set max-height */ + mCustomScrollBox.css("max-height","none"); + if(mCustomScrollBox.height()!==$this.height()){mCustomScrollBox.css("max-height",$this.height());} + + _expandContentHorizontally.call(this); /* expand content horizontally */ + + if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){ + mCSB_container.css("width",_contentWidth(mCSB_container)); + } + + d.overflowed=_overflowed.call(this); /* determine if scrolling is required */ + + _scrollbarVisibility.call(this); /* show/hide scrollbar(s) */ + + /* auto-adjust scrollbar dragger length analogous to content */ + if(o.autoDraggerLength){_setDraggerLength.call(this);} + + _scrollRatio.call(this); /* calculate and store scrollbar to content ratio */ + + _bindEvents.call(this); /* bind scrollbar events */ + + /* reset scrolling position and/or events */ + var to=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)]; + if(o.axis!=="x"){ /* y/yx axis */ + if(!d.overflowed[0]){ /* y scrolling is not required */ + _resetContentPosition.call(this); /* reset content position */ + if(o.axis==="y"){ + _unbindEvents.call(this); + }else if(o.axis==="yx" && d.overflowed[1]){ + _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); + } + }else if(mCSB_dragger[0].height()>mCSB_dragger[0].parent().height()){ + _resetContentPosition.call(this); /* reset content position */ + }else{ /* y scrolling is required */ + _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); + d.contentReset.y=null; + } + } + if(o.axis!=="y"){ /* x/yx axis */ + if(!d.overflowed[1]){ /* x scrolling is not required */ + _resetContentPosition.call(this); /* reset content position */ + if(o.axis==="x"){ + _unbindEvents.call(this); + }else if(o.axis==="yx" && d.overflowed[0]){ + _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); + } + }else if(mCSB_dragger[1].width()>mCSB_dragger[1].parent().width()){ + _resetContentPosition.call(this); /* reset content position */ + }else{ /* x scrolling is required */ + _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); + d.contentReset.x=null; + } + } + + /* callbacks: onImageLoad, onSelectorChange, onUpdate */ + if(cb && d){ + if(cb===2 && o.callbacks.onImageLoad && typeof o.callbacks.onImageLoad==="function"){ + o.callbacks.onImageLoad.call(this); + }else if(cb===3 && o.callbacks.onSelectorChange && typeof o.callbacks.onSelectorChange==="function"){ + o.callbacks.onSelectorChange.call(this); + }else if(o.callbacks.onUpdate && typeof o.callbacks.onUpdate==="function"){ + o.callbacks.onUpdate.call(this); + } + } + + _autoUpdate.call(this); /* initialize automatic updating (for dynamic content, fluid layouts etc.) */ + + } + + }); + + }, + /* ---------------------------------------- */ + + + + /* + plugin scrollTo method + triggers a scrolling event to a specific value + ---------------------------------------- + usage: $(selector).mCustomScrollbar("scrollTo",value,options); + */ + + scrollTo:function(val,options){ + + /* prevent silly things like $(selector).mCustomScrollbar("scrollTo",undefined); */ + if(typeof val=="undefined" || val==null){return;} + + var selector=_selector.call(this); /* validate selector */ + + return $(selector).each(function(){ + + var $this=$(this); + + if($this.data(pluginPfx)){ /* check if plugin has initialized */ + + var d=$this.data(pluginPfx),o=d.opt, + /* method default options */ + methodDefaults={ + trigger:"external", /* method is by default triggered externally (e.g. from other scripts) */ + scrollInertia:o.scrollInertia, /* scrolling inertia (animation duration) */ + scrollEasing:"mcsEaseInOut", /* animation easing */ + moveDragger:false, /* move dragger instead of content */ + timeout:60, /* scroll-to delay */ + callbacks:true, /* enable/disable callbacks */ + onStart:true, + onUpdate:true, + onComplete:true + }, + methodOptions=$.extend(true,{},methodDefaults,options), + to=_arr.call(this,val),dur=methodOptions.scrollInertia>0 && methodOptions.scrollInertia<17 ? 17 : methodOptions.scrollInertia; + + /* translate yx values to actual scroll-to positions */ + to[0]=_to.call(this,to[0],"y"); + to[1]=_to.call(this,to[1],"x"); + + /* + check if scroll-to value moves the dragger instead of content. + Only pixel values apply on dragger (e.g. 100, "100px", "-=100" etc.) + */ + if(methodOptions.moveDragger){ + to[0]*=d.scrollRatio.y; + to[1]*=d.scrollRatio.x; + } + + methodOptions.dur=_isTabHidden() ? 0 : dur; //skip animations if browser tab is hidden + + setTimeout(function(){ + /* do the scrolling */ + if(to[0]!==null && typeof to[0]!=="undefined" && o.axis!=="x" && d.overflowed[0]){ /* scroll y */ + methodOptions.dir="y"; + methodOptions.overwrite="all"; + _scrollTo($this,to[0].toString(),methodOptions); + } + if(to[1]!==null && typeof to[1]!=="undefined" && o.axis!=="y" && d.overflowed[1]){ /* scroll x */ + methodOptions.dir="x"; + methodOptions.overwrite="none"; + _scrollTo($this,to[1].toString(),methodOptions); + } + },methodOptions.timeout); + + } + + }); + + }, + /* ---------------------------------------- */ + + + + /* + plugin stop method + stops scrolling animation + ---------------------------------------- + usage: $(selector).mCustomScrollbar("stop"); + */ + stop:function(){ + + var selector=_selector.call(this); /* validate selector */ + + return $(selector).each(function(){ + + var $this=$(this); + + if($this.data(pluginPfx)){ /* check if plugin has initialized */ + + _stop($this); + + } + + }); + + }, + /* ---------------------------------------- */ + + + + /* + plugin disable method + temporarily disables the scrollbar(s) + ---------------------------------------- + usage: $(selector).mCustomScrollbar("disable",reset); + reset (boolean): resets content position to 0 + */ + disable:function(r){ + + var selector=_selector.call(this); /* validate selector */ + + return $(selector).each(function(){ + + var $this=$(this); + + if($this.data(pluginPfx)){ /* check if plugin has initialized */ + + var d=$this.data(pluginPfx); + + _autoUpdate.call(this,"remove"); /* remove automatic updating */ + + _unbindEvents.call(this); /* unbind events */ + + if(r){_resetContentPosition.call(this);} /* reset content position */ + + _scrollbarVisibility.call(this,true); /* show/hide scrollbar(s) */ + + $this.addClass(classes[3]); /* add disable class */ + + } + + }); + + }, + /* ---------------------------------------- */ + + + + /* + plugin destroy method + completely removes the scrollbar(s) and returns the element to its original state + ---------------------------------------- + usage: $(selector).mCustomScrollbar("destroy"); + */ + destroy:function(){ + + var selector=_selector.call(this); /* validate selector */ + + return $(selector).each(function(){ + + var $this=$(this); + + if($this.data(pluginPfx)){ /* check if plugin has initialized */ + + var d=$this.data(pluginPfx),o=d.opt, + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + scrollbar=$(".mCSB_"+d.idx+"_scrollbar"); + + if(o.live){removeLiveTimers(o.liveSelector || $(selector).selector);} /* remove live timers */ + + _autoUpdate.call(this,"remove"); /* remove automatic updating */ + + _unbindEvents.call(this); /* unbind events */ + + _resetContentPosition.call(this); /* reset content position */ + + $this.removeData(pluginPfx); /* remove plugin data object */ + + _delete(this,"mcs"); /* delete callbacks object */ + + /* remove plugin markup */ + scrollbar.remove(); /* remove scrollbar(s) first (those can be either inside or outside plugin's inner wrapper) */ + mCSB_container.find("img."+classes[2]).removeClass(classes[2]); /* remove loaded images flag */ + mCustomScrollBox.replaceWith(mCSB_container.contents()); /* replace plugin's inner wrapper with the original content */ + /* remove plugin classes from the element and add destroy class */ + $this.removeClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" "+classes[6]+" "+classes[7]+" "+classes[5]+" "+classes[3]).addClass(classes[4]); + + } + + }); + + } + /* ---------------------------------------- */ + + }, + + + + + + /* + ---------------------------------------- + FUNCTIONS + ---------------------------------------- + */ + + /* validates selector (if selector is invalid or undefined uses the default one) */ + _selector=function(){ + return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this; + }, + /* -------------------- */ + + + /* changes options according to theme */ + _theme=function(obj){ + var fixedSizeScrollbarThemes=["rounded","rounded-dark","rounded-dots","rounded-dots-dark"], + nonExpandedScrollbarThemes=["rounded-dots","rounded-dots-dark","3d","3d-dark","3d-thick","3d-thick-dark","inset","inset-dark","inset-2","inset-2-dark","inset-3","inset-3-dark"], + disabledScrollButtonsThemes=["minimal","minimal-dark"], + enabledAutoHideScrollbarThemes=["minimal","minimal-dark"], + scrollbarPositionOutsideThemes=["minimal","minimal-dark"]; + obj.autoDraggerLength=$.inArray(obj.theme,fixedSizeScrollbarThemes) > -1 ? false : obj.autoDraggerLength; + obj.autoExpandScrollbar=$.inArray(obj.theme,nonExpandedScrollbarThemes) > -1 ? false : obj.autoExpandScrollbar; + obj.scrollButtons.enable=$.inArray(obj.theme,disabledScrollButtonsThemes) > -1 ? false : obj.scrollButtons.enable; + obj.autoHideScrollbar=$.inArray(obj.theme,enabledAutoHideScrollbarThemes) > -1 ? true : obj.autoHideScrollbar; + obj.scrollbarPosition=$.inArray(obj.theme,scrollbarPositionOutsideThemes) > -1 ? "outside" : obj.scrollbarPosition; + }, + /* -------------------- */ + + + /* live option timers removal */ + removeLiveTimers=function(selector){ + if(liveTimers[selector]){ + clearTimeout(liveTimers[selector]); + _delete(liveTimers,selector); + } + }, + /* -------------------- */ + + + /* normalizes axis option to valid values: "y", "x", "yx" */ + _findAxis=function(val){ + return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y"; + }, + /* -------------------- */ + + + /* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */ + _findScrollButtonsType=function(val){ + return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless"; + }, + /* -------------------- */ + + + /* generates plugin markup */ + _pluginMarkup=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + expandClass=o.autoExpandScrollbar ? " "+classes[1]+"_expand" : "", + scrollbar=["
    ","
    "], + wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical", + scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0], + contentWrapper=o.axis==="yx" ? "
    " : "", + autoHideClass=o.autoHideScrollbar ? " "+classes[6] : "", + scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " "+classes[7] : ""; + if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */ + if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */ + o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */ + $this.addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+autoHideClass+scrollbarDirClass).wrapInner("
    "); + var mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"); + if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){ + mCSB_container.css("width",_contentWidth(mCSB_container)); + } + if(o.scrollbarPosition==="outside"){ + if($this.css("position")==="static"){ /* requires elements with non-static position */ + $this.css("position","relative"); + } + $this.css("overflow","visible"); + mCustomScrollBox.addClass("mCSB_outside").after(scrollbars); + }else{ + mCustomScrollBox.addClass("mCSB_inside").append(scrollbars); + mCSB_container.wrap(contentWrapper); + } + _scrollButtons.call(this); /* add scrollbar buttons */ + /* minimum dragger length */ + var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; + mCSB_dragger[0].css("min-height",mCSB_dragger[0].height()); + mCSB_dragger[1].css("min-width",mCSB_dragger[1].width()); + }, + /* -------------------- */ + + + /* calculates content width */ + _contentWidth=function(el){ + var val=[el[0].scrollWidth,Math.max.apply(Math,el.children().map(function(){return $(this).outerWidth(true);}).get())],w=el.parent().width(); + return val[0]>w ? val[0] : val[1]>w ? val[1] : "100%"; + }, + /* -------------------- */ + + + /* expands content horizontally */ + _expandContentHorizontally=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + mCSB_container=$("#mCSB_"+d.idx+"_container"); + if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){ + /* calculate scrollWidth */ + mCSB_container.css({"width":"auto","min-width":0,"overflow-x":"scroll"}); + var w=Math.ceil(mCSB_container[0].scrollWidth); + if(o.advanced.autoExpandHorizontalScroll===3 || (o.advanced.autoExpandHorizontalScroll!==2 && w>mCSB_container.parent().width())){ + mCSB_container.css({"width":w,"min-width":"100%","overflow-x":"inherit"}); + }else{ + /* + wrap content with an infinite width div and set its position to absolute and width to auto. + Setting width to auto before calculating the actual width is important! + We must let the browser set the width as browser zoom values are impossible to calculate. + */ + mCSB_container.css({"overflow-x":"inherit","position":"absolute"}) + .wrap("
    ") + .css({ /* set actual width, original position and un-wrap */ + /* + get the exact width (with decimals) and then round-up. + Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width + */ + "width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)), + "min-width":"100%", + "position":"relative" + }).unwrap(); + } + } + }, + /* -------------------- */ + + + /* adds scrollbar buttons */ + _scrollButtons=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"), + tabindex=!_isNumeric(o.scrollButtons.tabindex) ? "" : "tabindex='"+o.scrollButtons.tabindex+"'", + btnHTML=[ + "", + "", + "", + "" + ], + btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]]; + if(o.scrollButtons.enable){ + mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]); + } + }, + /* -------------------- */ + + + /* auto-adjusts scrollbar dragger length */ + _setDraggerLength=function(){ + var $this=$(this),d=$this.data(pluginPfx), + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], + ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)], + l=[ + parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()), + parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width()) + ], + h=oldIE && (l[1]contentHeight){contentHeight=h;} + if(w>contentWidth){contentWidth=w;} + return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()]; + }, + /* -------------------- */ + + + /* resets content position to 0 */ + _resetContentPosition=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; + _stop($this); /* stop any current scrolling before resetting */ + if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */ + mCSB_dragger[0].add(mCSB_container).css("top",0); + _scrollTo($this,"_resetY"); + } + if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */ + var cx=dx=0; + if(d.langDir==="rtl"){ /* adjust left position for rtl direction */ + cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false); + dx=Math.abs(cx/d.scrollRatio.x); + } + mCSB_container.css("left",cx); + mCSB_dragger[1].css("left",dx); + _scrollTo($this,"_resetX"); + } + }, + /* -------------------- */ + + + /* binds scrollbar events */ + _bindEvents=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt; + if(!d.bindEvents){ /* check if events are already bound */ + _draggable.call(this); + if(o.contentTouchScroll){_contentDraggable.call(this);} + _selectable.call(this); + if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */ + function _mwt(){ + mousewheelTimeout=setTimeout(function(){ + if(!$.event.special.mousewheel){ + _mwt(); + }else{ + clearTimeout(mousewheelTimeout); + _mousewheel.call($this[0]); + } + },100); + } + var mousewheelTimeout; + _mwt(); + } + _draggerRail.call(this); + _wrapperScroll.call(this); + if(o.advanced.autoScrollOnFocus){_focus.call(this);} + if(o.scrollButtons.enable){_buttons.call(this);} + if(o.keyboard.enable){_keyboard.call(this);} + d.bindEvents=true; + } + }, + /* -------------------- */ + + + /* unbinds scrollbar events */ + _unbindEvents=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + namespace=pluginPfx+"_"+d.idx, + sb=".mCSB_"+d.idx+"_scrollbar", + sel=$("#mCSB_"+d.idx+",#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,"+sb+" ."+classes[12]+",#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal,"+sb+">a"), + mCSB_container=$("#mCSB_"+d.idx+"_container"); + if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));} + if(o.advanced.extraDraggableSelectors){sel.add($(o.advanced.extraDraggableSelectors));} + if(d.bindEvents){ /* check if events are bound */ + /* unbind namespaced events from document/selectors */ + $(document).add($(!_canAccessIFrame() || top.document)).unbind("."+namespace); + sel.each(function(){ + $(this).unbind("."+namespace); + }); + /* clear and delete timeouts/objects */ + clearTimeout($this[0]._focusTimeout); _delete($this[0],"_focusTimeout"); + clearTimeout(d.sequential.step); _delete(d.sequential,"step"); + clearTimeout(mCSB_container[0].onCompleteTimeout); _delete(mCSB_container[0],"onCompleteTimeout"); + d.bindEvents=false; + } + }, + /* -------------------- */ + + + /* toggles scrollbar visibility */ + _scrollbarVisibility=function(disabled){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"), + content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"), + scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")], + mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")]; + if(o.axis!=="x"){ + if(d.overflowed[0] && !disabled){ + scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block"); + content.removeClass(classes[8]+" "+classes[10]); + }else{ + if(o.alwaysShowScrollbar){ + if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].css("display","none");} + content.removeClass(classes[10]); + }else{ + scrollbar[0].css("display","none"); + content.addClass(classes[10]); + } + content.addClass(classes[8]); + } + } + if(o.axis!=="y"){ + if(d.overflowed[1] && !disabled){ + scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block"); + content.removeClass(classes[9]+" "+classes[11]); + }else{ + if(o.alwaysShowScrollbar){ + if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].css("display","none");} + content.removeClass(classes[11]); + }else{ + scrollbar[1].css("display","none"); + content.addClass(classes[11]); + } + content.addClass(classes[9]); + } + } + if(!d.overflowed[0] && !d.overflowed[1]){ + $this.addClass(classes[5]); + }else{ + $this.removeClass(classes[5]); + } + }, + /* -------------------- */ + + + /* returns input coordinates of pointer, touch and mouse events (relative to document) */ + _coordinates=function(e){ + var t=e.type,o=e.target.ownerDocument!==document && frameElement!==null ? [$(frameElement).offset().top,$(frameElement).offset().left] : null, + io=_canAccessIFrame() && e.target.ownerDocument!==top.document && frameElement!==null ? [$(e.view.frameElement).offset().top,$(e.view.frameElement).offset().left] : [0,0]; + switch(t){ + case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp": + return o ? [e.originalEvent.pageY-o[0]+io[0],e.originalEvent.pageX-o[1]+io[1],false] : [e.originalEvent.pageY,e.originalEvent.pageX,false]; + break; + case "touchstart": case "touchmove": case "touchend": + var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], + touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length; + return e.target.ownerDocument!==document ? [touch.screenY,touch.screenX,touches>1] : [touch.pageY,touch.pageX,touches>1]; + break; + default: + return o ? [e.pageY-o[0]+io[0],e.pageX-o[1]+io[1],false] : [e.pageY,e.pageX,false]; + } + }, + /* -------------------- */ + + + /* + SCROLLBAR DRAG EVENTS + scrolls content via scrollbar dragging + */ + _draggable=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + namespace=pluginPfx+"_"+d.idx, + draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"], + mCSB_container=$("#mCSB_"+d.idx+"_container"), + mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]), + draggable,dragY,dragX, + rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger, + eds=o.advanced.extraDraggableSelectors ? $(!_canAccessIFrame() || top.document).add($(o.advanced.extraDraggableSelectors)) : $(!_canAccessIFrame() || top.document); + mCSB_dragger.bind("contextmenu."+namespace,function(e){ + e.preventDefault(); //prevent right click + }).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ + e.stopImmediatePropagation(); + e.preventDefault(); + if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ + touchActive=true; + if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */ + _iframe.call(mCSB_container,false); /* enable scrollbar dragging over iframes by disabling their events */ + _stop($this); + draggable=$(this); + var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, + h=draggable.height()+offset.top,w=draggable.width()+offset.left; + if(y0 && x0){ + dragY=y; + dragX=x; + } + _onDragClasses(draggable,"active",o.autoExpandScrollbar); + }).bind("touchmove."+namespace,function(e){ + e.stopImmediatePropagation(); + e.preventDefault(); + var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; + _drag(dragY,dragX,y,x); + }); + $(document).add(eds).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){ + if(draggable){ + var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; + if(dragY===y && dragX===x){return;} /* has it really moved? */ + _drag(dragY,dragX,y,x); + } + }).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ + if(draggable){ + _onDragClasses(draggable,"active",o.autoExpandScrollbar); + draggable=null; + } + touchActive=false; + if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */ + _iframe.call(mCSB_container,true); /* enable iframes events */ + }); + function _drag(dragY,dragX,y,x){ + mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0; + if(draggable.attr("id")===draggerId[1]){ + var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x; + }else{ + var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y; + } + _scrollTo($this,to.toString(),{dir:dir,drag:true}); + } + }, + /* -------------------- */ + + + /* + TOUCH SWIPE EVENTS + scrolls content via touch swipe + Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices + */ + _contentDraggable=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + namespace=pluginPfx+"_"+d.idx, + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], + draggable,dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount, + durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[],touchDrag,docDrag, + iframe=mCSB_container.find("iframe"), + events=[ + "touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace, //start + "touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace, //move + "touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace //end + ], + touchAction=document.body.style.touchAction!==undefined && document.body.style.touchAction!==""; + mCSB_container.bind(events[0],function(e){ + _onTouchstart(e); + }).bind(events[1],function(e){ + _onTouchmove(e); + }); + mCustomScrollBox.bind(events[0],function(e){ + _onTouchstart2(e); + }).bind(events[2],function(e){ + _onTouchend(e); + }); + if(iframe.length){ + iframe.each(function(){ + $(this).bind("load",function(){ + /* bind events on accessible iframes */ + if(_canAccessIFrame(this)){ + $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ + _onTouchstart(e); + _onTouchstart2(e); + }).bind(events[1],function(e){ + _onTouchmove(e); + }).bind(events[2],function(e){ + _onTouchend(e); + }); + } + }); + }); + } + function _onTouchstart(e){ + if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;} + touchable=1; touchDrag=0; docDrag=0; draggable=1; + $this.removeClass("mCS_touch_action"); + var offset=mCSB_container.offset(); + dragY=_coordinates(e)[0]-offset.top; + dragX=_coordinates(e)[1]-offset.left; + touchIntent=[_coordinates(e)[0],_coordinates(e)[1]]; + } + function _onTouchmove(e){ + if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;} + if(!o.documentTouchScroll){e.preventDefault();} + e.stopImmediatePropagation(); + if(docDrag && !touchDrag){return;} + if(draggable){ + runningTime=_getTime(); + var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, + easing="mcsLinearOut"; + touchMoveY.push(y); + touchMoveX.push(x); + touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]); + if(d.overflowed[0]){ + var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), + prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*20 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*230){return;} + speed=1000/(endTime-startTime); + var easing="mcsEaseOut",slow=speed<2.5, + diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0]; + distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX]; + var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])]; + speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed]; + var a=[ + Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])), + Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1])) + ]; + amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null]; + durB=[(absDistance[0]*4)+o.scrollInertia,(absDistance[1]*4)+o.scrollInertia]; + var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */ + amount[0]=absDistance[0]>md ? amount[0] : 0; + amount[1]=absDistance[1]>md ? amount[1] : 0; + if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite,false);} + if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite,false);} + } + function _m(ds,s){ + var r=[s*1.5,s*2,s/1.5,s/2]; + if(ds>90){ + return s>4 ? r[0] : r[3]; + }else if(ds>60){ + return s>3 ? r[3] : r[2]; + }else if(ds>30){ + return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2]; + }else{ + return s>8 ? s : r[3]; + } + } + function _drag(amount,dur,easing,dir,overwrite,drag){ + if(!amount){return;} + _scrollTo($this,amount.toString(),{dur:dur,scrollEasing:easing,dir:dir,overwrite:overwrite,drag:drag}); + } + }, + /* -------------------- */ + + + /* + SELECT TEXT EVENTS + scrolls content when text is selected + */ + _selectable=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, + namespace=pluginPfx+"_"+d.idx, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(), + action; + mCSB_container.bind("mousedown."+namespace,function(e){ + if(touchable){return;} + if(!action){action=1; touchActive=true;} + }).add(document).bind("mousemove."+namespace,function(e){ + if(!touchable && action && _sel()){ + var offset=mCSB_container.offset(), + y=_coordinates(e)[0]-offset.top+mCSB_container[0].offsetTop,x=_coordinates(e)[1]-offset.left+mCSB_container[0].offsetLeft; + if(y>0 && y0 && xwrapper.height()){ + _seq("on",40); + } + } + if(o.axis!=="y" && d.overflowed[1]){ + if(x<0){ + _seq("on",37); + }else if(x>wrapper.width()){ + _seq("on",39); + } + } + } + } + }).bind("mouseup."+namespace+" dragend."+namespace,function(e){ + if(touchable){return;} + if(action){action=0; _seq("off",null);} + touchActive=false; + }); + function _sel(){ + return window.getSelection ? window.getSelection().toString() : + document.selection && document.selection.type!="Control" ? document.selection.createRange().text : 0; + } + function _seq(a,c,s){ + seq.type=s && action ? "stepped" : "stepless"; + seq.scrollAmount=10; + _sequentialScroll($this,a,c,"mcsLinearOut",s ? 60 : null); + } + }, + /* -------------------- */ + + + /* + MOUSE WHEEL EVENT + scrolls content via mouse-wheel + via mouse-wheel plugin (https://github.com/brandonaaron/jquery-mousewheel) + */ + _mousewheel=function(){ + if(!$(this).data(pluginPfx)){return;} /* Check if the scrollbar is ready to use mousewheel events (issue: #185) */ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + namespace=pluginPfx+"_"+d.idx, + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], + iframe=$("#mCSB_"+d.idx+"_container").find("iframe"); + if(iframe.length){ + iframe.each(function(){ + $(this).bind("load",function(){ + /* bind events on accessible iframes */ + if(_canAccessIFrame(this)){ + $(this.contentDocument || this.contentWindow.document).bind("mousewheel."+namespace,function(e,delta){ + _onMousewheel(e,delta); + }); + } + }); + }); + } + mCustomScrollBox.bind("mousewheel."+namespace,function(e,delta){ + _onMousewheel(e,delta); + }); + function _onMousewheel(e,delta){ + _stop($this); + if(_disableMousewheel($this,e.target)){return;} /* disables mouse-wheel when hovering specific elements */ + var deltaFactor=o.mouseWheel.deltaFactor!=="auto" ? parseInt(o.mouseWheel.deltaFactor) : (oldIE && e.deltaFactor<100) ? 100 : e.deltaFactor || 100, + dur=o.scrollInertia; + if(o.axis==="x" || o.mouseWheel.axis==="x"){ + var dir="x", + px=[Math.round(deltaFactor*d.scrollRatio.x),parseInt(o.mouseWheel.scrollAmount)], + amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.width() ? mCustomScrollBox.width()*0.9 : px[0], + contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetLeft), + draggerPos=mCSB_dragger[1][0].offsetLeft, + limit=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(), + dlt=o.mouseWheel.axis==="y" ? (e.deltaY || delta) : e.deltaX; + }else{ + var dir="y", + px=[Math.round(deltaFactor*d.scrollRatio.y),parseInt(o.mouseWheel.scrollAmount)], + amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.height() ? mCustomScrollBox.height()*0.9 : px[0], + contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetTop), + draggerPos=mCSB_dragger[0][0].offsetTop, + limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), + dlt=e.deltaY || delta; + } + if((dir==="y" && !d.overflowed[0]) || (dir==="x" && !d.overflowed[1])){return;} + if(o.mouseWheel.invert || e.webkitDirectionInvertedFromDevice){dlt=-dlt;} + if(o.mouseWheel.normalizeDelta){dlt=dlt<0 ? -1 : 1;} + if((dlt>0 && draggerPos!==0) || (dlt<0 && draggerPos!==limit) || o.mouseWheel.preventDefault){ + e.stopImmediatePropagation(); + e.preventDefault(); + } + if(e.deltaFactor<5 && !o.mouseWheel.normalizeDelta){ + //very low deltaFactor values mean some kind of delta acceleration (e.g. osx trackpad), so adjusting scrolling accordingly + amount=e.deltaFactor; dur=17; + } + _scrollTo($this,(contentPos-(dlt*amount)).toString(),{dir:dir,dur:dur}); + } + }, + /* -------------------- */ + + + /* checks if iframe can be accessed */ + _canAccessIFrameCache=new Object(), + _canAccessIFrame=function(iframe){ + var result=false,cacheKey=false,html=null; + if(iframe===undefined){ + cacheKey="#empty"; + }else if($(iframe).attr("id")!==undefined){ + cacheKey=$(iframe).attr("id"); + } + if(cacheKey!==false && _canAccessIFrameCache[cacheKey]!==undefined){ + return _canAccessIFrameCache[cacheKey]; + } + if(!iframe){ + try{ + var doc=top.document; + html=doc.body.innerHTML; + }catch(err){/* do nothing */} + result=(html!==null); + }else{ + try{ + var doc=iframe.contentDocument || iframe.contentWindow.document; + html=doc.body.innerHTML; + }catch(err){/* do nothing */} + result=(html!==null); + } + if(cacheKey!==false){_canAccessIFrameCache[cacheKey]=result;} + return result; + }, + /* -------------------- */ + + + /* switches iframe's pointer-events property (drag, mousewheel etc. over cross-domain iframes) */ + _iframe=function(evt){ + var el=this.find("iframe"); + if(!el.length){return;} /* check if content contains iframes */ + var val=!evt ? "none" : "auto"; + el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */ + }, + /* -------------------- */ + + + /* disables mouse-wheel when hovering specific elements like select, datalist etc. */ + _disableMousewheel=function(el,target){ + var tag=target.nodeName.toLowerCase(), + tags=el.data(pluginPfx).opt.mouseWheel.disableOver, + /* elements that require focus */ + focusTags=["select","textarea"]; + return $.inArray(tag,tags) > -1 && !($.inArray(tag,focusTags) > -1 && !$(target).is(":focus")); + }, + /* -------------------- */ + + + /* + DRAGGER RAIL CLICK EVENT + scrolls content via dragger rail + */ + _draggerRail=function(){ + var $this=$(this),d=$this.data(pluginPfx), + namespace=pluginPfx+"_"+d.idx, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(), + mCSB_draggerContainer=$(".mCSB_"+d.idx+"_scrollbar ."+classes[12]), + clickable; + mCSB_draggerContainer.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ + touchActive=true; + if(!$(e.target).hasClass("mCSB_dragger")){clickable=1;} + }).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ + touchActive=false; + }).bind("click."+namespace,function(e){ + if(!clickable){return;} + clickable=0; + if($(e.target).hasClass(classes[12]) || $(e.target).hasClass("mCSB_draggerRail")){ + _stop($this); + var el=$(this),mCSB_dragger=el.find(".mCSB_dragger"); + if(el.parent(".mCSB_scrollTools_horizontal").length>0){ + if(!d.overflowed[1]){return;} + var dir="x", + clickDir=e.pageX>mCSB_dragger.offset().left ? -1 : 1, + to=Math.abs(mCSB_container[0].offsetLeft)-(clickDir*(wrapper.width()*0.9)); + }else{ + if(!d.overflowed[0]){return;} + var dir="y", + clickDir=e.pageY>mCSB_dragger.offset().top ? -1 : 1, + to=Math.abs(mCSB_container[0].offsetTop)-(clickDir*(wrapper.height()*0.9)); + } + _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); + } + }); + }, + /* -------------------- */ + + + /* + FOCUS EVENT + scrolls content via element focus (e.g. clicking an input, pressing TAB key etc.) + */ + _focus=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + namespace=pluginPfx+"_"+d.idx, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(); + mCSB_container.bind("focusin."+namespace,function(e){ + var el=$(document.activeElement), + nested=mCSB_container.find(".mCustomScrollBox").length, + dur=0; + if(!el.is(o.advanced.autoScrollOnFocus)){return;} + _stop($this); + clearTimeout($this[0]._focusTimeout); + $this[0]._focusTimer=nested ? (dur+17)*nested : 0; + $this[0]._focusTimeout=setTimeout(function(){ + var to=[_childPos(el)[0],_childPos(el)[1]], + contentPos=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], + isVisible=[ + (contentPos[0]+to[0]>=0 && contentPos[0]+to[0]=0 && contentPos[0]+to[1]a"); + btn.bind("contextmenu."+namespace,function(e){ + e.preventDefault(); //prevent right click + }).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace+" mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace+" mouseout."+namespace+" pointerout."+namespace+" MSPointerOut."+namespace+" click."+namespace,function(e){ + e.preventDefault(); + if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ + var btnClass=$(this).attr("class"); + seq.type=o.scrollButtons.scrollType; + switch(e.type){ + case "mousedown": case "touchstart": case "pointerdown": case "MSPointerDown": + if(seq.type==="stepped"){return;} + touchActive=true; + d.tweenRunning=false; + _seq("on",btnClass); + break; + case "mouseup": case "touchend": case "pointerup": case "MSPointerUp": + case "mouseout": case "pointerout": case "MSPointerOut": + if(seq.type==="stepped"){return;} + touchActive=false; + if(seq.dir){_seq("off",btnClass);} + break; + case "click": + if(seq.type!=="stepped" || d.tweenRunning){return;} + _seq("on",btnClass); + break; + } + function _seq(a,c){ + seq.scrollAmount=o.scrollButtons.scrollAmount; + _sequentialScroll($this,a,c); + } + }); + }, + /* -------------------- */ + + + /* + KEYBOARD EVENTS + scrolls content via keyboard + Keys: up arrow, down arrow, left arrow, right arrow, PgUp, PgDn, Home, End + */ + _keyboard=function(){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, + namespace=pluginPfx+"_"+d.idx, + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(), + editables="input,textarea,select,datalist,keygen,[contenteditable='true']", + iframe=mCSB_container.find("iframe"), + events=["blur."+namespace+" keydown."+namespace+" keyup."+namespace]; + if(iframe.length){ + iframe.each(function(){ + $(this).bind("load",function(){ + /* bind events on accessible iframes */ + if(_canAccessIFrame(this)){ + $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ + _onKeyboard(e); + }); + } + }); + }); + } + mCustomScrollBox.attr("tabindex","0").bind(events[0],function(e){ + _onKeyboard(e); + }); + function _onKeyboard(e){ + switch(e.type){ + case "blur": + if(d.tweenRunning && seq.dir){_seq("off",null);} + break; + case "keydown": case "keyup": + var code=e.keyCode ? e.keyCode : e.which,action="on"; + if((o.axis!=="x" && (code===38 || code===40)) || (o.axis!=="y" && (code===37 || code===39))){ + /* up (38), down (40), left (37), right (39) arrows */ + if(((code===38 || code===40) && !d.overflowed[0]) || ((code===37 || code===39) && !d.overflowed[1])){return;} + if(e.type==="keyup"){action="off";} + if(!$(document.activeElement).is(editables)){ + e.preventDefault(); + e.stopImmediatePropagation(); + _seq(action,code); + } + }else if(code===33 || code===34){ + /* PgUp (33), PgDn (34) */ + if(d.overflowed[0] || d.overflowed[1]){ + e.preventDefault(); + e.stopImmediatePropagation(); + } + if(e.type==="keyup"){ + _stop($this); + var keyboardDir=code===34 ? -1 : 1; + if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ + var dir="x",to=Math.abs(mCSB_container[0].offsetLeft)-(keyboardDir*(wrapper.width()*0.9)); + }else{ + var dir="y",to=Math.abs(mCSB_container[0].offsetTop)-(keyboardDir*(wrapper.height()*0.9)); + } + _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); + } + }else if(code===35 || code===36){ + /* End (35), Home (36) */ + if(!$(document.activeElement).is(editables)){ + if(d.overflowed[0] || d.overflowed[1]){ + e.preventDefault(); + e.stopImmediatePropagation(); + } + if(e.type==="keyup"){ + if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ + var dir="x",to=code===35 ? Math.abs(wrapper.width()-mCSB_container.outerWidth(false)) : 0; + }else{ + var dir="y",to=code===35 ? Math.abs(wrapper.height()-mCSB_container.outerHeight(false)) : 0; + } + _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); + } + } + } + break; + } + function _seq(a,c){ + seq.type=o.keyboard.scrollType; + seq.scrollAmount=o.keyboard.scrollAmount; + if(seq.type==="stepped" && d.tweenRunning){return;} + _sequentialScroll($this,a,c); + } + } + }, + /* -------------------- */ + + + /* scrolls content sequentially (used when scrolling via buttons, keyboard arrows etc.) */ + _sequentialScroll=function(el,action,trigger,e,s){ + var d=el.data(pluginPfx),o=d.opt,seq=d.sequential, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + once=seq.type==="stepped" ? true : false, + steplessSpeed=o.scrollInertia < 26 ? 26 : o.scrollInertia, /* 26/1.5=17 */ + steppedSpeed=o.scrollInertia < 1 ? 17 : o.scrollInertia; + switch(action){ + case "on": + seq.dir=[ + (trigger===classes[16] || trigger===classes[15] || trigger===39 || trigger===37 ? "x" : "y"), + (trigger===classes[13] || trigger===classes[15] || trigger===38 || trigger===37 ? -1 : 1) + ]; + _stop(el); + if(_isNumeric(trigger) && seq.type==="stepped"){return;} + _on(once); + break; + case "off": + _off(); + if(once || (d.tweenRunning && seq.dir)){ + _on(true); + } + break; + } + + /* starts sequence */ + function _on(once){ + if(o.snapAmount){seq.scrollAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : seq.dir[0]==="x" ? o.snapAmount[1] : o.snapAmount[0];} /* scrolling snapping */ + var c=seq.type!=="stepped", /* continuous scrolling */ + t=s ? s : !once ? 1000/60 : c ? steplessSpeed/1.5 : steppedSpeed, /* timer */ + m=!once ? 2.5 : c ? 7.5 : 40, /* multiplier */ + contentPos=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)], + ratio=[d.scrollRatio.y>10 ? 10 : d.scrollRatio.y,d.scrollRatio.x>10 ? 10 : d.scrollRatio.x], + amount=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*(ratio[1]*m)) : contentPos[0]+(seq.dir[1]*(ratio[0]*m)), + px=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*parseInt(seq.scrollAmount)) : contentPos[0]+(seq.dir[1]*parseInt(seq.scrollAmount)), + to=seq.scrollAmount!=="auto" ? px : amount, + easing=e ? e : !once ? "mcsLinear" : c ? "mcsLinearOut" : "mcsEaseInOut", + onComplete=!once ? false : true; + if(once && t<17){ + to=seq.dir[0]==="x" ? contentPos[1] : contentPos[0]; + } + _scrollTo(el,to.toString(),{dir:seq.dir[0],scrollEasing:easing,dur:t,onComplete:onComplete}); + if(once){ + seq.dir=false; + return; + } + clearTimeout(seq.step); + seq.step=setTimeout(function(){ + _on(); + },t); + } + /* stops sequence */ + function _off(){ + clearTimeout(seq.step); + _delete(seq,"step"); + _stop(el); + } + }, + /* -------------------- */ + + + /* returns a yx array from value */ + _arr=function(val){ + var o=$(this).data(pluginPfx).opt,vals=[]; + if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */ + /* check if value is object or array, its length and create an array with yx values */ + if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */ + vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val; + vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val; + }else{ /* array value (e.g. [100,100]) */ + vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null]; + } + /* check if array values are anonymous functions */ + if(typeof vals[0]==="function"){vals[0]=vals[0]();} + if(typeof vals[1]==="function"){vals[1]=vals[1]();} + return vals; + }, + /* -------------------- */ + + + /* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */ + _to=function(val,dir){ + if(val==null || typeof val=="undefined"){return;} + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(), + t=typeof val; + if(!dir){dir=o.axis==="x" ? "x" : "y";} + var contentLength=dir==="x" ? mCSB_container.outerWidth(false)-wrapper.width() : mCSB_container.outerHeight(false)-wrapper.height(), + contentPos=dir==="x" ? mCSB_container[0].offsetLeft : mCSB_container[0].offsetTop, + cssProp=dir==="x" ? "left" : "top"; + switch(t){ + case "function": /* this currently is not used. Consider removing it */ + return val(); + break; + case "object": /* js/jquery object */ + var obj=val.jquery ? val : $(val); + if(!obj.length){return;} + return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; + break; + case "string": case "number": + if(_isNumeric(val)){ /* numeric value */ + return Math.abs(val); + }else if(val.indexOf("%")!==-1){ /* percentage value */ + return Math.abs(contentLength*parseInt(val)/100); + }else if(val.indexOf("-=")!==-1){ /* decrease value */ + return Math.abs(contentPos-parseInt(val.split("-=")[1])); + }else if(val.indexOf("+=")!==-1){ /* inrease value */ + var p=(contentPos+parseInt(val.split("+=")[1])); + return p>=0 ? 0 : Math.abs(p); + }else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */ + return Math.abs(val.split("px")[0]); + }else{ + if(val==="top" || val==="left"){ /* special strings */ + return 0; + }else if(val==="bottom"){ + return Math.abs(wrapper.height()-mCSB_container.outerHeight(false)); + }else if(val==="right"){ + return Math.abs(wrapper.width()-mCSB_container.outerWidth(false)); + }else if(val==="first" || val==="last"){ + var obj=mCSB_container.find(":"+val); + return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; + }else{ + if($(val).length){ /* jquery selector */ + return dir==="x" ? _childPos($(val))[1] : _childPos($(val))[0]; + }else{ /* other values (e.g. "100em") */ + mCSB_container.css(cssProp,val); + methods.update.call(null,$this[0]); + return; + } + } + } + break; + } + }, + /* -------------------- */ + + + /* calls the update method automatically */ + _autoUpdate=function(rem){ + var $this=$(this),d=$this.data(pluginPfx),o=d.opt, + mCSB_container=$("#mCSB_"+d.idx+"_container"); + if(rem){ + /* + removes autoUpdate timer + usage: _autoUpdate.call(this,"remove"); + */ + clearTimeout(mCSB_container[0].autoUpdate); + _delete(mCSB_container[0],"autoUpdate"); + return; + } + upd(); + function upd(){ + clearTimeout(mCSB_container[0].autoUpdate); + if($this.parents("html").length===0){ + /* check element in dom tree */ + $this=null; + return; + } + mCSB_container[0].autoUpdate=setTimeout(function(){ + /* update on specific selector(s) length and size change */ + if(o.advanced.updateOnSelectorChange){ + d.poll.change.n=sizesSum(); + if(d.poll.change.n!==d.poll.change.o){ + d.poll.change.o=d.poll.change.n; + doUpd(3); + return; + } + } + /* update on main element and scrollbar size changes */ + if(o.advanced.updateOnContentResize){ + d.poll.size.n=$this[0].scrollHeight+$this[0].scrollWidth+mCSB_container[0].offsetHeight+$this[0].offsetHeight+$this[0].offsetWidth; + if(d.poll.size.n!==d.poll.size.o){ + d.poll.size.o=d.poll.size.n; + doUpd(1); + return; + } + } + /* update on image load */ + if(o.advanced.updateOnImageLoad){ + if(!(o.advanced.updateOnImageLoad==="auto" && o.axis==="y")){ //by default, it doesn't run on vertical content + d.poll.img.n=mCSB_container.find("img").length; + if(d.poll.img.n!==d.poll.img.o){ + d.poll.img.o=d.poll.img.n; + mCSB_container.find("img").each(function(){ + imgLoader(this); + }); + return; + } + } + } + if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();} + },o.advanced.autoUpdateTimeout); + } + /* a tiny image loader */ + function imgLoader(el){ + if($(el).hasClass(classes[2])){doUpd(); return;} + var img=new Image(); + function createDelegate(contextObject,delegateMethod){ + return function(){return delegateMethod.apply(contextObject,arguments);} + } + function imgOnLoad(){ + this.onload=null; + $(el).addClass(classes[2]); + doUpd(2); + } + img.onload=createDelegate(img,imgOnLoad); + img.src=el.src; + } + /* returns the total height and width sum of all elements matching the selector */ + function sizesSum(){ + if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";} + var total=0,sel=mCSB_container.find(o.advanced.updateOnSelectorChange); + if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=this.offsetHeight+this.offsetWidth;});} + return total; + } + /* calls the update method */ + function doUpd(cb){ + clearTimeout(mCSB_container[0].autoUpdate); + methods.update.call(null,$this[0],cb); + } + }, + /* -------------------- */ + + + /* snaps scrolling to a multiple of a pixels number */ + _snapAmount=function(to,amount,offset){ + return (Math.round(to/amount)*amount-offset); + }, + /* -------------------- */ + + + /* stops content and scrollbar animations */ + _stop=function(el){ + var d=el.data(pluginPfx), + sel=$("#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal"); + sel.each(function(){ + _stopTween.call(this); + }); + }, + /* -------------------- */ + + + /* + ANIMATES CONTENT + This is where the actual scrolling happens + */ + _scrollTo=function(el,to,options){ + var d=el.data(pluginPfx),o=d.opt, + defaults={ + trigger:"internal", + dir:"y", + scrollEasing:"mcsEaseOut", + drag:false, + dur:o.scrollInertia, + overwrite:"all", + callbacks:true, + onStart:true, + onUpdate:true, + onComplete:true + }, + options=$.extend(defaults,options), + dur=[options.dur,(options.drag ? 0 : options.dur)], + mCustomScrollBox=$("#mCSB_"+d.idx), + mCSB_container=$("#mCSB_"+d.idx+"_container"), + wrapper=mCSB_container.parent(), + totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0], + totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0]; + d.trigger=options.trigger; + if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */ + $(".mCSB_"+d.idx+"_scrollbar").css("visibility","visible"); + wrapper.scrollTop(0).scrollLeft(0); + } + if(to==="_resetY" && !d.contentReset.y){ + /* callbacks: onOverflowYNone */ + if(_cb("onOverflowYNone")){o.callbacks.onOverflowYNone.call(el[0]);} + d.contentReset.y=1; + } + if(to==="_resetX" && !d.contentReset.x){ + /* callbacks: onOverflowXNone */ + if(_cb("onOverflowXNone")){o.callbacks.onOverflowXNone.call(el[0]);} + d.contentReset.x=1; + } + if(to==="_resetY" || to==="_resetX"){return;} + if((d.contentReset.y || !el[0].mcs) && d.overflowed[0]){ + /* callbacks: onOverflowY */ + if(_cb("onOverflowY")){o.callbacks.onOverflowY.call(el[0]);} + d.contentReset.x=null; + } + if((d.contentReset.x || !el[0].mcs) && d.overflowed[1]){ + /* callbacks: onOverflowX */ + if(_cb("onOverflowX")){o.callbacks.onOverflowX.call(el[0]);} + d.contentReset.x=null; + } + if(o.snapAmount){ /* scrolling snapping */ + var snapAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : options.dir==="x" ? o.snapAmount[1] : o.snapAmount[0]; + to=_snapAmount(to,snapAmount,o.snapOffset); + } + switch(options.dir){ + case "x": + var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_horizontal"), + property="left", + contentPos=mCSB_container[0].offsetLeft, + limit=[ + mCustomScrollBox.width()-mCSB_container.outerWidth(false), + mCSB_dragger.parent().width()-mCSB_dragger.width() + ], + scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.x)], + tso=totalScrollOffsets[1], + tsbo=totalScrollBackOffsets[1], + totalScrollOffset=tso>0 ? tso/d.scrollRatio.x : 0, + totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.x : 0; + break; + case "y": + var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_vertical"), + property="top", + contentPos=mCSB_container[0].offsetTop, + limit=[ + mCustomScrollBox.height()-mCSB_container.outerHeight(false), + mCSB_dragger.parent().height()-mCSB_dragger.height() + ], + scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.y)], + tso=totalScrollOffsets[0], + tsbo=totalScrollBackOffsets[0], + totalScrollOffset=tso>0 ? tso/d.scrollRatio.y : 0, + totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.y : 0; + break; + } + if(scrollTo[1]<0 || (scrollTo[0]===0 && scrollTo[1]===0)){ + scrollTo=[0,0]; + }else if(scrollTo[1]>=limit[1]){ + scrollTo=[limit[0],limit[1]]; + }else{ + scrollTo[0]=-scrollTo[0]; + } + if(!el[0].mcs){ + _mcs(); /* init mcs object (once) to make it available before callbacks */ + if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */ + } + clearTimeout(mCSB_container[0].onCompleteTimeout); + _tweenTo(mCSB_dragger[0],property,Math.round(scrollTo[1]),dur[1],options.scrollEasing); + if(!d.tweenRunning && ((contentPos===0 && scrollTo[0]>=0) || (contentPos===limit[0] && scrollTo[0]<=limit[0]))){return;} + _tweenTo(mCSB_container[0],property,Math.round(scrollTo[0]),dur[0],options.scrollEasing,options.overwrite,{ + onStart:function(){ + if(options.callbacks && options.onStart && !d.tweenRunning){ + /* callbacks: onScrollStart */ + if(_cb("onScrollStart")){_mcs(); o.callbacks.onScrollStart.call(el[0]);} + d.tweenRunning=true; + _onDragClasses(mCSB_dragger); + d.cbOffsets=_cbOffsets(); + } + },onUpdate:function(){ + if(options.callbacks && options.onUpdate){ + /* callbacks: whileScrolling */ + if(_cb("whileScrolling")){_mcs(); o.callbacks.whileScrolling.call(el[0]);} + } + },onComplete:function(){ + if(options.callbacks && options.onComplete){ + if(o.axis==="yx"){clearTimeout(mCSB_container[0].onCompleteTimeout);} + var t=mCSB_container[0].idleTimer || 0; + mCSB_container[0].onCompleteTimeout=setTimeout(function(){ + /* callbacks: onScroll, onTotalScroll, onTotalScrollBack */ + if(_cb("onScroll")){_mcs(); o.callbacks.onScroll.call(el[0]);} + if(_cb("onTotalScroll") && scrollTo[1]>=limit[1]-totalScrollOffset && d.cbOffsets[0]){_mcs(); o.callbacks.onTotalScroll.call(el[0]);} + if(_cb("onTotalScrollBack") && scrollTo[1]<=totalScrollBackOffset && d.cbOffsets[1]){_mcs(); o.callbacks.onTotalScrollBack.call(el[0]);} + d.tweenRunning=false; + mCSB_container[0].idleTimer=0; + _onDragClasses(mCSB_dragger,"hide"); + },t); + } + } + }); + /* checks if callback function exists */ + function _cb(cb){ + return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function"; + } + /* checks whether callback offsets always trigger */ + function _cbOffsets(){ + return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit[0]+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo]; + } + /* + populates object with useful values for the user + values: + content: this.mcs.content + content top position: this.mcs.top + content left position: this.mcs.left + dragger top position: this.mcs.draggerTop + dragger left position: this.mcs.draggerLeft + scrolling y percentage: this.mcs.topPct + scrolling x percentage: this.mcs.leftPct + scrolling direction: this.mcs.direction + */ + function _mcs(){ + var cp=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], /* content position */ + dp=[mCSB_dragger[0].offsetTop,mCSB_dragger[0].offsetLeft], /* dragger position */ + cl=[mCSB_container.outerHeight(false),mCSB_container.outerWidth(false)], /* content length */ + pl=[mCustomScrollBox.height(),mCustomScrollBox.width()]; /* content parent length */ + el[0].mcs={ + content:mCSB_container, /* original content wrapper as jquery object */ + top:cp[0],left:cp[1],draggerTop:dp[0],draggerLeft:dp[1], + topPct:Math.round((100*Math.abs(cp[0]))/(Math.abs(cl[0])-pl[0])),leftPct:Math.round((100*Math.abs(cp[1]))/(Math.abs(cl[1])-pl[1])), + direction:options.dir + }; + /* + this refers to the original element containing the scrollbar(s) + usage: this.mcs.top, this.mcs.leftPct etc. + */ + } + }, + /* -------------------- */ + + + /* + CUSTOM JAVASCRIPT ANIMATION TWEEN + Lighter and faster than jquery animate() and css transitions + Animates top/left properties and includes easings + */ + _tweenTo=function(el,prop,to,duration,easing,overwrite,callbacks){ + if(!el._mTween){el._mTween={top:{},left:{}};} + var callbacks=callbacks || {}, + onStart=callbacks.onStart || function(){},onUpdate=callbacks.onUpdate || function(){},onComplete=callbacks.onComplete || function(){}, + startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style,_request,tobj=el._mTween[prop]; + if(prop==="left"){from=el.offsetLeft;} + var diff=to-from; + tobj.stop=0; + if(overwrite!=="none"){_cancelTween();} + _startTween(); + function _step(){ + if(tobj.stop){return;} + if(!progress){onStart.call();} + progress=_getTime()-startTime; + _tween(); + if(progress>=tobj.time){ + tobj.time=(progress>tobj.time) ? progress+_delay-(progress-tobj.time) : progress+_delay-1; + if(tobj.time0){ + tobj.currVal=_ease(tobj.time,from,diff,duration,easing); + elStyle[prop]=Math.round(tobj.currVal)+"px"; + }else{ + elStyle[prop]=to+"px"; + } + onUpdate.call(); + } + function _startTween(){ + _delay=1000/60; + tobj.time=progress+_delay; + _request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame; + tobj.id=_request(_step); + } + function _cancelTween(){ + if(tobj.id==null){return;} + if(!window.requestAnimationFrame){clearTimeout(tobj.id); + }else{window.cancelAnimationFrame(tobj.id);} + tobj.id=null; + } + function _ease(t,b,c,d,type){ + switch(type){ + case "linear": case "mcsLinear": + return c*t/d + b; + break; + case "mcsLinearOut": + t/=d; t--; return c * Math.sqrt(1 - t*t) + b; + break; + case "easeInOutSmooth": + t/=d/2; + if(t<1) return c/2*t*t + b; + t--; + return -c/2 * (t*(t-2) - 1) + b; + break; + case "easeInOutStrong": + t/=d/2; + if(t<1) return c/2 * Math.pow( 2, 10 * (t - 1) ) + b; + t--; + return c/2 * ( -Math.pow( 2, -10 * t) + 2 ) + b; + break; + case "easeInOut": case "mcsEaseInOut": + t/=d/2; + if(t<1) return c/2*t*t*t + b; + t-=2; + return c/2*(t*t*t + 2) + b; + break; + case "easeOutSmooth": + t/=d; t--; + return -c * (t*t*t*t - 1) + b; + break; + case "easeOutStrong": + return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b; + break; + case "easeOut": case "mcsEaseOut": default: + var ts=(t/=d)*t,tc=ts*t; + return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t); + } + } + }, + /* -------------------- */ + + + /* returns current time */ + _getTime=function(){ + if(window.performance && window.performance.now){ + return window.performance.now(); + }else{ + if(window.performance && window.performance.webkitNow){ + return window.performance.webkitNow(); + }else{ + if(Date.now){return Date.now();}else{return new Date().getTime();} + } + } + }, + /* -------------------- */ + + + /* stops a tween */ + _stopTween=function(){ + var el=this; + if(!el._mTween){el._mTween={top:{},left:{}};} + var props=["top","left"]; + for(var i=0; i

    public virtual string DocumentStoreType { get; protected set; } - public virtual string GoogleCustomSearchId { get; set; } - public virtual Dictionary ExtraProperties { get; protected set; } public virtual string MainWebsiteUrl { get; set; } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/VersionInfo.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/VersionInfo.cs new file mode 100644 index 0000000000..c10781e508 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/VersionInfo.cs @@ -0,0 +1,12 @@ +using System; + +namespace Volo.Docs.Projects +{ + [Serializable] //Serialization needed because this object is stored in cache + public class VersionInfo + { + public string DisplayName { get; set; } + + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo.Docs.HttpApi.csproj b/modules/docs/src/Volo.Docs.HttpApi/Volo.Docs.HttpApi.csproj index c4b436c6f6..13d295b421 100644 --- a/modules/docs/src/Volo.Docs.HttpApi/Volo.Docs.HttpApi.csproj +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo.Docs.HttpApi.csproj @@ -11,6 +11,7 @@ + diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/DocsHttpApiModule.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/DocsHttpApiModule.cs index 003f2e3068..0d700576be 100644 --- a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/DocsHttpApiModule.cs +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/DocsHttpApiModule.cs @@ -1,9 +1,12 @@ -using Volo.Abp.Modularity; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; namespace Volo.Docs { [DependsOn( - typeof(DocsApplicationContractsModule))] + typeof(DocsApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule) + )] public class DocsHttpApiModule : AbpModule { diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs new file mode 100644 index 0000000000..54244bbe01 --- /dev/null +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Docs.Documents +{ + [RemoteService] + [Area("docs")] + [ControllerName("Document")] + [Route("api/docs/documents")] + public class DocsDocumentController : AbpController, IDocumentAppService + { + protected IDocumentAppService DocumentAppService { get; } + + public DocsDocumentController(IDocumentAppService documentAppService) + { + DocumentAppService = documentAppService; + } + + [HttpGet] + [Route("")] + public virtual Task GetAsync(GetDocumentInput input) + { + return DocumentAppService.GetAsync(input); + } + + [HttpGet] + [Route("default")] + public virtual Task GetDefaultAsync(GetDefaultDocumentInput input) + { + return DocumentAppService.GetDefaultAsync(input); + } + + [HttpGet] + [Route("navigation")] + public virtual Task GetNavigationAsync(GetNavigationDocumentInput input) + { + return DocumentAppService.GetNavigationAsync(input); + } + + [HttpGet] + [Route("resource")] + public Task GetResourceAsync(GetDocumentResourceInput input) + { + return DocumentAppService.GetResourceAsync(input); + } + } +} diff --git a/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs new file mode 100644 index 0000000000..773655aab8 --- /dev/null +++ b/modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Projects/DocsProjectController.cs @@ -0,0 +1,43 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; + +namespace Volo.Docs.Projects +{ + [RemoteService] + [Area("docs")] + [ControllerName("Project")] + [Route("api/docs/projects")] + public class DocsProjectController : AbpController, IProjectAppService + { + protected IProjectAppService ProjectAppService { get; } + + public DocsProjectController(IProjectAppService projectAppService) + { + ProjectAppService = projectAppService; + } + + [HttpGet] + [Route("")] + public virtual Task> GetListAsync() + { + return ProjectAppService.GetListAsync(); + } + + [HttpGet] + [Route("{shortName}")] + public virtual Task GetAsync(string shortName) + { + return ProjectAppService.GetAsync(shortName); + } + + [HttpGet] + [Route("{shortName}/versions")] + public virtual Task> GetVersionsAsync(string shortName) + { + return ProjectAppService.GetVersionsAsync(shortName); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs new file mode 100644 index 0000000000..0061c6e999 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentResourceController.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Http; +using Volo.Abp.IO; +using Volo.Docs.Documents; + +namespace Volo.Docs.Areas.Documents +{ + [RemoteService] + [Area("docs")] + [ControllerName("DocumentResource")] + [Route("document-resources")] + public class DocumentResourceController : AbpController + { + private readonly IDocumentAppService _documentAppService; + + public DocumentResourceController(IDocumentAppService documentAppService) + { + _documentAppService = documentAppService; + } + + [HttpGet] + [Route("")] + //[Produces(MimeTypes.Image.Jpeg, MimeTypes.Image.Png, MimeTypes.Image.Gif)] + public async Task GetResource(GetDocumentResourceInput input) + { + input.Name = input.Name.RemovePreFix("/"); + var documentResource = await _documentAppService.GetResourceAsync(input); + var contentType = MimeTypes.GetByExtension(FileHelper.GetExtension(input.Name)); + return File(documentResource.Content, contentType); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/Helpers/TagHelpers/TreeTagHelper.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs similarity index 95% rename from modules/docs/src/Volo.Docs.Web/Areas/Documents/Helpers/TagHelpers/TreeTagHelper.cs rename to modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs index bab4600677..38e95a6e93 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/Helpers/TagHelpers/TreeTagHelper.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs @@ -5,8 +5,10 @@ using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Docs.Documents; using Volo.Docs.Utils; -namespace Volo.Docs.Areas.Documents.Helpers.TagHelpers +namespace Volo.Docs.Areas.Documents.TagHelpers { + //TODO: Better to convert element "document-nav-tree" + //TODO: Or better to convert to a partial view or to a view component instead of a tag helper! [HtmlTargetElement("ul", Attributes = "root-node")] public class TreeTagHelper : TagHelper { diff --git a/modules/docs/src/Volo.Docs.Web/DocsWebAutoMapperProfile.cs b/modules/docs/src/Volo.Docs.Web/DocsWebAutoMapperProfile.cs new file mode 100644 index 0000000000..4a25c94370 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/DocsWebAutoMapperProfile.cs @@ -0,0 +1,15 @@ +using AutoMapper; +using Volo.Abp.AutoMapper; +using Volo.Docs.Documents; + +namespace Volo.Docs +{ + public class DocsWebAutoMapperProfile : Profile + { + public DocsWebAutoMapperProfile() + { + CreateMap() + .Ignore(x => x.RootNode); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs b/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs index cbda4d697f..1791463fb3 100644 --- a/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs +++ b/modules/docs/src/Volo.Docs.Web/DocsWebModule.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; +using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; +using Volo.Docs.HtmlConverting; using Volo.Docs.Localization; +using Volo.Docs.Markdown; namespace Volo.Docs { @@ -34,6 +37,16 @@ namespace Volo.Docs //TODO: Make configurable! options.Conventions.AddPageRoute("/Documents/Project/Index", "documents/{projectName}/{version}/{*documentName}"); }); + + Configure(options => + { + options.AddProfile(validate: true); + }); + + Configure(options => + { + options.Converters[MarkdownDocumentToHtmlConverter.Type] = typeof(MarkdownDocumentToHtmlConverter); + }); } } } diff --git a/modules/docs/src/Volo.Docs.Web/Formatting/DocumentConverterFactory.cs b/modules/docs/src/Volo.Docs.Web/Formatting/DocumentConverterFactory.cs deleted file mode 100644 index 74c73590c2..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Formatting/DocumentConverterFactory.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.DependencyInjection; - -namespace Volo.Docs.Formatting -{ - public class DocumentConverterFactory : IDocumentConverterFactory, ITransientDependency - { - private readonly IServiceProvider _serviceProvider; - - public DocumentConverterFactory(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public IDocumentConverter Create(string format) - { - switch (format.ToLowerInvariant()) - { - case MarkdownDocumentConverter.Type: - return _serviceProvider.GetRequiredService(); - default: - throw new ApplicationException($"Undefined document formatting: {format}"); - } - } - } -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverter.cs b/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverter.cs deleted file mode 100644 index ef11fc6851..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverter.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Volo.Docs.Formatting -{ - public interface IDocumentConverter - { - string Convert(string content); - - string NormalizeLinks(string content, string projectShortName, string version, string documentLocalDirectory); - } -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverterFactory.cs b/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverterFactory.cs deleted file mode 100644 index 20fe67f142..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Formatting/IDocumentConverterFactory.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Docs.Formatting -{ - public interface IDocumentConverterFactory - { - IDocumentConverter Create(string format); - } -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Formatting/MarkdownDocumentConverter.cs b/modules/docs/src/Volo.Docs.Web/Formatting/MarkdownDocumentConverter.cs deleted file mode 100644 index c2189f2d72..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Formatting/MarkdownDocumentConverter.cs +++ /dev/null @@ -1,113 +0,0 @@ -using CommonMark; -using System; -using System.Text; -using System.Text.RegularExpressions; -using Volo.Abp.DependencyInjection; -using Volo.Docs.Utils; - -namespace Volo.Docs.Formatting -{ - public class MarkdownDocumentConverter : IDocumentConverter, ITransientDependency - { - public const string Type = "md"; - - private const string NewLinkFormat = "[{0}](/documents/{1}/{2}{3}/{4})"; - - private const string MarkdownLinkRegExp = @"\[([^)]+)\]\(([^)]+." + Type + @")\)"; - - private const string AnchorLinkRegExp = @"]+href=\""(.*?)\""[^>]*>(.*)?"; - - public string Convert(string content) - { - return content == null ? null : CommonMarkConverter.Convert(Encoding.UTF8.GetString(Encoding.Default.GetBytes(content))); - } - - public string NormalizeLinks(string content, string projectShortName, string version, - string documentLocalDirectory) - { - if (content == null) - { - return null; - } - - var normalized = Regex.Replace(content, MarkdownLinkRegExp, delegate (Match match) - { - var link = match.Groups[2].Value; - if (UrlHelper.IsExternalLink(link)) - { - return match.Value; - } - - var displayText = match.Groups[1].Value; - - var documentName = RemoveFileExtension(link); - var documentLocalDirectoryNormalized = documentLocalDirectory.TrimStart('/').TrimEnd('/'); - if (!string.IsNullOrWhiteSpace(documentLocalDirectoryNormalized)) - { - documentLocalDirectoryNormalized = "/" + documentLocalDirectoryNormalized; - } - - return string.Format(NewLinkFormat, displayText, projectShortName, version, documentLocalDirectoryNormalized, documentName); - }); - - normalized = Regex.Replace(normalized, AnchorLinkRegExp, delegate (Match match) - { - var link = match.Groups[1].Value; - if (IsRemoteUrl(link)) - { - return match.Value; - } - - var displayText = match.Groups[2].Value; - var documentName = RemoveFileExtension(link); - var documentLocalDirectoryNormalized = documentLocalDirectory.TrimStart('/').TrimEnd('/'); - if (!string.IsNullOrWhiteSpace(documentLocalDirectoryNormalized)) - { - documentLocalDirectoryNormalized = "/" + documentLocalDirectoryNormalized; - } - - return string.Format(NewLinkFormat, displayText, projectShortName, version, documentLocalDirectoryNormalized, documentName); - }); - - return normalized; - } - - private static string RemoveFileExtension(string documentName) - { - if (documentName == null) - { - return null; - } - - if (string.IsNullOrWhiteSpace(documentName)) - { - return documentName; - } - - if (!documentName.EndsWith(Type, StringComparison.OrdinalIgnoreCase)) - { - return documentName; - } - - return documentName.Left(documentName.Length - Type.Length - 1); - } - - //TODO: Merge with UrlHelper.IsExternalLink - private static bool IsRemoteUrl(string url) - { - if (url == null) - { - return true; - } - - try - { - return Regex.IsMatch(url, @"\A(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?\z"); - } - catch (Exception) - { - return true; - } - } - } -} diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterFactory.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterFactory.cs new file mode 100644 index 0000000000..a6a7978eee --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterFactory.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Docs.HtmlConverting +{ + public class DocumentToHtmlConverterFactory : IDocumentToHtmlConverterFactory, ITransientDependency + { + protected DocumentToHtmlConverterOptions Options { get; } + protected IServiceProvider ServiceProvider { get; } + + public DocumentToHtmlConverterFactory( + IServiceProvider serviceProvider, + IOptions options) + { + ServiceProvider = serviceProvider; + Options = options.Value; + } + + public virtual IDocumentToHtmlConverter Create(string format) + { + var serviceType = Options.Converters.GetOrDefault(format); + if (serviceType == null) + { + throw new ApplicationException($"Unknown document format: {format}"); + } + + return (IDocumentToHtmlConverter)ServiceProvider.GetRequiredService(serviceType); + } + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterOptions.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterOptions.cs new file mode 100644 index 0000000000..f332f6f58a --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/DocumentToHtmlConverterOptions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; + +namespace Volo.Docs.HtmlConverting +{ + public class DocumentToHtmlConverterOptions + { + public Dictionary Converters { get; set; } + + public DocumentToHtmlConverterOptions() + { + Converters = new Dictionary(); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/HtmlNormalizer.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs similarity index 97% rename from modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/HtmlNormalizer.cs rename to modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs index 248784a753..ed3f999614 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/HtmlNormalizer.cs +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/HtmlNormalizer.cs @@ -2,7 +2,7 @@ using System.Text.RegularExpressions; using Volo.Docs.Utils; -namespace Volo.Docs.Pages.Documents.Project +namespace Volo.Docs.HtmlConverting { public static class HtmlNormalizer { diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverter.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverter.cs new file mode 100644 index 0000000000..1ff429510b --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverter.cs @@ -0,0 +1,10 @@ +using Volo.Docs.Documents; +using Volo.Docs.Projects; + +namespace Volo.Docs.HtmlConverting +{ + public interface IDocumentToHtmlConverter + { + string Convert(ProjectDto project, DocumentWithDetailsDto document,string version); + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverterFactory.cs b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverterFactory.cs new file mode 100644 index 0000000000..9cdca43a8f --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/HtmlConverting/IDocumentToHtmlConverterFactory.cs @@ -0,0 +1,7 @@ +namespace Volo.Docs.HtmlConverting +{ + public interface IDocumentToHtmlConverterFactory + { + IDocumentToHtmlConverter Create(string format); + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs b/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs new file mode 100644 index 0000000000..7851d99a99 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs @@ -0,0 +1,120 @@ +using System; +using System.Text; +using System.Text.RegularExpressions; +using CommonMark; +using Volo.Abp.DependencyInjection; +using Volo.Docs.Documents; +using Volo.Docs.HtmlConverting; +using Volo.Docs.Projects; +using Volo.Docs.Utils; + +namespace Volo.Docs.Markdown +{ + public class MarkdownDocumentToHtmlConverter : IDocumentToHtmlConverter, ITransientDependency + { + public const string Type = "md"; + + private const string MdLinkFormat = "[{0}](/documents/{1}/{2}{3}/{4})"; + private const string MarkdownLinkRegExp = @"\[([^)]+)\]\(([^)]+." + Type + @")\)"; + private const string AnchorLinkRegExp = @"]+href=\""(.*?)\""[^>]*>(.*)?"; + + public virtual string Convert(ProjectDto project, DocumentWithDetailsDto document, string version) + { + if (document.Content.IsNullOrEmpty()) + { + return document.Content; + } + + var content = NormalizeLinks( + document.Content, + project.ShortName, + version, + document.LocalDirectory + ); + + return CommonMarkConverter.Convert(Encoding.UTF8.GetString(Encoding.Default.GetBytes(content))); + } + + protected virtual string NormalizeLinks( + string content, + string projectShortName, + string version, + string documentLocalDirectory) + { + var normalized = Regex.Replace(content, MarkdownLinkRegExp, delegate(Match match) + { + var link = match.Groups[2].Value; + if (UrlHelper.IsExternalLink(link)) + { + return match.Value; + } + + var displayText = match.Groups[1].Value; + + var documentName = RemoveFileExtension(link); + var documentLocalDirectoryNormalized = documentLocalDirectory.TrimStart('/').TrimEnd('/'); + if (!string.IsNullOrWhiteSpace(documentLocalDirectoryNormalized)) + { + documentLocalDirectoryNormalized = "/" + documentLocalDirectoryNormalized; + } + + return string.Format( + MdLinkFormat, + displayText, + projectShortName, + version, + documentLocalDirectoryNormalized, + documentName + ); + }); + + normalized = Regex.Replace(normalized, AnchorLinkRegExp, delegate (Match match) + { + var link = match.Groups[1].Value; + if (UrlHelper.IsExternalLink(link)) + { + return match.Value; + } + + var displayText = match.Groups[2].Value; + var documentName = RemoveFileExtension(link); + var documentLocalDirectoryNormalized = documentLocalDirectory.TrimStart('/').TrimEnd('/'); + if (!string.IsNullOrWhiteSpace(documentLocalDirectoryNormalized)) + { + documentLocalDirectoryNormalized = "/" + documentLocalDirectoryNormalized; + } + + return string.Format( + MdLinkFormat, + displayText, + projectShortName, + version, + documentLocalDirectoryNormalized, + documentName + ); + }); + + return normalized; + } + + private static string RemoveFileExtension(string documentName) + { + if (documentName == null) + { + return null; + } + + if (string.IsNullOrWhiteSpace(documentName)) + { + return documentName; + } + + if (!documentName.EndsWith(Type, StringComparison.OrdinalIgnoreCase)) + { + return documentName; + } + + return documentName.Left(documentName.Length - Type.Length - 1); + } + } +} diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationNode.cs b/modules/docs/src/Volo.Docs.Web/Models/NavigationNode.cs similarity index 100% rename from modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationNode.cs rename to modules/docs/src/Volo.Docs.Web/Models/NavigationNode.cs diff --git a/modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationWithDetailsDto.cs b/modules/docs/src/Volo.Docs.Web/Models/NavigationWithDetailsDto.cs similarity index 100% rename from modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationWithDetailsDto.cs rename to modules/docs/src/Volo.Docs.Web/Models/NavigationWithDetailsDto.cs diff --git a/modules/docs/src/Volo.Docs.Web/Models/VersionInfo.cs b/modules/docs/src/Volo.Docs.Web/Models/VersionInfoViewModel.cs similarity index 69% rename from modules/docs/src/Volo.Docs.Web/Models/VersionInfo.cs rename to modules/docs/src/Volo.Docs.Web/Models/VersionInfoViewModel.cs index 1cbe68a045..7def41b3f3 100644 --- a/modules/docs/src/Volo.Docs.Web/Models/VersionInfo.cs +++ b/modules/docs/src/Volo.Docs.Web/Models/VersionInfoViewModel.cs @@ -1,6 +1,6 @@ namespace Volo.Docs.Models { - public class VersionInfo + public class VersionInfoViewModel { public string DisplayText { get; set; } @@ -8,7 +8,7 @@ namespace Volo.Docs.Models public bool IsSelected { get; set; } - public VersionInfo(string displayText, string version, bool isSelected = false) + public VersionInfoViewModel(string displayText, string version, bool isSelected = false) { DisplayText = displayText; Version = version; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml index 59d2ae9e1b..00e5bcf069 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml @@ -10,7 +10,7 @@ } @section styles { - + } diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs index 97a2c85747..552aa0c21d 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs @@ -32,6 +32,7 @@ namespace Volo.Docs.Pages.Documents } Projects = listResult.Items; + return Page(); } } diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index b58e571473..29a6b786a6 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -1,5 +1,9 @@ @page @using Microsoft.AspNetCore.Mvc.Localization +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.MalihuCustomScrollbar +@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Popper @using Volo.Abp.AspNetCore.Mvc.UI.Theming @using Volo.Docs @using Volo.Docs.Localization @@ -10,33 +14,32 @@ @{ ViewBag.FluidLayout = true; Layout = ThemeManager.CurrentTheme.GetEmptyLayout(); - var projectDisplayName = Model.ProjectDisplayName ?? Model.ProjectName; } @section styles { - - - - - - + + + + + + } @section scripts { - + + + + + + + + + + + + - - - - - - - - - - - }
    @@ -46,10 +49,10 @@
    - @if (Model.Versions.Any()) + @if (Model.VersionSelectItems.Any()) {
    @@ -106,9 +109,9 @@ else { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 59f0524308..bd2c5e8485 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -3,16 +3,16 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.Rendering; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; using Volo.Docs.Documents; -using Volo.Docs.Formatting; +using Volo.Docs.HtmlConverting; using Volo.Docs.Models; using Volo.Docs.Projects; namespace Volo.Docs.Pages.Documents.Project { - public class IndexModel : PageModel + public class IndexModel : AbpPageModel { [BindProperty(SupportsGet = true)] public string ProjectName { get; set; } @@ -23,105 +23,82 @@ namespace Volo.Docs.Pages.Documents.Project [BindProperty(SupportsGet = true)] public string DocumentName { get; set; } - public string ProjectDisplayName { get; set; } - - public string ProjectFormat { get; private set; } + public ProjectDto Project { get; set; } public string DocumentNameWithExtension { get; private set; } public DocumentWithDetailsDto Document { get; private set; } - public List Versions { get; private set; } - public List VersionSelectItems { get; private set; } public NavigationWithDetailsDto Navigation { get; private set; } - public VersionInfo LatestVersionInfo { get; private set; } + public VersionInfoViewModel LatestVersionInfo { get; private set; } private readonly IDocumentAppService _documentAppService; - private readonly IDocumentConverterFactory _documentConverterFactory; + private readonly IDocumentToHtmlConverterFactory _documentToHtmlConverterFactory; private readonly IProjectAppService _projectAppService; public IndexModel( IDocumentAppService documentAppService, - IDocumentConverterFactory documentConverterFactory, + IDocumentToHtmlConverterFactory documentToHtmlConverterFactory, IProjectAppService projectAppService) { _documentAppService = documentAppService; - _documentConverterFactory = documentConverterFactory; + _documentToHtmlConverterFactory = documentToHtmlConverterFactory; _projectAppService = projectAppService; } - public async Task OnGet() + public async Task OnGetAsync() { - var project = await _projectAppService.GetByShortNameAsync(ProjectName); - - SetPageParams(project); - - await SetVersionAsync(project); - + await SetProjectAsync(); + await SetVersionAsync(); await SetDocumentAsync(); - await SetNavigationAsync(); } - private async Task SetNavigationAsync() + private async Task SetProjectAsync() { - try - { - Navigation = await _documentAppService.GetNavigationDocumentAsync(ProjectName, Version, false); - } - catch (DocumentNotFoundException) //TODO: What if called on a remote service which may return 404 - { - return; - } - - Navigation.ConvertItems(); + Project = await _projectAppService.GetAsync(ProjectName); } - private void SetPageParams(ProjectDto project) + private async Task SetVersionAsync() { - ProjectFormat = project.Format; - ProjectDisplayName = project.Name; + //TODO: Needs refactoring - if (DocumentName.IsNullOrWhiteSpace()) - { - DocumentName = project.DefaultDocumentName; - } - - DocumentNameWithExtension = DocumentName + "." + project.Format; - } + var output = await _projectAppService.GetVersionsAsync(Project.ShortName); + var versions = output.Items + .Select(v => new VersionInfoViewModel(v.DisplayName, v.Name)) + .ToList(); - private async Task SetVersionAsync(ProjectDto project) - { - var versionInfoDtos = await _documentAppService.GetVersions(project.ShortName); - - Versions = versionInfoDtos.Select(v => new VersionInfo(v.DisplayName, v.Name)).ToList(); - - LatestVersionInfo = GetLatestVersion(); - - if (string.Equals(Version, DocsAppConsts.Latest, StringComparison.OrdinalIgnoreCase)) - { - LatestVersionInfo.IsSelected = true; - Version = LatestVersionInfo.Version; - } - else + if (versions.Any()) { - var versionFromUrl = Versions.FirstOrDefault(v => v.Version == Version); - if (versionFromUrl != null) + LatestVersionInfo = versions.First(); + LatestVersionInfo.DisplayText = $"{LatestVersionInfo.DisplayText} ({DocsAppConsts.Latest})"; + LatestVersionInfo.Version = LatestVersionInfo.Version; + + if (string.Equals(Version, DocsAppConsts.Latest, StringComparison.OrdinalIgnoreCase)) { - versionFromUrl.IsSelected = true; - Version = versionFromUrl.Version; + LatestVersionInfo.IsSelected = true; + Version = LatestVersionInfo.Version; } else { - Versions.First().IsSelected = true; - Version = Versions.First().Version; + var versionFromUrl = versions.FirstOrDefault(v => v.Version == Version); + if (versionFromUrl != null) + { + versionFromUrl.IsSelected = true; + Version = versionFromUrl.Version; + } + else + { + versions.First().IsSelected = true; + Version = versions.First().Version; + } } } - VersionSelectItems = Versions.Select(v => new SelectListItem + VersionSelectItems = versions.Select(v => new SelectListItem { Text = v.DisplayText, Value = CreateLink(LatestVersionInfo, v.Version, DocumentName), @@ -129,9 +106,31 @@ namespace Volo.Docs.Pages.Documents.Project }).ToList(); } - public string CreateLink(VersionInfo latestVersion, string version, string documentName = null) + private async Task SetNavigationAsync() + { + try + { + var document = await _documentAppService.GetNavigationAsync( + new GetNavigationDocumentInput + { + ProjectId = Project.Id, + Version = Version + } + ); + + Navigation = ObjectMapper.Map(document); + } + catch (DocumentNotFoundException) //TODO: What if called on a remote service which may return 404 + { + return; + } + + Navigation.ConvertItems(); + } + + public string CreateLink(VersionInfoViewModel latestVersion, string version, string documentName = null) { - if (latestVersion.Version == version) + if (latestVersion == null || latestVersion.Version == version) { version = DocsAppConsts.Latest; } @@ -146,16 +145,6 @@ namespace Volo.Docs.Pages.Documents.Project return link; } - private VersionInfo GetLatestVersion() - { - var latestVersion = Versions.First(); - - latestVersion.DisplayText = $"{latestVersion.DisplayText} ({DocsAppConsts.Latest})"; - latestVersion.Version = latestVersion.Version; - - return latestVersion; - } - public string GetSpecificVersionOrLatest() { if (Document?.Version == null) @@ -170,32 +159,65 @@ namespace Volo.Docs.Pages.Documents.Project private async Task SetDocumentAsync() { + if (DocumentName.IsNullOrWhiteSpace()) + { + DocumentName = Project.DefaultDocumentName; + } + + DocumentNameWithExtension = DocumentName + "." + Project.Format; + try { if (DocumentNameWithExtension.IsNullOrWhiteSpace()) { - Document = await _documentAppService.GetDefaultAsync(ProjectName, Version, true); + Document = await _documentAppService.GetDefaultAsync( + new GetDefaultDocumentInput + { + ProjectId = Project.Id, + Version = Version + } + ); } else { - Document = await _documentAppService.GetByNameAsync(ProjectName, DocumentNameWithExtension, Version, true); + Document = await _documentAppService.GetAsync( + new GetDocumentInput + { + ProjectId = Project.Id, + Name = DocumentNameWithExtension, + Version = Version + } + ); } } catch (DocumentNotFoundException) { - return; + //TODO: Handle it! + throw; } - - var converter = _documentConverterFactory.Create(Document.Format ?? ProjectFormat); - var content = converter.NormalizeLinks(Document.Content, Document.Project.ShortName, GetSpecificVersionOrLatest(), Document.LocalDirectory); - content = converter.Convert(content); + ConvertDocumentContentToHtml(); + } - content = HtmlNormalizer.ReplaceImageSources(content, Document.RawRootUrl, Document.LocalDirectory); - content = HtmlNormalizer.ReplaceCodeBlocksLanguage(content, "language-C#", "language-csharp"); //todo find a way to make it on client in prismJS configuration (eg: map C# => csharp) + private void ConvertDocumentContentToHtml() + { + var converter = _documentToHtmlConverterFactory.Create(Document.Format ?? Project.Format); + var content = converter.Convert(Project, Document, GetSpecificVersionOrLatest()); + + content = HtmlNormalizer.ReplaceImageSources( + content, + Document.RawRootUrl, + Document.LocalDirectory + ); + + //todo find a way to make it on client in prismJS configuration (eg: map C# => csharp) + content = HtmlNormalizer.ReplaceCodeBlocksLanguage( + content, + "language-C#", + "language-csharp" + ); Document.Content = content; } - } } \ No newline at end of file diff --git a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.css similarity index 56% rename from modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.css rename to modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.css index 99943aa0a6..a2f7903f73 100644 --- a/modules/docs/app/Volo.DocsTestApp/wwwroot/libs/bootstrap-toc/bootstrap-toc.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.css @@ -1,5 +1,5 @@ -/*! - * Bootstrap Table of Contents v1.0.0 (http://afeld.github.io/bootstrap-toc/) +/*! + * Bootstrap Table of Contents v<%= version %> (http://afeld.github.io/bootstrap-toc/) * Copyright 2015 Aidan Feldman * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ @@ -7,54 +7,54 @@ /* All levels of nav */ nav[data-toggle='toc'] .nav > li > a { - display: block; - padding: 4px 20px; - font-size: 13px; - font-weight: 500; - color: #767676; + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; } nav[data-toggle='toc'] .nav > li > a:hover, nav[data-toggle='toc'] .nav > li > a:focus { - padding-left: 19px; - color: #563d7c; - text-decoration: none; - background-color: transparent; - border-left: 1px solid #563d7c; + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; } nav[data-toggle='toc'] .nav-link.active, nav[data-toggle='toc'] .nav-link.active:hover, nav[data-toggle='toc'] .nav-link.active:focus { - padding-left: 18px; - font-weight: bold; - color: #563d7c; - background-color: transparent; - border-left: 2px solid #563d7c; + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; } /* Nav: second level (shown on .active) */ nav[data-toggle='toc'] .nav-link + ul { - display: none; /* Hide by default, but at >768px, show it */ - padding-bottom: 10px; + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; } nav[data-toggle='toc'] .nav .nav > li > a { - padding-top: 1px; - padding-bottom: 1px; - padding-left: 30px; - font-size: 12px; - font-weight: normal; + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; } nav[data-toggle='toc'] .nav .nav > li > a:hover, nav[data-toggle='toc'] .nav .nav > li > a:focus { - padding-left: 29px; + padding-left: 29px; } nav[data-toggle='toc'] .nav .nav > li > .active, nav[data-toggle='toc'] .nav .nav > li > .active:hover, nav[data-toggle='toc'] .nav .nav > li > .active:focus { - padding-left: 28px; - font-weight: 500; + padding-left: 28px; + font-weight: 500; } nav[data-toggle='toc'] .nav-link.active + ul { - display: block; -} + display: block; +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.js new file mode 100644 index 0000000000..3b92bf5e7e --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v1.0.0 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function ($) { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function ($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function (el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function (el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function (el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function () { + return $(''); + }, + + createChildNavList: function ($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function (anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function (headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function ($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function ($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function (el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function ($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function (i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function (arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function (opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function () { + $('nav[data-toggle="toc"]').each(function (i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(jQuery); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.less b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.less new file mode 100644 index 0000000000..d819f85ccc --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.less @@ -0,0 +1,110 @@ +@color_1: #767676; +@color_2: #563d7c; +@background_color_1: transparent; + +/*! + * Bootstrap Table of Contents v<%= version %> (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ +/* All levels of nav */ +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] { + .nav { + > li { + > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: @color_1; + + &:hover { + padding-left: 19px; + color: @color_2; + text-decoration: none; + background-color: @background_color_1; + border-left: 1px solid #563d7c; + } + + &:focus { + padding-left: 19px; + color: @color_2; + text-decoration: none; + background-color: @background_color_1; + border-left: 1px solid #563d7c; + } + } + } + + .nav { + > li { + > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; + + &:hover { + padding-left: 29px; + } + + &:focus { + padding-left: 29px; + } + } + + > .active { + padding-left: 28px; + font-weight: 500; + + &:hover { + padding-left: 28px; + font-weight: 500; + } + + &:focus { + padding-left: 28px; + font-weight: 500; + } + } + } + } + } + + .nav-link.active { + padding-left: 18px; + font-weight: bold; + color: @color_2; + background-color: @background_color_1; + border-left: 2px solid #563d7c; + + &:hover { + padding-left: 18px; + font-weight: bold; + color: @color_2; + background-color: @background_color_1; + border-left: 2px solid #563d7c; + } + + &:focus { + padding-left: 18px; + font-weight: bold; + color: @color_2; + background-color: @background_color_1; + border-left: 2px solid #563d7c; + } + + & + ul { + display: block; + } + } + + .nav-link { + & + ul { + display: none; + padding-bottom: 10px; + } + } +} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.min.css new file mode 100644 index 0000000000..e01dffc122 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/bootstrap-toc.min.css @@ -0,0 +1 @@ +nav[data-toggle=toc] .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{padding-left:19px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}nav[data-toggle=toc] .nav-link.active,nav[data-toggle=toc] .nav-link.active:focus,nav[data-toggle=toc] .nav-link.active:hover{padding-left:18px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}nav[data-toggle=toc] .nav-link+ul{display:none;padding-bottom:10px}nav[data-toggle=toc] .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{padding-left:29px}nav[data-toggle=toc] .nav .nav>li>.active,nav[data-toggle=toc] .nav .nav>li>.active:focus,nav[data-toggle=toc] .nav .nav>li>.active:hover{padding-left:28px;font-weight:500}nav[data-toggle=toc] .nav-link.active+ul{display:block} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 7ef3529ad1..0ac501cc94 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -82,4 +82,5 @@ initAnchorTags(".docs-page .docs-body"); }); -})(jQuery); \ No newline at end of file +})(jQuery); + diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js new file mode 100644 index 0000000000..5eb102473f --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Scripts/vs.js @@ -0,0 +1,98 @@ +(function ($) { + $(function () { + $('li:not(.last-link) a.tree-toggle').click(function () { + $(this).parent().children('ul.tree').toggle(100); + $(this).closest("li").toggleClass("selected-tree"); + }); + $('li:not(.last-link) span.plus-icon i.fa-chevron-right').click(function () { + + var $element = $(this).parent(); + + $element.parent().children('ul.tree').toggle(100); + $element.closest("li").toggleClass("selected-tree"); + }); + + var scrollTopBtn = $(".scroll-top-btn"); + var enoughHeight = $(".docs-sidebar-wrapper > .docs-top").height() + 60; + + $(window).scroll(function () { + var topPos = $(window).scrollTop(); + if (topPos > enoughHeight) { + $(scrollTopBtn).addClass("showup"); + $("body").addClass("scrolled"); + } else { + $(scrollTopBtn).removeClass("showup"); + $("body").removeClass("scrolled"); + } + }); + + $(scrollTopBtn).click(function () { + $('html, body').animate({ + scrollTop: 0 + }, 500); + return false; + }); + + var navSelector = '#docs-sticky-index'; + var $myNav = $(navSelector); + Toc.init($myNav); + $('body').scrollspy({ + target: $myNav + }); + $("#docs-sticky-index a").on('click', function (event) { + if (this.hash !== "") { + event.preventDefault(); + var hash = this.hash; + $('html, body').animate({ + scrollTop: $(hash).offset().top + }, 500, function () { + window.location.hash = hash; + }); + } + }); + + $('.btn-toggle').on("click", function () { + $(".toggle-row").slideToggle(400); + $(this).toggleClass("less"); + }); + + $('.close-mmenu').on("click", function () { + $(".navbar-collapse").removeClass("show"); + }); + + $('.open-dmenu').on("click", function () { + $(".docs-tree-list").slideToggle(); + }); + + $(window).on("load", function () { + $("#sidebar-scroll").mCustomScrollbar({ + theme: "minimal" + }); + }); + + $(window).on("load", function () { + $("#scroll-index").mCustomScrollbar({ + theme: "minimal-dark" + }); + }); + }); + + window.Toc.helpers.createNavList = function () { + return $(''); + }; + + window.Toc.helpers.createChildNavList = function ($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }; + + window.Toc.helpers.generateNavEl = function (anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $(''); + $li.append($a); + return $li; + }; +})(jQuery); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css similarity index 97% rename from modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.css rename to modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css index 5573b0147e..d41426ff3a 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.css @@ -473,27 +473,11 @@ div.code-toolbar > .toolbar a { border-radius: .25rem; color: #fff !important; margin-left: -1rem; } - .jumbotron .btn, footer .btn { - display: block; - margin-bottom: 10px; } - .multi-tenancy { - text-align: center !important; } .section-with-logos img { margin: 15px; opacity: 1; -webkit-filter: grayscale(0%); filter: grayscale(0%); } - .jumbotron { - padding-top: 160px; - margin-top: -160px; - border-radius: 0; - padding-bottom: 40px; - margin-bottom: 0; - font-size: .85em; - padding-left: 45px; - padding-right: 45px; } - .jumbotron .jumbotron-logo { - display: none; } span.code-arrow { padding: 0px 0 0px; display: block; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css similarity index 96% rename from modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.min.css rename to modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css index 7d9af3836e..24185d8161 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.min.css +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.min.css @@ -1 +1 @@ -body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:2rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}.jumbotron .jumbotron-logo{display:none;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file +body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:2rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;}@media(max-width:767px){body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;}} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.scss b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss similarity index 92% rename from modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.scss rename to modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss index ecb140ec1e..19ba230906 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.scss +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Shared/Styles/vs.scss @@ -1,6 +1,7 @@ body { position: relative; } + .docs-page { background: rgb(245, 247, 249); @@ -679,7 +680,7 @@ body { } } } - + .for-mobile { display: none; @@ -688,7 +689,7 @@ body { .for-desktop { display: inline-block; } - + pre[class*="language-"] { padding: 1.4em 2em !important; margin: 15px 0 25px !important; @@ -703,6 +704,7 @@ code { border-radius: 3px; color: #28a745; } + pre { code { padding: 0; @@ -716,6 +718,7 @@ pre { color: #d69d85; } } + :not(pre) > code[class*="language-"], pre[class*="language-"] { background: #191919 !important; } @@ -727,4 +730,82 @@ div.code-toolbar > .toolbar span { div.code-toolbar > .toolbar a { cursor: copy; +} + +@media (max-width: 767px) { + body { + font-size: 14px; + } + + .for-mobile { + display: inline-block; + } + + .for-desktop { + display: none; + } + + .close-mmenu, .close-dmenu { + position: absolute; + top: -78px; + left: 25px; + color: #fff; + font-size: 68px; + background: #fff; + opacity: 0; + } + + .navbar { + padding: .5rem 1.75rem; + + .navbar-collapse { + background: rgb(56, 0, 61); + position: fixed; + top: 86px; + left: 0; + width: 100%; + height: 100vh; + height: calc(100vh - 86px); + z-index: 100 !important; + + .navbar-nav { + height: 100vh; + padding: 20px 30px; + overflow: auto; + + .nav-link { + padding: 1.2rem !important; + } + } + } + + .navbar-toggler { + padding: .5rem .75rem; + font-size: 1.5rem; + line-height: 1; + background-color: transparent; + border: 0; + border-radius: .25rem; + color: #fff !important; + margin-left: -1rem; + } + } + + .section-with-logos img { + margin: 15px; + opacity: 1; + -webkit-filter: grayscale(0%); + filter: grayscale(0%); + } + + span.code-arrow { + padding: 0px 0 0px; + display: block; + transform: rotate(90deg); + font-size: 2em; + } + + .mb-5, .my-5 { + margin-bottom: 2rem !important; + } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.css deleted file mode 100644 index 7f4a05c75d..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.css +++ /dev/null @@ -1,433 +0,0 @@ -body { - position: relative; } - -.docs-page { - background: #f5f7f9; } - .docs-page .anchorjs-link { - transition: all .25s linear; } - .docs-page *:hover > .anchorjs-link { - margin-left: -1.125em !important; - transition: color .25s linear; - color: gray; } - .docs-page .anchorjs-link:hover { - color: #007bff; - text-decoration: none; } - .docs-page .docs-sidebar { - background: #f5f7f9; - padding-right: 1rem; - position: relative; - top: 0px; - left: 0; - position: fixed; } - .docs-page .docs-sidebar .docs-sidebar-wrapper { - width: 270px; - float: right; } - .docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control { - background: none; - padding-left: 36px; - width: 100%; - background: #e9ecef; - border: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus, .docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active, .docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover, .docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited { - box-shadow: none; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version { - position: relative; - padding: 0 1rem; - margin: .5rem 0 1rem; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select { - border-radius: 8px; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text { - border: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control { - line-height: 1; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - padding: .3em .5em .5em; - border: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus, .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active, .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover, .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited { - box-shadow: none; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter { - position: relative; - padding: 0 1rem; - margin: .5rem 0; - font-size: .9em; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon { - position: absolute; - top: 0px; - padding: 8px 10px; - line-height: 1; - left: 16px; - background: none; - padding: 0.375rem 0.75rem; - font-size: 1rem; - line-height: 1.5; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa { - color: #ddd; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list { - height: 100vh; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list > ul { - display: block; - height: calc(100vh - 210px); } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul { - font-size: .935em; - list-style: none; - padding: 0 1rem; - margin: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li { - margin-left: 0px; - padding-left: 24px; - display: block; - width: 100%; - position: relative; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a { - color: #999; - font-weight: 700; - padding: 7px 0; - display: block; - border-bottom: 1px solid #eeeff3; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover { - color: #000; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link { - top: 11px; - color: #aaa; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle { - color: #999; - padding: 7px 0; - display: block; - border-bottom: 1px solid #eeeff3; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon { - font-size: .85em; - transition: .3s; - width: 18px; - height: 18px; - text-align: center; - padding: 0; - line-height: 1; - border-radius: 50%; - margin-right: 4px; - position: absolute; - left: 2px; - top: 11px; - color: #aaa; - cursor: default; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link { - color: #555; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right { - cursor: pointer; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul { - padding: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a { - font-weight: 400; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul { - padding: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a { - font-weight: 300; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree > a { - color: #000; - transition: .4s; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree > span .fa { - transform: rotate(90deg); - color: #007bff; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link > span .fa { - transform: rotate(0deg); } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand { - font-size: 1.5rem; - color: #000; - font-weight: 700; - padding: 20px 0 10px; - line-height: 1; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong { - font-weight: 300; - text-transform: uppercase; - font-size: .9rem; - opacity: .6; } - .docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site { - color: #000; - opacity: .15; - transition: .4s; - font-size: .75rem; - font-weight: 300; } - .docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover { - text-decoration: none; - opacity: .5; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc { - font-size: .85em; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong { - display: block; } - .docs-page .docs-content .docs-link-btns { - border-bottom: 1px solid #f4f5f7; - background: #fdfdfd; - padding: 10px 20px; - margin: 0 -15px; - text-align: right; - font-size: .8em; } - .docs-page .docs-content .docs-link-btns a { - color: #999; } - .docs-page .docs-content .docs-link-btns a:hover { - color: #444; - text-decoration: none; } - .docs-page .docs-content .docs-text-field { - padding: 2rem; } - .docs-page .docs-content article.docs-body h1 { - padding-top: 2rem; - font-size: 2.25rem; - padding-bottom: 10px; } - .docs-page .docs-content article.docs-body h2 { - padding-top: 2rem; - padding-bottom: 10px; - font-size: 2rem; } - .docs-page .docs-content article.docs-body h3, .docs-page .docs-content article.docs-body h4, .docs-page .docs-content article.docs-body h5, .docs-page .docs-content article.docs-body h6 { - padding-top: 20px; - padding-bottom: 5px; - font-size: 1.5rem; } - .docs-page .docs-content article.docs-body h1, .docs-page .docs-content article.docs-body h2, .docs-page .docs-content article.docs-body h3, .docs-page .docs-content article.docs-body h4, .docs-page .docs-content article.docs-body h5, .docs-page .docs-content article.docs-body h6 { - position: relative; } - .docs-page .docs-content article.docs-body h1 .anchor, .docs-page .docs-content article.docs-body h2 .anchor, .docs-page .docs-content article.docs-body h3 .anchor, .docs-page .docs-content article.docs-body h4 .anchor, .docs-page .docs-content article.docs-body h5 .anchor, .docs-page .docs-content article.docs-body h6 .anchor { - position: absolute; - right: -26px; - font-size: 18px; - bottom: 5px; - color: #999; - opacity: 0; - transition: .5s; } - .docs-page .docs-content article.docs-body h1:hover .anchor, .docs-page .docs-content article.docs-body h2:hover .anchor, .docs-page .docs-content article.docs-body h3:hover .anchor, .docs-page .docs-content article.docs-body h4:hover .anchor, .docs-page .docs-content article.docs-body h5:hover .anchor, .docs-page .docs-content article.docs-body h6:hover .anchor { - opacity: 1; } - .docs-page .docs-content article.docs-body img { - max-width: 100%; - border: 1px solid #f4f5f7; - margin: 15px 0 25px; - box-shadow: 0 0 45px #f8f9fa; - border-radius: 6px; } - .docs-page .docs-page-index { - min-height: 100vh; } - .docs-page .docs-page-index #scroll-index { - max-height: 100vh; } - .docs-page .docs-page-index .docs-inner-anchors { - position: fixed; - top: 0px; - /* max-width: 270px; */ - padding: 10px; - font-size: .90em; - /* height: 100vh; */ } - .docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills { - font-size: .92em; - margin-left: 15px; - border-left: 1px solid #eee; } - .docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link { - padding: 3px 14px 4px; - color: #aaa; - line-height: 1.2; - position: relative; - border-left: 1px solid #eee; - border-radius: 0; - margin-left: -1px; - margin-top: 1px; - margin-bottom: 1px; - transition: .2s; } - .docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active { - border-left: 2px solid #007bff; - background: none; - color: #007bff; } - .docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active { - color: #007bff; } - .docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active { - color: #007bff; } - .docs-page .docs-page-index .docs-inner-anchors .index-scroll { - margin-left: -30px; } - .docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper { - max-width: 300px; - float: left; } - .docs-page .docs-page-index .scroll-top-btn { - display: none; - font-size: .85em; - color: #aaa; - text-decoration: none; - padding-left: 18px; } - .docs-page .docs-page-index .scroll-top-btn.showup { - display: block; } - -@media (min-width: 1100px) { - .container { - max-width: 1080px; } - .docs-page .docs-sidebar.dark-sidebar { - background: #191919; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control { - background: #333; - border-color: #333; - color: #999; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label { - background: #444; - border-color: #444; - color: #ddd; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control { - background: #333; - color: #999; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select { - border: 0; - border-radius: 6px; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa { - color: #aaa; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a { - color: #aaa; - border-bottom: 1px solid #333; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover { - color: #fff; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon { - font-size: .85em; - transition: .3s; - width: 18px; - height: 18px; - text-align: center; - padding: 0; - line-height: 1; - border-radius: 50%; - margin-right: 4px; - position: absolute; - left: 2px; - top: 11px; - color: #aaa; - cursor: default; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link { - color: #555; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right { - cursor: pointer; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link { - top: 11px; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle { - color: #555; - padding: 7px 0; - display: block; - border-bottom: 1px solid #333; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree > a { - color: #fff; - transition: .4s; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree > a span .fa { - color: #fff; } - .docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree > a span:not(.last-link) .fa { - transform: rotate(90deg); - color: #fff; } - .docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand { - color: #fff; - text-transform: uppercase; } - .docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site { - color: #fff; } - .docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc { - color: #ddd; } } - -@media (min-width: 1366px) { - .container { - max-width: 1340px; } } - -@media (min-width: 1440px) { - .container { - max-width: 1400px; } } - -@media (max-width: 767px) { - .docs-page .docs-content article.docs-body h1 { - padding-top: 1.5rem; } - .docs-page { - background: #f5f7f9; } - .docs-page > .container-fluid { - display: block; } - .docs-page > .container-fluid > .row { - display: block; } - .docs-page .docs-sidebar { - position: fixed; - max-width: 100%; - width: 100%; - display: block; - padding: 0 !important; - top: 0; - left: 0; - z-index: 100; - right: 0; } - .docs-page .docs-sidebar .docs-sidebar-wrapper { - max-width: 100%; - width: 100%; - top: 0px; - position: relative; - margin: 0 !important; - height: 72px; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list { - padding: .5rem 1.5rem 2rem 1.5rem; - position: fixed; - top: 70px; - font-size: 17px; - left: 0; - width: 100%; - z-index: 100; - background: #f5f7f9; - display: none; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter { - position: relative; - padding: 0 0 1rem !important; } - .docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon { - left: 0px; } - .docs-page .docs-sidebar .docs-top .navbar-logo { - padding: 0rem; - padding-top: .3rem; - display: block; - text-align: center; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand { - font-size: 1.5rem; - font-weight: 700; - display: block; - margin-right: 0em; - padding: 7px 0 10px; - text-transform: uppercase; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo { - width: 110px; } - .docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site { - display: none; } - .docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc { - font-size: 1em; - display: none; } - .docs-page .docs-sidebar .docs-top .open-dmenu { - position: absolute; - top: 10px; - left: 20px; } - .docs-page .docs-content { - padding-top: 72px; - max-width: 100%; - display: block !important; } - .docs-page .docs-content .docs-text-field { - padding: 1rem 1.5rem; } - .docs-page .docs-page-index { - display: none; } } - -.for-mobile { - display: none; } - -.for-desktop { - display: inline-block; } - -pre[class*="language-"] { - padding: 1.4em 2em !important; - margin: 15px 0 25px !important; - border-radius: 6px; } - -code { - padding: 0.2em 0.4em; - margin: 0; - font-size: 82%; - background-color: #f0f1f3; - border-radius: 3px; - color: #28a745; } - -pre code { - padding: 0; } - -pre .token.keyword { - color: #569cd6; } - -pre .token.atrule, pre .token.attr-value, pre .token.function, pre .token.class-name { - color: #d69d85; } - -:not(pre) > code[class*="language-"], pre[class*="language-"] { - background: #191919 !important; } - -div.code-toolbar > .toolbar span { - cursor: default; } - -div.code-toolbar > .toolbar a { - cursor: copy; } diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.min.css deleted file mode 100644 index d45859a5eb..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_docs.min.css +++ /dev/null @@ -1 +0,0 @@ -body{position:relative;}.docs-page{background:#f5f7f9;}.docs-page .anchorjs-link{transition:all .25s linear;}.docs-page *:hover>.anchorjs-link{margin-left:-1.125em !important;transition:color .25s linear;color:#808080;}.docs-page .anchorjs-link:hover{color:#007bff;text-decoration:none;}.docs-page .docs-sidebar{background:#f5f7f9;padding-right:1rem;position:relative;top:0;left:0;position:fixed;}.docs-page .docs-sidebar .docs-sidebar-wrapper{width:270px;float:right;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control{background:none;padding-left:36px;width:100%;background:#e9ecef;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper input.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version{position:relative;padding:0 1rem;margin:.5rem 0 1rem;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select{border-radius:8px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select .input-group-text{border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{line-height:1;border-top-left-radius:0;border-bottom-left-radius:0;padding:.3em .5em .5em;border:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:focus,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:active,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:hover,.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control:visited{box-shadow:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter{position:relative;padding:0 1rem;margin:.5rem 0;font-size:.9em;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon{position:absolute;top:0;padding:8px 10px;line-height:1;left:16px;background:none;padding:.375rem .75rem;font-size:1rem;line-height:1.5;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#ddd;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{height:100vh;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list>ul{display:block;height:calc(100vh - 210px);}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul{font-size:.935em;list-style:none;padding:0 1rem;margin:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li{margin-left:0;padding-left:24px;display:block;width:100%;position:relative;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#999;font-weight:700;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#000;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a.last-link{top:11px;color:#aaa;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#999;padding:7px 0;display:block;border-bottom:1px solid #eeeff3;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li a{font-weight:400;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul{padding:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li ul li ul li a{font-weight:300;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#000;transition:.4s;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>span .fa{transform:rotate(90deg);color:#007bff;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree.last-link>span .fa{transform:rotate(0deg);}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;color:#000;font-weight:700;padding:20px 0 10px;line-height:1;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand strong{font-weight:300;text-transform:uppercase;font-size:.9rem;opacity:.6;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{color:#000;opacity:.15;transition:.4s;font-size:.75rem;font-weight:300;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site:hover{text-decoration:none;opacity:.5;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:.85em;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc strong{display:block;}.docs-page .docs-content .docs-link-btns{border-bottom:1px solid #f4f5f7;background:#fdfdfd;padding:10px 20px;margin:0 -15px;text-align:right;font-size:.8em;}.docs-page .docs-content .docs-link-btns a{color:#999;}.docs-page .docs-content .docs-link-btns a:hover{color:#444;text-decoration:none;}.docs-page .docs-content .docs-text-field{padding:2rem;}.docs-page .docs-content article.docs-body h1{padding-top:2rem;font-size:2.25rem;padding-bottom:10px;}.docs-page .docs-content article.docs-body h2{padding-top:2rem;padding-bottom:10px;font-size:2rem;}.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{padding-top:20px;padding-bottom:5px;font-size:1.5rem;}.docs-page .docs-content article.docs-body h1,.docs-page .docs-content article.docs-body h2,.docs-page .docs-content article.docs-body h3,.docs-page .docs-content article.docs-body h4,.docs-page .docs-content article.docs-body h5,.docs-page .docs-content article.docs-body h6{position:relative;}.docs-page .docs-content article.docs-body h1 .anchor,.docs-page .docs-content article.docs-body h2 .anchor,.docs-page .docs-content article.docs-body h3 .anchor,.docs-page .docs-content article.docs-body h4 .anchor,.docs-page .docs-content article.docs-body h5 .anchor,.docs-page .docs-content article.docs-body h6 .anchor{position:absolute;right:-26px;font-size:18px;bottom:5px;color:#999;opacity:0;transition:.5s;}.docs-page .docs-content article.docs-body h1:hover .anchor,.docs-page .docs-content article.docs-body h2:hover .anchor,.docs-page .docs-content article.docs-body h3:hover .anchor,.docs-page .docs-content article.docs-body h4:hover .anchor,.docs-page .docs-content article.docs-body h5:hover .anchor,.docs-page .docs-content article.docs-body h6:hover .anchor{opacity:1;}.docs-page .docs-content article.docs-body img{max-width:100%;border:1px solid #f4f5f7;margin:15px 0 25px;box-shadow:0 0 45px #f8f9fa;border-radius:6px;}.docs-page .docs-page-index{min-height:100vh;}.docs-page .docs-page-index #scroll-index{max-height:100vh;}.docs-page .docs-page-index .docs-inner-anchors{position:fixed;top:0;padding:10px;font-size:.9em;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills{font-size:.92em;margin-left:15px;border-left:1px solid #eee;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link{padding:3px 14px 4px;color:#aaa;line-height:1.2;position:relative;border-left:1px solid #eee;border-radius:0;margin-left:-1px;margin-top:1px;margin-bottom:1px;transition:.2s;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-link.active{border-left:2px solid #007bff;background:none;color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .navbar .nav-pills .nav-pills .nav-pills .nav-link.active{color:#007bff;}.docs-page .docs-page-index .docs-inner-anchors .index-scroll{margin-left:-30px;}.docs-page .docs-page-index .docs-inner-anchors .docs-anchors-wrapper{max-width:300px;float:left;}.docs-page .docs-page-index .scroll-top-btn{display:none;font-size:.85em;color:#aaa;text-decoration:none;padding-left:18px;}.docs-page .docs-page-index .scroll-top-btn.showup{display:block;}@media(min-width:1100px){.container{max-width:1080px;}.docs-page .docs-sidebar.dark-sidebar{background:#191919;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select select.form-control{background:#333;border-color:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-version .version-select label{background:#444;border-color:#444;color:#ddd;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .form-control{background:#333;color:#999;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter select{border:0;border-radius:6px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-filter .filter-icon i.fa{color:#aaa;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a{color:#aaa;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a:hover{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon{font-size:.85em;transition:.3s;width:18px;height:18px;text-align:center;padding:0;line-height:1;border-radius:50%;margin-right:4px;position:absolute;left:2px;top:11px;color:#aaa;cursor:default;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-long-arrow-right.no-link{color:#555;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon .fa-chevron-right{cursor:pointer;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li a .plus-icon.last-link{top:11px;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li span.tree-toggle{color:#555;padding:7px 0;display:block;border-bottom:1px solid #333;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a{color:#fff;transition:.4s;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span .fa{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-sidebar-wrapper .docs-tree-list ul li.selected-tree>a span:not(.last-link) .fa{transform:rotate(90deg);color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-brand{color:#fff;text-transform:uppercase;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .go-back-site{color:#fff;}.docs-page .docs-sidebar.dark-sidebar .docs-top .navbar-logo .navbar-logo-desc{color:#ddd;}}@media(min-width:1366px){.container{max-width:1340px;}}@media(min-width:1440px){.container{max-width:1400px;}}@media(max-width:767px){.docs-page .docs-content article.docs-body h1{padding-top:1.5rem;}.docs-page{background:#f5f7f9;}.docs-page>.container-fluid{display:block;}.docs-page>.container-fluid>.row{display:block;}.docs-page .docs-sidebar{position:fixed;max-width:100%;width:100%;display:block;padding:0 !important;top:0;left:0;z-index:100;right:0;}.docs-page .docs-sidebar .docs-sidebar-wrapper{max-width:100%;width:100%;top:0;position:relative;margin:0 !important;height:72px;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list{padding:.5rem 1.5rem 2rem 1.5rem;position:fixed;top:70px;font-size:17px;left:0;width:100%;z-index:100;background:#f5f7f9;display:none;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter{position:relative;padding:0 0 1rem !important;}.docs-page .docs-sidebar .docs-sidebar-wrapper .docs-tree-list .docs-filter .filter-icon{left:0;}.docs-page .docs-sidebar .docs-top .navbar-logo{padding:0;padding-top:.3rem;display:block;text-align:center;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand{font-size:1.5rem;font-weight:700;display:block;margin-right:0;padding:7px 0 10px;text-transform:uppercase;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-brand .docs-logo{width:110px;}.docs-page .docs-sidebar .docs-top .navbar-logo .go-back-site{display:none;}.docs-page .docs-sidebar .docs-top .navbar-logo .navbar-logo-desc{font-size:1em;display:none;}.docs-page .docs-sidebar .docs-top .open-dmenu{position:absolute;top:10px;left:20px;}.docs-page .docs-content{padding-top:72px;max-width:100%;display:block !important;}.docs-page .docs-content .docs-text-field{padding:1rem 1.5rem;}.docs-page .docs-page-index{display:none;}}.for-mobile{display:none;}.for-desktop{display:inline-block;}pre[class*="language-"]{padding:1.4em 2em !important;margin:15px 0 25px !important;border-radius:6px;}code{padding:.2em .4em;margin:0;font-size:82%;background-color:#f0f1f3;border-radius:3px;color:#28a745;}pre code{padding:0;}pre .token.keyword{color:#569cd6;}pre .token.atrule,pre .token.attr-value,pre .token.function,pre .token.class-name{color:#d69d85;}:not(pre)>code[class*="language-"],pre[class*="language-"]{background:#191919 !important;}div.code-toolbar>.toolbar span{cursor:default;}div.code-toolbar>.toolbar a{cursor:copy;} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.css deleted file mode 100644 index ea46f1f37f..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.css +++ /dev/null @@ -1,79 +0,0 @@ -body { - font-size: 14px; } - -.for-mobile { - display: inline-block; } - -.for-desktop { - display: none; } - -.close-mmenu, .close-dmenu { - position: absolute; - top: -78px; - left: 25px; - color: #fff; - font-size: 68px; - background: #fff; - opacity: 0; } - -.navbar { - padding: .5rem 1.75rem; } - .navbar .navbar-collapse { - background: #38003d; - position: fixed; - top: 86px; - left: 0; - width: 100%; - height: 100vh; - height: calc(100vh - 86px); - z-index: 100 !important; } - .navbar .navbar-collapse .navbar-nav { - height: 100vh; - padding: 20px 30px; - overflow: auto; } - .navbar .navbar-collapse .navbar-nav .nav-link { - padding: 1.2rem !important; } - .navbar .navbar-toggler { - padding: .5rem .75rem; - font-size: 1.5rem; - line-height: 1; - background-color: transparent; - border: 0; - border-radius: .25rem; - color: #fff !important; - margin-left: -1rem; } - -.jumbotron .btn, footer .btn { - display: block; - margin-bottom: 10px; } - -.multi-tenancy { - text-align: center !important; } - -.section-with-logos img { - margin: 15px; - opacity: 1; - -webkit-filter: grayscale(0%); - filter: grayscale(0%); } - -.jumbotron { - padding-top: 160px; - margin-top: -160px; - border-radius: 0; - padding-bottom: 40px; - margin-bottom: 0; - font-size: .85em; - padding-left: 45px; - padding-right: 45px; } - .jumbotron .jumbotron-logo { - display: none; } - -span.code-arrow { - padding: 0px 0 0px; - display: block; - transform: rotate(90deg); - font-size: 2em; } - -.mb-5, .my-5 { - margin-bottom: 2rem !important; } - diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.min.css b/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.min.css deleted file mode 100644 index f990e0d7f0..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.min.css +++ /dev/null @@ -1 +0,0 @@ -body{font-size:14px;}.for-mobile{display:inline-block;}.for-desktop{display:none;}.close-mmenu,.close-dmenu{position:absolute;top:-78px;left:25px;color:#fff;font-size:68px;background:#fff;opacity:0;}.navbar{padding:.5rem 1.75rem;}.navbar .navbar-collapse{background:#38003d;position:fixed;top:86px;left:0;width:100%;height:100vh;height:calc(100vh - 86px);z-index:100 !important;}.navbar .navbar-collapse .navbar-nav{height:100vh;padding:20px 30px;overflow:auto;}.navbar .navbar-collapse .navbar-nav .nav-link{padding:1.2rem !important;}.navbar .navbar-toggler{padding:.5rem .75rem;font-size:1.5rem;line-height:1;background-color:transparent;border:0;border-radius:.25rem;color:#fff !important;margin-left:-1rem;}.jumbotron .btn,footer .btn{display:block;margin-bottom:10px;}.multi-tenancy{text-align:center !important;}.section-with-logos img{margin:15px;opacity:1;-webkit-filter:grayscale(0%);filter:grayscale(0%);}.jumbotron{padding-top:160px;margin-top:-160px;border-radius:0;padding-bottom:40px;margin-bottom:0;font-size:.85em;padding-left:45px;padding-right:45px;}.jumbotron .jumbotron-logo{display:none;}span.code-arrow{padding:0 0 0;display:block;transform:rotate(90deg);font-size:2em;}.mb-5,.my-5{margin-bottom:2rem !important;} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.scss b/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.scss deleted file mode 100644 index 1dbc28608c..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/_responsive.scss +++ /dev/null @@ -1,91 +0,0 @@ - body { - font-size: 14px; - } -.for-mobile { - display: inline-block; -} -.for-desktop { - display: none; -} - -.close-mmenu, .close-dmenu { - position: absolute; - top: -78px; - left: 25px; - color: #fff; - font-size: 68px; - background: #fff; - opacity: 0; -} -.navbar { - padding: .5rem 1.75rem; - .navbar-collapse { - background: rgb(56, 0, 61); - position: fixed; - top: 86px; - left: 0; - width: 100%; - height: 100vh; - height: calc(100vh - 86px); - z-index: 100 !important; - .navbar-nav { - height: 100vh; - padding: 20px 30px; - overflow: auto; - .nav-link { - padding: 1.2rem !important; - } - } - } - - .navbar-toggler { - padding: .5rem .75rem; - font-size: 1.5rem; - line-height: 1; - background-color: transparent; - border: 0; - border-radius: .25rem; - color:#fff!important; - margin-left: -1rem; - } -} -.jumbotron, footer { - .btn { - display: block; - margin-bottom: 10px; - } -} -.multi-tenancy { - text-align: center !important; -} - -.section-with-logos img { - margin: 15px; - opacity: 1; - -webkit-filter: grayscale(0%); - filter: grayscale(0%); -} - -.jumbotron { - padding-top: 160px; - margin-top: -160px; - border-radius: 0; - padding-bottom: 40px; - margin-bottom: 0; - font-size: .85em; - - padding-left: 45px; - padding-right: 45px; - .jumbotron-logo { - display:none; - } -} -span.code-arrow { - padding: 0px 0 0px; - display: block; - transform: rotate(90deg); - font-size: 2em; -} -.mb-5, .my-5 { - margin-bottom: 2rem!important; -} diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.js deleted file mode 100644 index 3cbc901467..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.js +++ /dev/null @@ -1,122 +0,0 @@ -$('li:not(.last-link) a.tree-toggle').click(function () { - $(this).parent().children('ul.tree').toggle(100); - $(this).closest("li").toggleClass("selected-tree"); -}); -$('li:not(.last-link) span.plus-icon i.fa-chevron-right').click(function () { - - //var hasLink = $(this).parent().find("a").length > 0; - //if (!hasLink) { - // return; - //} - - ////if ($(this).find("i.fa-long-arrow-right").length > 0) { - //// return; - ////} - - var $element = $(this).parent(); - - $element.parent().children('ul.tree').toggle(100); - $element.closest("li").toggleClass("selected-tree"); -}); - -$(document).ready(function () { - var scrollTopBtn = $(".scroll-top-btn"); - var enoughHeight = $(".docs-sidebar-wrapper > .docs-top").height() + 60; - - $(window).scroll(function () { - var topPos = $(window).scrollTop(); - if (topPos > enoughHeight) { - $(scrollTopBtn).addClass("showup"); - $("body").addClass("scrolled"); - } else { - $(scrollTopBtn).removeClass("showup"); - $("body").removeClass("scrolled"); - } - }); - - $(scrollTopBtn).click(function () { - $('html, body').animate({ - scrollTop: 0 - }, 500); - return false; - }); - -}); - -$(document).ready(function () { - var navSelector = '#docs-sticky-index'; - var $myNav = $(navSelector); - Toc.init($myNav); - $('body').scrollspy({ - target: $myNav - }); - $("#docs-sticky-index a").on('click', function (event) { - if (this.hash !== "") { - event.preventDefault(); - var hash = this.hash; - $('html, body').animate({ - scrollTop: $(hash).offset().top - }, 500, function () { - window.location.hash = hash; - }); - } - }); -}); - - - -$('.btn-toggle').on("click", function () { - $(".toggle-row").slideToggle(400); - $(this).toggleClass("less"); -}); - -$('.close-mmenu').on("click", function () { - $(".navbar-collapse").removeClass("show"); -}); - -$('.open-dmenu').on("click", function () { - $(".docs-tree-list").slideToggle(); -}); - - -(function ($) { - - $(window).on("load", function () { - $("#sidebar-scroll").mCustomScrollbar({ - theme: "minimal" - }); - }); - - $(window).on("load", function () { - $("#scroll-index").mCustomScrollbar({ - theme: "minimal-dark" - }); - }); - - - - window.Toc.helpers.createNavList = function () { - return $(''); - }; - - window.Toc.helpers.createChildNavList = function ($parent) { - var $childList = this.createNavList(); - $parent.append($childList); - return $childList; - }; - - window.Toc.helpers.generateNavEl = function (anchor, text) { - var $a = $(''); - $a.attr('href', '#' + anchor); - $a.text(text); - var $li = $(''); - $li.append($a); - return $li; - }; - - -})(jQuery); - - - - diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.scss b/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.scss deleted file mode 100644 index 022a4d96bd..0000000000 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/vs.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import "_docs.scss"; -@media (max-width: 767px) { - @import "_responsive.scss"; - - -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj index a9d8487dff..5897dec291 100644 --- a/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj +++ b/modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.csproj @@ -40,6 +40,9 @@ + + + diff --git a/modules/docs/src/Volo.Docs.Web/compilerconfig.json b/modules/docs/src/Volo.Docs.Web/compilerconfig.json index 9812985b0c..3645b5a8f5 100644 --- a/modules/docs/src/Volo.Docs.Web/compilerconfig.json +++ b/modules/docs/src/Volo.Docs.Web/compilerconfig.json @@ -1,19 +1,7 @@ [ { - "outputFile": "wwwroot/pages/documents/project/index.css", - "inputFile": "wwwroot/pages/documents/project/index.less" - }, - { - "outputFile": "Pages/Documents/_docs.css", - "inputFile": "Pages/Documents/_docs.scss" - }, - { - "outputFile": "Pages/Documents/_responsive.css", - "inputFile": "Pages/Documents/_responsive.scss" - }, - { - "outputFile": "Pages/Documents/vs.css", - "inputFile": "Pages/Documents/vs.scss" + "outputFile": "Pages/Documents/Shared/Styles/vs.css", + "inputFile": "Pages/Documents/Shared/Styles/vs.scss" }, { "outputFile": "Pages/Documents/Project/index.css", diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/.bower.json b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/.bower.json deleted file mode 100644 index 3632626c5d..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/.bower.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "anchor-js", - "version": "4.1.0", - "authors": [ - "Bryan Braun" - ], - "description": "A Javascript utility for adding deep anchor links to online docs.", - "main": "anchor.js", - "license": "MIT", - "homepage": "https://github.com/bryanbraun/anchorjs", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests", - "package.json" - ], - "_release": "4.1.0", - "_resolution": { - "type": "version", - "tag": "4.1.0", - "commit": "848ef8ca7e8bbd5edb032b6c3623f05aefb5ef0b" - }, - "_source": "https://github.com/bryanbraun/anchorjs.git", - "_target": "^4.1.0", - "_originalSource": "anchor-js", - "_direct": true -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/README.md b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/README.md deleted file mode 100644 index 33da96e2f1..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# AnchorJS [![Build Status](https://img.shields.io/travis/bryanbraun/anchorjs/master.svg?style=flat)](https://travis-ci.org/bryanbraun/anchorjs) - -A JavaScript utility for adding deep anchor links ([like these](http://ux.stackexchange.com/q/36304/33248)) to existing page content. AnchorJS is lightweight, accessible, and has no dependencies. - -**[See Live Examples in the Documentation](http://bryanbraun.github.io/anchorjs#examples).** - -![Anchoring links](docs/img/anchoring-links.png) - -## Installation - -Download AnchorJS using npm, - -```bash -npm install anchor-js -``` - -or bower: - -```bash -bower install anchor-js --save-dev -``` - -(or just [download it from github](https://github.com/bryanbraun/anchorjs/releases)). - -Then include the anchor.js file (or anchor.min.js) in your webpage. - -```html - -``` - -You could also include it via a CDN like [CDNJS](https://cdnjs.com/libraries/anchor-js) or [jsDelivr](http://www.jsdelivr.com/projects/anchorjs). - -## Usage -See **[the Documentation](http://bryanbraun.github.io/anchorjs#basic-usage)** for detailed instructions. - -## Compatibility -Currently Supports: IE9+ and modern browsers - -## Contributing [![devDependency Status](https://img.shields.io/david/dev/bryanbraun/anchorjs.svg?style=flat)](https://david-dm.org/bryanbraun/anchorjs#info=devDependencies) -To contribute: - -1. Fork/Clone the repo. -2. Make your changes. -3. Write tests as needed. -4. Run tests locally to confirm everything is working: - - Install phantomjs: `brew install phantomjs` - - Install test modules: Run `npm install` - - Run all tests: `npm test` -5. Minify the code: `npm run release` -6. Submit a Pull Request. - -## License -Licensed with the [MIT License](http://opensource.org/licenses/MIT). diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.min.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.min.js deleted file mode 100644 index ee4e3b3f4d..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/anchor.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * AnchorJS - v4.1.0 - 2017-09-20 - * https://github.com/bryanbraun/anchorjs - * Copyright (c) 2017 Bryan Braun; Licensed MIT - */ -!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(this,function(){"use strict";return function(A){function e(A){A.icon=A.hasOwnProperty("icon")?A.icon:"",A.visible=A.hasOwnProperty("visible")?A.visible:"hover",A.placement=A.hasOwnProperty("placement")?A.placement:"right",A.ariaLabel=A.hasOwnProperty("ariaLabel")?A.ariaLabel:"Anchor",A.class=A.hasOwnProperty("class")?A.class:"",A.truncate=A.hasOwnProperty("truncate")?Math.floor(A.truncate):64}function t(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new Error("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}function i(){if(null===document.head.querySelector("style.anchorjs")){var A,e=document.createElement("style");e.className="anchorjs",e.appendChild(document.createTextNode("")),void 0===(A=document.head.querySelector('[rel="stylesheet"], style'))?document.head.appendChild(e):document.head.insertBefore(e,A),e.sheet.insertRule(" .anchorjs-link { opacity: 0; text-decoration: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }",e.sheet.cssRules.length),e.sheet.insertRule(" *:hover > .anchorjs-link, .anchorjs-link:focus { opacity: 1; }",e.sheet.cssRules.length),e.sheet.insertRule(" [data-anchorjs-icon]::after { content: attr(data-anchorjs-icon); }",e.sheet.cssRules.length),e.sheet.insertRule(' @font-face { font-family: "anchorjs-icons"; src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype"); }',e.sheet.cssRules.length)}}this.options=A||{},this.elements=[],e(this.options),this.isTouchDevice=function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)},this.add=function(A){var n,o,s,a,r,c,h,l,u,d,f,p=[];if(e(this.options),"touch"===(f=this.options.visible)&&(f=this.isTouchDevice()?"always":"hover"),A||(A="h2, h3, h4, h5, h6"),0===(n=t(A)).length)return this;for(i(),o=document.querySelectorAll("[id]"),s=[].map.call(o,function(A){return A.id}),r=0;r\]\.\/\(\)\*\\]/g;return this.options.truncate||e(this.options),A.trim().replace(/\'/gi,"").replace(t,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&(" "+A.firstChild.className+" ").indexOf(" anchorjs-link ")>-1,t=A.lastChild&&(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ")>-1;return e||t||!1}}}); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/banner.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/banner.js deleted file mode 100644 index 6bd551ef94..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/banner.js +++ /dev/null @@ -1,17 +0,0 @@ -const fs = require('fs'); -const pkg = require('./package.json'); -const filename = 'anchor.min.js'; -const script = fs.readFileSync(filename); -const padStart = str => ('0' + str).slice(-2) -const dateObj = new Date; -const date = `${dateObj.getFullYear()}-${padStart(dateObj.getMonth() + 1)}-${padStart(dateObj.getDate())}`; -const banner = `/** - * AnchorJS - v${pkg.version} - ${date} - * ${pkg.homepage} - * Copyright (c) ${dateObj.getFullYear()} Bryan Braun; Licensed ${pkg.license} - */ -`; - -if (script.slice(0, 3) != '/**') { - fs.writeFileSync(filename, banner + script); -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/bower.json b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/bower.json deleted file mode 100644 index bb80f99dce..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/bower.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "anchor-js", - "version": "4.1.0", - "authors": [ - "Bryan Braun" - ], - "description": "A Javascript utility for adding deep anchor links to online docs.", - "main": "anchor.js", - "license": "MIT", - "homepage": "https://github.com/bryanbraun/anchorjs", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests", - "package.json" - ] -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/anchor.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/anchor.js deleted file mode 100644 index 5813b98ed0..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/anchor.js +++ /dev/null @@ -1,335 +0,0 @@ -/* eslint-env amd, node */ - -// https://github.com/umdjs/umd/blob/master/templates/returnExports.js -(function (root, factory) { - 'use strict'; - - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], factory); - } else if (typeof module === 'object' && module.exports) { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - // Browser globals (root is window) - root.AnchorJS = factory(); - root.anchors = new root.AnchorJS(); - } -}(this, function () { - 'use strict'; - - function AnchorJS(options) { - this.options = options || {}; - this.elements = []; - - /** - * Assigns options to the internal options object, and provides defaults. - * @param {Object} opts - Options object - */ - function _applyRemainingDefaultOptions(opts) { - opts.icon = opts.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'. - opts.visible = opts.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' & 'touch' - opts.placement = opts.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left' - opts.ariaLabel = opts.hasOwnProperty('ariaLabel') ? opts.ariaLabel : 'Anchor'; // Accepts any text. - opts.class = opts.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name. - // Using Math.floor here will ensure the value is Number-cast and an integer. - opts.truncate = opts.hasOwnProperty('truncate') ? Math.floor(opts.truncate) : 64; // Accepts any value that can be typecast to a number. - } - - _applyRemainingDefaultOptions(this.options); - - /** - * Checks to see if this device supports touch. Uses criteria pulled from Modernizr: - * https://github.com/Modernizr/Modernizr/blob/da22eb27631fc4957f67607fe6042e85c0a84656/feature-detects/touchevents.js#L40 - * @return {Boolean} - true if the current device supports touch. - */ - this.isTouchDevice = function() { - return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); - }; - - /** - * Add anchor links to page elements. - * @param {String|Array|Nodelist} selector - A CSS selector for targeting the elements you wish to add anchor links - * to. Also accepts an array or nodeList containing the relavant elements. - * @return {this} - The AnchorJS object - */ - this.add = function(selector) { - var elements, - elsWithIds, - idList, - elementID, - i, - index, - count, - tidyText, - newTidyText, - readableID, - anchor, - visibleOptionToUse, - indexesToDrop = []; - - // We reapply options here because somebody may have overwritten the default options object when setting options. - // For example, this overwrites all options but visible: - // - // anchors.options = { visible: 'always'; } - _applyRemainingDefaultOptions(this.options); - - visibleOptionToUse = this.options.visible; - if (visibleOptionToUse === 'touch') { - visibleOptionToUse = this.isTouchDevice() ? 'always' : 'hover'; - } - - // Provide a sensible default selector, if none is given. - if (!selector) { - selector = 'h2, h3, h4, h5, h6'; - } - - elements = _getElements(selector); - - if (elements.length === 0) { - return this; - } - - _addBaselineStyles(); - - // We produce a list of existing IDs so we don't generate a duplicate. - elsWithIds = document.querySelectorAll('[id]'); - idList = [].map.call(elsWithIds, function assign(el) { - return el.id; - }); - - for (i = 0; i < elements.length; i++) { - if (this.hasAnchorJSLink(elements[i])) { - indexesToDrop.push(i); - continue; - } - - if (elements[i].hasAttribute('id')) { - elementID = elements[i].getAttribute('id'); - } else if (elements[i].hasAttribute('data-anchor-id')) { - elementID = elements[i].getAttribute('data-anchor-id'); - } else { - tidyText = this.urlify(elements[i].textContent); - - // Compare our generated ID to existing IDs (and increment it if needed) - // before we add it to the page. - newTidyText = tidyText; - count = 0; - do { - if (index !== undefined) { - newTidyText = tidyText + '-' + count; - } - - index = idList.indexOf(newTidyText); - count += 1; - } while (index !== -1); - index = undefined; - idList.push(newTidyText); - - elements[i].setAttribute('id', newTidyText); - elementID = newTidyText; - } - - readableID = elementID.replace(/-/g, ' '); - - // The following code builds the following DOM structure in a more effiecient (albeit opaque) way. - // ''; - anchor = document.createElement('a'); - anchor.className = 'anchorjs-link ' + this.options.class; - anchor.href = '#' + elementID; - anchor.setAttribute('aria-label', this.options.ariaLabel); - anchor.setAttribute('data-anchorjs-icon', this.options.icon); - - if (visibleOptionToUse === 'always') { - anchor.style.opacity = '1'; - } - - if (this.options.icon === '\ue9cb') { - anchor.style.font = '1em/1 anchorjs-icons'; - - // We set lineHeight = 1 here because the `anchorjs-icons` font family could otherwise affect the - // height of the heading. This isn't the case for icons with `placement: left`, so we restore - // line-height: inherit in that case, ensuring they remain positioned correctly. For more info, - // see https://github.com/bryanbraun/anchorjs/issues/39. - if (this.options.placement === 'left') { - anchor.style.lineHeight = 'inherit'; - } - } - - if (this.options.placement === 'left') { - anchor.style.position = 'absolute'; - anchor.style.marginLeft = '-1em'; - anchor.style.paddingRight = '0.5em'; - elements[i].insertBefore(anchor, elements[i].firstChild); - } else { // if the option provided is `right` (or anything else). - anchor.style.paddingLeft = '0.375em'; - elements[i].appendChild(anchor); - } - } - - for (i = 0; i < indexesToDrop.length; i++) { - elements.splice(indexesToDrop[i] - i, 1); - } - this.elements = this.elements.concat(elements); - - return this; - }; - - /** - * Removes all anchorjs-links from elements targed by the selector. - * @param {String|Array|Nodelist} selector - A CSS selector string targeting elements with anchor links, - * OR a nodeList / array containing the DOM elements. - * @return {this} - The AnchorJS object - */ - this.remove = function(selector) { - var index, - domAnchor, - elements = _getElements(selector); - - for (var i = 0; i < elements.length; i++) { - domAnchor = elements[i].querySelector('.anchorjs-link'); - if (domAnchor) { - // Drop the element from our main list, if it's in there. - index = this.elements.indexOf(elements[i]); - if (index !== -1) { - this.elements.splice(index, 1); - } - // Remove the anchor from the DOM. - elements[i].removeChild(domAnchor); - } - } - return this; - }; - - /** - * Removes all anchorjs links. Mostly used for tests. - */ - this.removeAll = function() { - this.remove(this.elements); - }; - - /** - * Urlify - Refine text so it makes a good ID. - * - * To do this, we remove apostrophes, replace nonsafe characters with hyphens, - * remove extra hyphens, truncate, trim hyphens, and make lowercase. - * - * @param {String} text - Any text. Usually pulled from the webpage element we are linking to. - * @return {String} - hyphen-delimited text for use in IDs and URLs. - */ - this.urlify = function(text) { - // Regex for finding the nonsafe URL characters (many need escaping): & +$,:;=?@"#{}|^~[`%!'<>]./()*\ - var nonsafeChars = /[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\]/g, - urlText; - - // The reason we include this _applyRemainingDefaultOptions is so urlify can be called independently, - // even after setting options. This can be useful for tests or other applications. - if (!this.options.truncate) { - _applyRemainingDefaultOptions(this.options); - } - - // Note: we trim hyphens after truncating because truncating can cause dangling hyphens. - // Example string: // " ⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." - urlText = text.trim() // "⚡⚡ Don't forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." - .replace(/\'/gi, '') // "⚡⚡ Dont forget: URL fragments should be i18n-friendly, hyphenated, short, and clean." - .replace(nonsafeChars, '-') // "⚡⚡-Dont-forget--URL-fragments-should-be-i18n-friendly--hyphenated--short--and-clean-" - .replace(/-{2,}/g, '-') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-short-and-clean-" - .substring(0, this.options.truncate) // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated-" - .replace(/^-+|-+$/gm, '') // "⚡⚡-Dont-forget-URL-fragments-should-be-i18n-friendly-hyphenated" - .toLowerCase(); // "⚡⚡-dont-forget-url-fragments-should-be-i18n-friendly-hyphenated" - - return urlText; - }; - - /** - * Determines if this element already has an AnchorJS link on it. - * Uses this technique: http://stackoverflow.com/a/5898748/1154642 - * @param {HTMLElemnt} el - a DOM node - * @return {Boolean} true/false - */ - this.hasAnchorJSLink = function(el) { - var hasLeftAnchor = el.firstChild && ((' ' + el.firstChild.className + ' ').indexOf(' anchorjs-link ') > -1), - hasRightAnchor = el.lastChild && ((' ' + el.lastChild.className + ' ').indexOf(' anchorjs-link ') > -1); - - return hasLeftAnchor || hasRightAnchor || false; - }; - - /** - * Turns a selector, nodeList, or array of elements into an array of elements (so we can use array methods). - * It also throws errors on any other inputs. Used to handle inputs to .add and .remove. - * @param {String|Array|Nodelist} input - A CSS selector string targeting elements with anchor links, - * OR a nodeList / array containing the DOM elements. - * @return {Array} - An array containing the elements we want. - */ - function _getElements(input) { - var elements; - if (typeof input === 'string' || input instanceof String) { - // See https://davidwalsh.name/nodelist-array for the technique transforming nodeList -> Array. - elements = [].slice.call(document.querySelectorAll(input)); - // I checked the 'input instanceof NodeList' test in IE9 and modern browsers and it worked for me. - } else if (Array.isArray(input) || input instanceof NodeList) { - elements = [].slice.call(input); - } else { - throw new Error('The selector provided to AnchorJS was invalid.'); - } - return elements; - } - - /** - * _addBaselineStyles - * Adds baseline styles to the page, used by all AnchorJS links irregardless of configuration. - */ - function _addBaselineStyles() { - // We don't want to add global baseline styles if they've been added before. - if (document.head.querySelector('style.anchorjs') !== null) { - return; - } - - var style = document.createElement('style'), - linkRule = - ' .anchorjs-link {' + - ' opacity: 0;' + - ' text-decoration: none;' + - ' -webkit-font-smoothing: antialiased;' + - ' -moz-osx-font-smoothing: grayscale;' + - ' }', - hoverRule = - ' *:hover > .anchorjs-link,' + - ' .anchorjs-link:focus {' + - ' opacity: 1;' + - ' }', - anchorjsLinkFontFace = - ' @font-face {' + - ' font-family: "anchorjs-icons";' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above - ' src: url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype");' + - ' }', - pseudoElContent = - ' [data-anchorjs-icon]::after {' + - ' content: attr(data-anchorjs-icon);' + - ' }', - firstStyleEl; - - style.className = 'anchorjs'; - style.appendChild(document.createTextNode('')); // Necessary for Webkit. - - // We place it in the head with the other style tags, if possible, so as to - // not look out of place. We insert before the others so these styles can be - // overridden if necessary. - firstStyleEl = document.head.querySelector('[rel="stylesheet"], style'); - if (firstStyleEl === undefined) { - document.head.appendChild(style); - } else { - document.head.insertBefore(style, firstStyleEl); - } - - style.sheet.insertRule(linkRule, style.sheet.cssRules.length); - style.sheet.insertRule(hoverRule, style.sheet.cssRules.length); - style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length); - style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length); - } - } - - return AnchorJS; -})); diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/favicon.ico b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/favicon.ico deleted file mode 100644 index 2a6c767106..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/favicon.ico and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.eot b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.eot deleted file mode 100644 index 350ea35b4b..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.eot and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.svg b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.svg deleted file mode 100644 index 5e14922b21..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.ttf b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.ttf deleted file mode 100644 index 1971eb1814..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.ttf and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.woff b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.woff deleted file mode 100644 index fb3b104339..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/anchorjs-extras.woff and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/fonts.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/fonts.css deleted file mode 100644 index c0b57b8e57..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/fonts/fonts.css +++ /dev/null @@ -1,24 +0,0 @@ -@font-face { - font-family: 'anchorjs-extras'; - src:url('anchorjs-extras.eot?-qcq09q'); - src:url('anchorjs-extras.eot?#iefix-qcq09q') format('embedded-opentype'), - url('anchorjs-extras.woff?-qcq09q') format('woff'), - url('anchorjs-extras.ttf?-qcq09q') format('truetype'), - url('anchorjs-extras.svg?-qcq09q#anchorjs-extras') format('svg'); - font-weight: normal; - font-style: normal; -} - -[class^="ajs-"], [class*=" ajs-"] { - font-family: 'anchorjs-extras'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering =========== */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/grunticon.loader.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/grunticon.loader.js deleted file mode 100644 index de17974263..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/grunticon.loader.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */ - -(function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.png.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.png.css deleted file mode 100644 index f0bab86024..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.png.css +++ /dev/null @@ -1,5 +0,0 @@ - -.icon-grunticon-link { - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABuklEQVQ4T52U4VnCMBiE71hAnECcgLCBblBYAJxANgAmEDfABWg3kA2IE6ATWBbo+XwplLaWguZnm765fncX4h9LkesC6DHxvv45/8JT5CIQLyB74TspBbFChgUTn9qjq4EauhXIMYA9pBWIFKId0IfkITwa9CpgARM+ID0c1QSRIzcHOIP0ythPLwLbYMdxaTjwgO4Y+9uLwKAicjaztKysPPtCZab7VqAi9wBSkPZNjp4UuiXIZ2RqVqiRm0KYgbR45Csf/FMdHCJE7EDuud72fiksufkFaIkMnyBM6QSSDm6G/B1g7yAdMg2Z+KQCbHUzcg4dbiwy5mYFJr0x9pNKDptgGrolgHFZ1S9lJVgBDA3oMEYtZzqpEogEQgLCQZiEttRgJ+Bo8Amgi0zWz1ChwguDktaMfunxHtCca29/UFkMs+jw+5j0c90Oau1Q62viN+f2GdCGvQW04NrPmzYebpcuE29/0rqCyxoNUkg7xn5Q333OzbMKA9DctKTnc1mU5mehzXPWYEATNFcY0s5NcRWZozav3M3utbBqDvMKzUMjgJvD6V/INLUGXJrd8X3j5XDpdmmD/wAyTxBSftthKwAAAABJRU5ErkJggg=='); - background-repeat: no-repeat; -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.svg.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.svg.css deleted file mode 100644 index ea5bd003c9..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.data.svg.css +++ /dev/null @@ -1,5 +0,0 @@ - -.icon-grunticon-link { - background-image: url('data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3C%21--%20Generated%20by%20IcoMoon.io%20--%3E%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-//W3C//DTD%20SVG%201.1//EN%22%20%22http%3A//www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20width%3D%2220%22%20height%3D%2220%22%20viewBox%3D%220%200%20768%20768%22%3E%0A%20%20%3Cg%20fill%3D%22%23FF5231%22%3E%0A%20%20%20%20%3Cpath%20d%3D%22M544%2032q37.75%200%2072.875%2014.25t62.875%2042%2042%2062.875%2014.25%2072.875q0%2037.5-14.375%2072.875t-41.875%2062.875l-96%2096q-2.75%202.75-8.25%207.75-26.75%2023.75-59.75%2036.125t-67.75%2012.375q-43.75%200-82.75-18.75-29.25-13.75-53-37.5t-37.5-53q18.75-18.75%2045.25-18.75%209.25%200%2018.75%202.75%2016.25%2026.25%2042.5%2042.5%2030.75%2018.75%2066.75%2018.75%2025%200%2048.5-9.5t42-28l96-96q18.5-18.5%2028-42t9.5-48.5-9.5-48.5-28-42-42-28-48.5-9.5-48.5%209.5-42%2028l-67.25%2067.25q-32-8.75-66.25-8.75-5.5%200-15.5%200.5%205-5.5%207.75-8.25l96-96q27.5-27.5%2062.875-41.875t72.875-14.375zM320%20256q43.75%200%2082.75%2018.75%2029.25%2013.75%2053%2037.5t37.5%2053q-18.75%2018.75-45.25%2018.75-9.25%200-18.75-2.75-16.25-26.25-42.5-42.5-30.75-18.75-66.75-18.75-25%200-48.5%209.5t-42%2028l-96%2096q-18.5%2018.5-28%2042t-9.5%2048.5%209.5%2048.5%2028%2042%2042%2028%2048.5%209.5%2048.5-9.5%2042-28l67.25-67.25q32%208.75%2066.25%208.75%205.5%200%2015.5-0.5-5%205.5-7.75%208.25l-96%2096q-27.75%2027.75-62.875%2042t-72.875%2014.25q-37.5%200-72.875-14.375t-62.875-41.875q-27.75-27.75-42-62.875t-14.25-72.875%2014.25-72.875%2042-62.875l96-96q2.75-2.75%208.25-7.75%2026.75-23.75%2059.75-36.125t67.75-12.375z%22%3E%3C/path%3E%0A%20%20%3C/g%3E%0A%3C/svg%3E%0A'); - background-repeat: no-repeat; -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.fallback.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.fallback.css deleted file mode 100644 index 832f36fe7e..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/icons.fallback.css +++ /dev/null @@ -1,5 +0,0 @@ - -.icon-grunticon-link { - background-image: url('png/grunticon-link.png'); - background-repeat: no-repeat; -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/png/grunticon-link.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/png/grunticon-link.png deleted file mode 100644 index eefa53f0c2..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/png/grunticon-link.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/preview.html b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/preview.html deleted file mode 100644 index 864885d91d..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/grunticon/preview.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - Icons Preview! - - - - - - - - -

    PREVIEW - you can change this in the previewTemplate option

    - - -
    .icon-grunticon-link:

    - - - - diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchoring-links.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchoring-links.png deleted file mode 100644 index 9d28abcf80..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchoring-links.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorjs_logo.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorjs_logo.png deleted file mode 100644 index 06c8b4df50..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorjs_logo.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorlinks2.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorlinks2.png deleted file mode 100644 index 9118b1ecca..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/anchorlinks2.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh-link.svg b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh-link.svg deleted file mode 100644 index 24abb41cc9..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh-link.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh_link.svg b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh_link.svg deleted file mode 100644 index 8e43abb449..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/gh_link.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/hyperlink.svg b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/hyperlink.svg deleted file mode 100644 index 3a8745a683..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/hyperlink.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/link.svg b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/link.svg deleted file mode 100644 index 5aaef2fcac..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/link.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/mini-logo.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/mini-logo.png deleted file mode 100644 index 3806c67b04..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/mini-logo.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/primer-md.png b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/primer-md.png deleted file mode 100644 index 1db2cb60ca..0000000000 Binary files a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/img/primer-md.png and /dev/null differ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/index.html b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/index.html deleted file mode 100644 index a3c44582e3..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/index.html +++ /dev/null @@ -1,822 +0,0 @@ - - - - - AnchorJS - Add deep anchor links to your docs - - - - - - - - - - -
    -

    AnchorJS

    - -
    -

    Add deep anchor links to your docs.

    -

    What are "deep anchor links"? Here are a few examples:

    -
    -
    -
    -
    - -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options.visible = 'always';
    -anchors.add('h3');
    -
    -
    -
    -
    -

    Paragraph Link

    - - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: '¶'
    -};
    -anchors.add('p');
    -
    -
    -
    -

    See more examples

    -
    -

    Used by

    - - Bootstrap Logo - ESLint logo - 18F Logo - Bundler Logo - Mocha Logo - Middleman logo - -
    -
    -
    -

    Overview

    - Examples of deep anchor links from across the web. -

    AnchorJS lets you drop deep anchor links (like these) onto any webpage, and be on your way.

    -

    You don't need to set up IDs or worry about urls. AnchorJS will respect your IDs if you have them, and generate them if you don't.

    -

    It uses an attractive link icon by default, but you can customize the display via options and CSS syling. The examples demonstrate a few customization ideas.

    -

    Finally, AnchorJS is lightweight, accessible, and has no dependencies.

    - -

    Installation

    - -

    Download AnchorJS using npm,

    -
    npm install anchor-js
    -

    or bower:

    -
    bower install anchor-js
    -

    (or just download it from github).

    -

    Then include the anchor.js file (or anchor.min.js) in your webpage.

    -
    <script src="anchor.js"></script>
    -

    You could also include it via a CDN like CDNJS or jsDelivr.

    -

    If you're using it from Node/CommonJS, include it via:

    -
    var anchorJS = require('anchor-js');
    -var anchors = new anchorJS();
    - -

    Basic usage

    -

    AnchorJS provides the anchors.add() method which takes a CSS selector (similar to jQuery) for targeting elements you want to deep-link. Here are some usage examples.

    -
    /**
    - * Example 1
    - * Add anchors to all h1's on the page
    - */
    -anchors.add('h1');
    -
    -/**
    - * Example 2
    - * Adds anchors to elements that have been assigned the class '.anchored'
    - */
    -anchors.add('.anchored');
    -
    -/**
    - * Example 3
    - * If no selector is provided, it falls back to a default selector of:
    - * 'h2, h3, h4, h5, h6'
    - */
    -anchors.add();
    - -

    Don't run it too late!

    -

    You need to add anchors to the page early in the page load process if you want browsers to jump to the ID properly.

    -

    We recommend you call anchors.add() before the DOM finishes loading...

    - -
    <!-- Add anchors before the closing body tag. -->
    -  <script>
    -    anchors.add();
    -  </script>
    -</body>
    -

    ...or on DOMContentLoaded:

    -
    // Add anchors on DOMContentLoaded
    -document.addEventListener("DOMContentLoaded", function(event) {
    -  anchors.add();
    -});
    - -

    Don't add anchors on later events, like $(document).ready() or window.onload as some browsers will attempt to jump to your ID before AnchorJS can add it to the page. For more details, see github issue #69).

    - -

    Options

    -

    You can set a number of options to customize how your anchors look:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OptionAccepted ValuesDefault ValueDescription
    placementright
    left
    rightright appends the anchor to the end of the element.
    left places it to the left, in the margin.
    visiblehover
    always
    touch
    hoverhover displays the anchor when hovering over the element.
    always will always display the anchor link.
    touch will always display anchors for devices that support touch events, and only display them via hover for devices that do not support touch events. This approximates touchscreen detection (but isn't 100% accurate).
    icon(any unicode character)Replace the default link icon with the character(s) provided. These are a few good options: #, , , and §.
    class(any string)(none)Adds the provided class(es) to the anchor html.
    truncate(any positive number)64Truncates the generated ID to the specified character length. Note: the length may not be exactly the same, if there are dangling spaces or hyphens to be trimmed.
    ariaLabel(any text)AnchorAllows you to customize or translate the default aria-label ("Anchor"), for screenreaders that encounter the link.
    -

    For example:

    -
    /**
    - * Example 1
    - * Add anchors to all h1s, h2s and h3s inside of #post.
    - * Anchors will be always visible.
    - */
    -anchors.options.visible = 'always';
    -anchors.add('#post h1, #post h2, #post h3');
    -
    -/**
    - * Example 2
    - * Provide options as an object before adding anchors to the page.
    - * Adds always-visible ¶ anchors in the left margin of each p tag inside .story
    - */
    -anchors.options = {
    -  placement: 'left',
    -  visible: 'always',
    -  icon: '¶'
    -};
    -anchors.add('.story > p');
    - -

    Advanced usage

    - -
    -

    Section IDs

    -

    In some cases, you might want to link to existing section IDs instead of the heading element itself. You can instruct AnchorJS to do this with the data-anchor-id attribute:

    -
    <section id="section-1">
    -  <h3 data-anchor-id="section-1">Section 1</h3>
    -  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed...</p>
    -</section>
    -
    -<!-- ... -->
    -
    -<script>
    -  anchors.add('h3');
    -</script>
    -

    This allows you to do things like highlight sections when your users jump to them.

    -
    - -

    Removing anchors

    -

    You can remove anchors with the anchors.remove() or anchors.removeAll() methods:

    -
    /**
    - * Example 1
    - * Remove anchors from all h1s on the page.
    - */
    -anchors.remove('h1');
    -
    -/**
    - * Example 2
    - * Remove all anchors from the page.
    - */
    -anchors.removeAll();
    -

    Removing anchors with .remove() should be uncommon. If you simply want anchors on a more selective group, consider using the CSS :not() pseudo-class when you add them, like so:

    -
    /**
    - * Example 2
    - * Add anchors to all h2s, except for those with a class of "no-anchor".
    - */
    -anchors.add('h2:not(.no-anchor)');
    - -

    Chaining commands

    -

    You can chain commands of add() and remove() (since they return a copy of anchors), but it's usually more performant to lean on CSS when targeting elements: - -

    /**
    -  * Example 1
    -  * Adds anchors to `.my-anchors` and `.my-other-anchors` except for those
    -  * with a class of `no-anchor`.
    -  */
    - anchors.add('.my-anchors').add('.my-other-anchors').remove('.no-anchor');
    -
    - /**
    -  * Example 2
    -  * A more performant way to add anchors to the same classes in Example 1 above.
    -  */
    -  anchors.add('.my-anchors:not(.no-anchor), .my-other-anchors:not(.no-anchor)');
    - -

    Multiple sets of anchors

    -

    You can have multiple sets of anchors on one page, each with their own design. To do so, just create your own instances of the AnchorJS object:

    -
    var sidebarAnchors = new AnchorJS();
    -anchors.add('.main h2'); // The default instance.
    -sidebarAnchors.add('.sidebar h2'); // The new instance.
    -

    You can preset your instance with whatever options you like:

    -
    var sidebarAnchors = new AnchorJS({
    -  placement: 'left',
    -  icon: '¶'
    -});
    -sidebarAnchors.add('.sidebar h2');
    - -

    Generating navigations

    -

    AnchorJS doesn't include methods for dynamically generating navigations (like a table of contents or jump nav). This is to keep AnchorJS lightweight and simple for the most common usecases.

    -

    However, AnchorJS does expose a list of all anchored elements at anchors.elements. This way, external code can look up the elements and use them to generate navigations (as shown in this example).

    -

    You can also use AnchorJS alongside a static navigation with pre-defined IDs (as is done in this example).

    - -

    Examples

    -
    -
    -
    -

    Basic Link

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options.visible = 'always';
    -anchors.add('h3');
    -
    -
    -
    -
    -

    Basic Link - Left

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left'
    -};
    -anchors.add('h3');
    -
    -
    -
    -
    -

    Paragraph Link

    - - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: '¶'
    -};
    -anchors.add('p');
    -
    -
    -
    -
    -

    Octothorp

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  icon: '#'
    -};
    -anchors.add('h3');
    -
    -
    -
    -
    -

    Unicode Icon 1

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: '§'
    -};
    -anchors.add('h3');
    -
    -
    -
    -
    -

    Unicode Icon 2

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  icon: '❡'
    -};
    -anchors.add('p');
    -
    -
    -
    -
    -

    Custom Text

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  icon: '# LINK'
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  font-weight: 200;
    -  margin-left: 1em;
    -  padding-right: 0.375em;
    -  font-size: 0.5em;
    -  border: 1px dashed #FFBAAC;
    -  vertical-align: middle;
    -}
    -
    -
    -
    -
    -

    Custom Image

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    // Use an empty string ('') for the icon when styling the background with CSS.
    -anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: ''
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  width: 14px;
    -  height: 32px;
    -  margin-top: 6px;
    -  margin-left: -1.25em !important;
    -  background: url('img/mini-logo.png') no-repeat;
    -}
    -
    -
    -
    -
    -

    Link w/CSS Styling

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left'
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  display: inline-block;
    -  height: 32px;
    -  width: 18px;
    -  border-radius: 50%;
    -  background-color: #FF5231;
    -  color: white;
    -  margin-top: 4px;
    -  margin-left: -1.4em !important;
    -}
    -.anchorjs-link:before {
    -  margin-left: 7px;
    -  margin-top: -4px;
    -  display: block;
    -}
    -
    -
    -
    -
    -

    Icon Font

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    // Just pass in the octal code for your icon-font character.
    -anchors.options = {
    -  visible: 'always',
    -  icon: '\uf0c1'
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  font-family: 'your-icon-font';
    -}
    -
    -
    -
    -
    -

    SVG Icon

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  icon: ''
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  display: inline-block;
    -  background: url('img/hyperlink.svg') no-repeat;
    -  margin-left: 8px;
    -  width: 14px;
    -  height: 24px;
    -}
    -
    -
    -
    -
    -

    Base64 Icon

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: ''
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjIwcHgiIGhlaWdodD0iMTBweCIgdmlld0JveD0iMCAwIDIwIDEwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9ImxpbmsiIGZpbGw9IiNGRjUyMzEiPgogICAgICAgICAgICA8cGF0aCBkPSJNMTUsMCBMMTIuMzA0Njg3NSwwIEMxMy4yNDIxODc1LDAuNjI1IDE0LjEyMTA5MzgsMS43MzgyODEyNSAxNC4zOTQ1MzEyLDIuNSBMMTQuOTgwNDY4OCwyLjUgQzE2LjI1LDIuNSAxNy40ODA0Njg4LDMuNzUgMTcuNDgwNDY4OCw1IEMxNy40ODA0Njg4LDYuMjUgMTYuMjEwOTM3NSw3LjUgMTQuOTgwNDY4OCw3LjUgTDExLjIzMDQ2ODgsNy41IEMxMCw3LjUgOC43MzA0Njg3NSw2LjI1IDguNzMwNDY4NzUsNSBDOC43MzA0Njg3NSw0LjU1MDc4MTI1IDguODY3MTg3NSw0LjEyMTA5Mzc1IDkuMDgyMDMxMjUsMy43NSBMNi40MDYyNSwzLjc1IEM2LjMwODU5Mzc1LDQuMTYwMTU2MjUgNi4yNSw0LjU3MDMxMjUgNi4yNSw1IEM2LjI1LDcuNSA4LjczMDQ2ODc1LDEwIDExLjIzMDQ2ODgsMTAgTDE1LDEwIEMxNy41LDEwIDIwLDcuNSAyMCw1IEMyMCwyLjUgMTcuNSwwIDE1LDAgTDE1LDAgWiBNNS42MDU0Njg3NSw3LjUgTDUuMDE5NTMxMjUsNy41IEMzLjc1LDcuNSAyLjUxOTUzMTI1LDYuMjUgMi41MTk1MzEyNSw1IEMyLjUxOTUzMTI1LDMuNzUgMy43ODkwNjI1LDIuNSA1LjAxOTUzMTI1LDIuNSBMOC43Njk1MzEyNSwyLjUgQzEwLDIuNSAxMS4yNjk1MzEyLDMuNzUgMTEuMjY5NTMxMiw1IEMxMS4yNjk1MzEyLDUuNDQ5MjE4NzUgMTEuMTMyODEyNSw1Ljg3ODkwNjI1IDEwLjkxNzk2ODgsNi4yNSBMMTMuNTkzNzUsNi4yNSBDMTMuNjkxNDA2Miw1LjgzOTg0Mzc1IDEzLjc1LDUuNDI5Njg3NSAxMy43NSw1IEMxMy43NSwyLjUgMTEuMjY5NTMxMiwwIDguNzY5NTMxMjUsMCBMNSwwIEMyLjUsMCAwLDIuNSAwLDUgQzAsNy41IDIuNSwxMCA1LDEwIEw3LjY5NTMxMjUsMTAgQzYuNzU3ODEyNSw5LjM3NSA1Ljg3ODkwNjI1LDguMjYxNzE4NzUgNS42MDU0Njg3NSw3LjUgTDUuNjA1NDY4NzUsNy41IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+") no-repeat;
    -  margin-top: 15px;
    -  height: 16px;
    -  width: 20px;
    -}
    -
    -
    -
    -
    -

    CSS Icon

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: ''
    -};
    -anchors.add('h3');
    -
    /* See also: nicolasgallagher.com/pure-css-gui-icons */
    -.anchorjs-link {
    -  border-color: #FF5231 #FF5231 transparent;
    -  border-width: 15px 7px 6px;
    -  border-style: solid;
    -  margin-top: 10px;
    -  font-size: 22px;
    -  padding-right: 0 !important;
    -}
    -
    -
    -
    -
    -

    Emoji

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = {
    -  visible: 'always',
    -  placement: 'left',
    -  icon: '⚓'
    -};
    -anchors.add('p');
    -
    .anchorjs-link {
    -  margin-left: -1.8em !important;
    -}
    -
    -
    - -
    -
    -

    Grunticon

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    // Assuming you have set up
    -// grunticon and you have a
    -// grunticon class named
    -// 'icon-grunticon-link'...
    -anchors.options = {
    -  visible: 'always',
    -  class: 'icon-grunticon-link'
    -  icon: ''
    -};
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  display: inline-block;
    -  margin-left: 0.375em;
    -  width: 0.375em;
    -  height: 20px;
    -}
    -
    -
    - -
    - -

    Hover examples

    -
    -
    -
    -

    Basic Hover

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.add('h3');
    -
    -
    -
    -
    -

    Color Transition

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.add('h3');
    -
    .anchorjs-link:hover {
    -  color: #2500AD;
    -}
    -*:hover > .anchorjs-link {
    -  transition: color .25s linear;
    -}
    -
    -
    -
    -
    -

    Shift Out

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options.placement = 'left';
    -anchors.add('h3');
    -
    .anchorjs-link {
    -  transition: all .25s linear;
    -}
    -*:hover > .anchorjs-link {
    -  margin-left: -1.125em !important;
    -}
    -
    -
    - -
    -
    -

    Arrow

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options.icon = '# LINK';
    -anchors.add('h3');
    -
    /* Based on http://codepen.io/corysimmons/pen/NPBXbe */
    -/* Vendor prefixes not included */
    -.anchorjs-link {
    -  position: relative;
    -  top: 4px;
    -  height: 36px;
    -  flex: 1;
    -  background: #FF5231;
    -  color: white;
    -  font-family: Helvetica, Arial, sans-serif;
    -  font-weight: 200;
    -  font-size: 1rem;
    -  margin-right: -6%;
    -  padding-right: 6%;
    -  padding-left: 42px !important;
    -  line-height: 38px;
    -  transition: all 0.5s ease;
    -  transform: translateX(100%);
    -}
    -.anchorjs-link::before {
    -  position: absolute;
    -  display: block;
    -  left: 0;
    -  width: 0;
    -  height: 0;
    -  content: '';
    -  border: 18px solid #fdfdfd; /* Background color */
    -  border-right-color: #FF5231;
    -  transition: all 0.5s ease;
    -}
    -h2 {
    -  display: flex;
    -}
    -*:hover > .anchorjs-link {
    -  transform: translateX(0);
    -}
    -*:hover > .anchorjs-link:hover {
    -  background: #FF806A;
    -}
    -*:hover > .anchorjs-link:hover::before {
    -  border-right-color: #FF806A;
    -}
    -
    -
    - -
    -
    -

    Tooltip

    -

    Lorem ipsum dolor consectetur amet nulla elit. Vivamus luctus urna sed urna ultricies. Vivamus luctus urna sed.

    - {} -
    -
    -
    anchors.options = { icon: 'Permalink' };
    -anchors.add('h3');
    -
    /* tooltip box */
    -.anchorjs-link:after {
    -  display: inline-block;
    -  transition: opacity .25s linear;
    -  font-family: Verdana, sans-serif;
    -  font-size: 0.75ex;
    -  font-weight: 100;
    -  padding: 0.5ex 1.5ex;
    -  background: #444;
    -  color: #fff;
    -  border-radius: 0.6ex;
    -  vertical-align: 0.8ex;
    -}
    -/* tooltip arrow */
    -.anchorjs-link:before {
    -  content: '';
    -  display: inline-block;
    -  border-top: 0.3ex solid transparent;
    -  border-right: 0.5ex solid #444;
    -  border-bottom: 0.3ex solid transparent;
    -  vertical-align: 0.35ex;
    -}
    -.anchorjs-link:hover:after {
    -  background-color: #666;
    -}
    -.anchorjs-link:hover:before {
    -  border-right-color: #666;
    -}
    -
    -
    - -
    - - Fork me on GitHub -
    - - - - - - - diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/scripts.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/scripts.js deleted file mode 100644 index c283e73a41..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/scripts.js +++ /dev/null @@ -1,12 +0,0 @@ -$(document).ready(function() { - var preEls = $('pre'); - - $('.example-code-link').click(function(e) { - e.preventDefault(); - $(this).parent().next().slideToggle(); - }); - - // Dynamically add PrismJS class for syntax highlight - preEls.filter('[class*="js"]').find('code').addClass('language-javascript'); - preEls.filter('.css').find('code').addClass('language-css'); -}); diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/styles.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/styles.css deleted file mode 100644 index 5e588f5fd7..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/anchor-js/docs/styles.css +++ /dev/null @@ -1,494 +0,0 @@ -/*//// Base Styles ////*/ - -div, -article, -section, -main, -footer, -header, -form, -fieldset, -pre, -code, -p, -input[type="text"], -input[type="tel"], -input[type="email"], -input[type="url"], -input[type="password"] { - box-sizing: border-box; -} - -body { - font-family: 'Source Sans Pro', sans-serif; - background-color: rgb(162, 255, 224); - color: #262626; - margin: 0 1.5em; -} - -h1 { - font-size: 2.2em; -} -h2 { - font-size: 2.0em; - margin-top: 1.5em; -} -h3 { - font-size: 1.8em; -} - -table { - border-collapse: collapse; - background: white; - box-shadow: 0px 0px 10px -4px #666; - border: 1px solid white; -} - -table td, -table th { - padding: 0.5em; - border: 1px solid #ddd; -} - -img { - max-width: 100%; -} - -a { - color: black; - text-decoration: underline; -} - -/*//// Code Snippet Styles ////*/ - -code, -samp, -kbd { - background-color: #141414; - color: #f7f7f7; - font-family: "Inconsolata", "Menlo", "Consolas", monospace; - font-size: 0.9em; - padding: 2px 6px; - text-align: left; - border-radius: 3px; -} - -pre { - background-color: #141414; - color: #f7f7f7; - font-family: "Inconsolata", "Menlo", "Consolas", monospace; - font-size: 0.9em; - line-height: 1.2em; - margin: 0; - overflow: auto; - padding: 1em; - border-radius: 3px; -} - -.examples pre, -.hover-examples pre, -.preview-examples pre { - padding-left: 2.75em; - border-radius: 0; -} - -/* Override 'code' css rules if using 'pre > code' markup. */ -pre > code { - font-size: 1em; - padding: 0px; -} - -/* for IE7 and IE6 */ -*:first-child+html pre { - overflow: visible; - overflow-x: auto; - overflow-y: hidden; - padding-bottom: 2em; -} - -* html pre { - overflow: visible; - overflow-x: auto; - padding-bottom: 2em; -} - -/* Reset PrismJS' border styles */ -.main pre[class*="language-"], -.example pre[class*="language-"] { - border: 0; - border-radius: 3px; -} - -/*//// Page Styles ////*/ -.header { - max-width: 720px; - margin: 0 auto; - padding-top: 1.5em; -} - -.page-title { - text-align: center; -} - -.logo { - display: block; - margin: 0 auto; -} - -.desc { - padding: 1em 0; - text-align: center; -} -.maindesc { - font-size: 30px; - margin-bottom: 1em; -} -.subdesc { - font-size: 15px; -} - -.more-examples { - text-align: right; - font-size: 12px; - margin: 0 5px 0 0; -} - -.main { - line-height: 1.4; - margin: 0 auto; - max-width: 720px; -} -.used-by { - text-align: center; - position: relative; - padding: 1em 0; -} -.used-by-label { - font-size: 20px; - text-align: center; - font-weight: normal; -} -.used-by img { - border-radius: 8px; - opacity: 1; - margin: 0px 10px; - width: 96px; -} - -.anchorlink-examples { - float: right; - margin: 0 0 1em 1em; - box-shadow: 0px 0px 10px -3px #666; -} - -.options-table { - width: 100%; - margin: 1em 0; -} - -.minicol { - width: 62px; -} - -.footer { - text-align: center; - color: #777; -} -.footer a { - color: #777; -} - -/*///////////// Examples /////////////*/ - -.examples, -.hover-examples, -.preview-examples { - max-width: 720px; - margin: 0 auto; - display: -webkit-flex; - display: flex; - -webkit-flex-direction: row; - flex-direction: row; - -webkit-justify-content: center; - justify-content: center; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -webkit-align-content: flex-end; - align-content: flex-end; -} - -.example { - max-width: 350px; - min-height: 160px; - margin: 5px; -} -.example-label { - font-size: 12px; - color: #777; - display: none; -} -.example-content { - padding: 0 0 0 3.5em; - overflow: hidden; - position: relative; - background: #fff; - box-shadow: 0px 0px 10px -3px #666; -} - -.example-code-link { - width: 16px; - position: absolute; - top: 8px; - right: 8px; - font-family: Courier monospace; - color: #aaa; - text-decoration: none; -} - -.example-code-link:hover:after, -.example-code-link:focus:after { - left: -50px; - opacity: 1; - -webkit-transition: all 0.25s ease-in; - transition: all 0.25s ease-in; -} - -.example-code-link:after { - content: "SOURCE"; - font-family: Helvetica, Arial, sans-serif; - font-size: 10px; - line-height: 1; - display: block; - position: absolute; - text-transform: uppercase; - top: 7px; - left: -45px; - opacity: 0; - -webkit-transition: all 0.25s ease-in; - transition: all 0.25s ease-in; -} - -.example-code { - display: none; -} - -.css { - border-top: 1px solid #666; -} - -.css, -.js { - position: relative; -} - -.css::before, -.js::before { - left: 0; - top: 0; - padding: 1px 4px; - color: white; - background: #FF5231; - position: absolute; - font-size: 11px; - text-transform: uppercase; -} - -.css::before { - content: 'css'; -} -.js::before { - content: 'js'; -} - -.example-content > p { - width: 310px; -} - -.anchorjs-link { - color: #FF5231; -} - -/*///// Styles within Examples /////*/ -.examples .example:nth-child(3) .anchorjs-link, -.preview-examples .example:nth-child(2) .anchorjs-link { - font-family: Helvetica, Arial, sans-serif; -} - -.examples .example:nth-child(7) .anchorjs-link { - font-weight: 200; - margin-left: 1em; - padding-right: 0.375em; - font-size: 0.5em; - border: 1px dashed #FFBAAC; - vertical-align: middle; -} - -.examples .example:nth-child(8) .anchorjs-link { - width: 14px; - height: 32px; - margin-top: 6px; - background: url('img/mini-logo.png') no-repeat; - margin-left: -1.25em !important; -} - -.examples .example:nth-child(9) .anchorjs-link:after { - margin-left: 7px; - margin-top: -4px; - display: block; -} - -.examples .example:nth-child(9) .anchorjs-link { - background-color: #FF5231; - height: 32px; - width: 18px; - border-radius: 50%; - display: inline-block; - color: white; - margin-top: 4px; - margin-left: -1.4em !important; -} - -.examples .example:nth-child(11) .anchorjs-link { - display: inline-block; - background: url('img/hyperlink.svg') no-repeat; - margin-left: 8px; - width: 14px; - height: 24px; -} - -.examples .example:nth-child(12) .anchorjs-link { - background: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjIwcHgiIGhlaWdodD0iMTBweCIgdmlld0JveD0iMCAwIDIwIDEwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9ImxpbmsiIGZpbGw9IiNGRjUyMzEiPgogICAgICAgICAgICA8cGF0aCBkPSJNMTUsMCBMMTIuMzA0Njg3NSwwIEMxMy4yNDIxODc1LDAuNjI1IDE0LjEyMTA5MzgsMS43MzgyODEyNSAxNC4zOTQ1MzEyLDIuNSBMMTQuOTgwNDY4OCwyLjUgQzE2LjI1LDIuNSAxNy40ODA0Njg4LDMuNzUgMTcuNDgwNDY4OCw1IEMxNy40ODA0Njg4LDYuMjUgMTYuMjEwOTM3NSw3LjUgMTQuOTgwNDY4OCw3LjUgTDExLjIzMDQ2ODgsNy41IEMxMCw3LjUgOC43MzA0Njg3NSw2LjI1IDguNzMwNDY4NzUsNSBDOC43MzA0Njg3NSw0LjU1MDc4MTI1IDguODY3MTg3NSw0LjEyMTA5Mzc1IDkuMDgyMDMxMjUsMy43NSBMNi40MDYyNSwzLjc1IEM2LjMwODU5Mzc1LDQuMTYwMTU2MjUgNi4yNSw0LjU3MDMxMjUgNi4yNSw1IEM2LjI1LDcuNSA4LjczMDQ2ODc1LDEwIDExLjIzMDQ2ODgsMTAgTDE1LDEwIEMxNy41LDEwIDIwLDcuNSAyMCw1IEMyMCwyLjUgMTcuNSwwIDE1LDAgTDE1LDAgWiBNNS42MDU0Njg3NSw3LjUgTDUuMDE5NTMxMjUsNy41IEMzLjc1LDcuNSAyLjUxOTUzMTI1LDYuMjUgMi41MTk1MzEyNSw1IEMyLjUxOTUzMTI1LDMuNzUgMy43ODkwNjI1LDIuNSA1LjAxOTUzMTI1LDIuNSBMOC43Njk1MzEyNSwyLjUgQzEwLDIuNSAxMS4yNjk1MzEyLDMuNzUgMTEuMjY5NTMxMiw1IEMxMS4yNjk1MzEyLDUuNDQ5MjE4NzUgMTEuMTMyODEyNSw1Ljg3ODkwNjI1IDEwLjkxNzk2ODgsNi4yNSBMMTMuNTkzNzUsNi4yNSBDMTMuNjkxNDA2Miw1LjgzOTg0Mzc1IDEzLjc1LDUuNDI5Njg3NSAxMy43NSw1IEMxMy43NSwyLjUgMTEuMjY5NTMxMiwwIDguNzY5NTMxMjUsMCBMNSwwIEMyLjUsMCAwLDIuNSAwLDUgQzAsNy41IDIuNSwxMCA1LDEwIEw3LjY5NTMxMjUsMTAgQzYuNzU3ODEyNSw5LjM3NSA1Ljg3ODkwNjI1LDguMjYxNzE4NzUgNS42MDU0Njg3NSw3LjUgTDUuNjA1NDY4NzUsNy41IFoiIGlkPSJTaGFwZSI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+") no-repeat; - margin-top: 15px; - height: 16px; - width: 20px; -} - -.examples .example:nth-child(13) .anchorjs-link { - border-color: #FF5231 #FF5231 transparent; - border-width: 15px 7px 6px; - border-style: solid; - margin-top: 10px; - font-size: 22px; - padding-right: 0 !important; -} - -.examples .example:nth-child(14) .anchorjs-link { - margin-left: -1.8em !important; -} - -.examples .example:nth-child(15) .anchorjs-link { - display: inline-block; - width: 0.375em; - height: 20px; - margin-left: 0.375em; -} - -/* Hover Examples */ - -.hover-examples .example:nth-child(2) *:hover > .anchorjs-link, -.hover-examples .example:nth-child(2) .anchorjs-link:focus { - transition: color .25s linear; -} -.hover-examples .example:nth-child(2) .anchorjs-link:hover { - color: #2500AD; -} - -.hover-examples .example:nth-child(3) .anchorjs-link { - transition: all .25s linear; -} -.hover-examples .example:nth-child(3) *:hover > .anchorjs-link, -.hover-examples .example:nth-child(3) .anchorjs-link:focus { - margin-left: -1.125em !important; -} - - -.hover-examples .example:nth-child(4) h3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} -.hover-examples .example:nth-child(4) .anchorjs-link { - background: #FF5231; - color: white; - font-family: Helvetica, Arial, sans-serif; - font-weight: 200; - font-size: 1rem; - position: relative; - top: 2px; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - margin-right: -6%; - padding-right: 6%; - padding-left: 42px !important; - height: 36px; - line-height: 38px; - -webkit-transition: all 0.5s ease; - transition: all 0.5s ease; - -webkit-transform: translateX(100%); - -ms-transform: translateX(100%); - transform: translateX(100%); -} -.hover-examples .example:nth-child(4) .anchorjs-link::before { - position: absolute; - left: 0; - display: block; - width: 0; - height: 0; - border: 18px solid #fff; - border-right-color: #FF5231; - content: ''; - transition: all 0.5s ease; -} -.hover-examples .example:nth-child(4) *:hover > .anchorjs-link, -.hover-examples .example:nth-child(4) .anchorjs-link:focus { - -webkit-transform: translateX(0); - -ms-transform: translateX(0); - - transform: translateX(0); -} -.hover-examples .example:nth-child(4) *:hover > .anchorjs-link:hover, -.hover-examples .example:nth-child(4) .anchorjs-link:focus { - background: #FF806A; -} -.hover-examples .example:nth-child(4) *:hover > .anchorjs-link:hover::before, -.hover-examples .example:nth-child(4) .anchorjs-link:focus { - border-right-color: #FF806A; -} - -.hover-examples .example:nth-child(5) .anchorjs-link:after { - display: inline-block; - transition: opacity .25s linear; - font-family: Verdana, sans-serif; - font-size: 0.75ex; - font-weight: 100; - padding: 0.5ex 1.5ex; - background: #444; - color: #fff; - border-radius: 0.6ex; - vertical-align: 0.8ex; -} -.hover-examples .example:nth-child(5) .anchorjs-link:before { - content: ''; - display: inline-block; - border-top: 0.3ex solid transparent; - border-right: 0.5ex solid #444; - border-bottom: 0.3ex solid transparent; - vertical-align: 0.35ex; -} -.hover-examples .example:nth-child(5) .anchorjs-link:hover:after { - background-color: #666; -} -.hover-examples .example:nth-child(5) .anchorjs-link:hover:before { - border-right-color: #666; -} - -/*////// Utilities ////////*/ -/* Clearfix */ -.group:after { - content: ""; - display: table; - clear: both; -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.bower.json b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.bower.json deleted file mode 100644 index 1eb20d813b..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.bower.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "bootstrap-toc", - "homepage": "https://github.com/afeld/bootstrap-toc", - "version": "0.4.1", - "_release": "0.4.1", - "_resolution": { - "type": "version", - "tag": "v0.4.1", - "commit": "a46628385301df48d2a0d813b2a7f529a074662b" - }, - "_source": "https://github.com/afeld/bootstrap-toc.git", - "_target": "0.4.1", - "_originalSource": "bootstrap-toc" -} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.gitignore b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.gitignore deleted file mode 100644 index f97854ca14..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -_site/ -node_modules/ -Gemfile.lock -*.sw? diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.travis.yml b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.travis.yml deleted file mode 100644 index 218810bac7..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -sudo: false -language: node_js -node_js: - - "5.1" -branches: - only: - - /.*/ -cache: - directories: - - node_modules diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/Gemfile b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/Gemfile deleted file mode 100644 index f1b369d2ef..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gem 'github-pages', group: :jekyll_plugins diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/LICENSE.md b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/LICENSE.md deleted file mode 100644 index 0346635160..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/LICENSE.md +++ /dev/null @@ -1,25 +0,0 @@ -The MIT License (MIT) -===================== - -Copyright © 2015 Aidan Feldman - -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. diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_config.yml b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_config.yml deleted file mode 100644 index d089191136..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_config.yml +++ /dev/null @@ -1,6 +0,0 @@ -baseurl: /bootstrap-toc -markdown: kramdown -kramdown: - input: GFM -exclude: - - node_modules/ diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/default.html b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/default.html deleted file mode 100644 index 3c71fdf875..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/default.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - Table of Contents plugin for Bootstrap - - - - - - - - - - - - - - -
    -
    -
    - -
    -
    - {{ content }} -
    - - -
    -
    -
    -
    - - diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/test.html b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/test.html deleted file mode 100644 index c6551588b8..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/_layouts/test.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: default ---- - - -{{ content }} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/assets/screen.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/assets/screen.css deleted file mode 100644 index 8aba2dc682..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/assets/screen.css +++ /dev/null @@ -1,54 +0,0 @@ -.right .github-fork-ribbon { - background-color: #563d7c; -} - -.container { - max-width: 800px; - padding-top: 40px; - padding-bottom: 40px; -} - -.hint { - color: #563d7c; - display: inline-block; - font-weight: bold; - left: 20px; /* match the left margin of the top-level nav items */ - position: relative; - top: 0.5em; -} -.hint:before { - content: '↑'; - display: block; - font-size: 3em; - margin-bottom: 5px; - text-align: center; -} - -footer { - margin-top: 50px; - text-align: center; -} - -/* small screens */ -@media (max-width: 768px) { - /* override the Affix plugin so that the navigation isn't sticky */ - nav.affix[data-toggle='toc'] { - position: static; - } - - /* display the second-level nav */ - nav[data-toggle='toc'] .nav .nav { - display: block; - } - - .hint { - top: 0; - } -} - -/* large screens */ -@media (min-width: 768px) { - h1:first-child { - margin-top: 0; - } -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.css deleted file mode 100644 index fe0934e71b..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.css +++ /dev/null @@ -1,58 +0,0 @@ -/*! - * Bootstrap Table of Contents v<%= version %> (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ - -/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ - -/* All levels of nav */ -nav[data-toggle='toc'] .nav > li > a { - display: block; - padding: 4px 20px; - font-size: 13px; - font-weight: 500; - color: #767676; -} -nav[data-toggle='toc'] .nav > li > a:hover, -nav[data-toggle='toc'] .nav > li > a:focus { - padding-left: 19px; - color: #563d7c; - text-decoration: none; - background-color: transparent; - border-left: 1px solid #563d7c; -} -nav[data-toggle='toc'] .nav > .active > a, -nav[data-toggle='toc'] .nav > .active:hover > a, -nav[data-toggle='toc'] .nav > .active:focus > a { - padding-left: 18px; - font-weight: bold; - color: #563d7c; - background-color: transparent; - border-left: 2px solid #563d7c; -} - -/* Nav: second level (shown on .active) */ -nav[data-toggle='toc'] .nav .nav { -} -nav[data-toggle='toc'] .nav .nav > li > a { - padding-top: 4px; - padding-bottom: 4px; - padding-left: 40px; - font-size: 11px; - font-weight: normal; -} -nav[data-toggle='toc'] .nav .nav > li > a:hover, -nav[data-toggle='toc'] .nav .nav > li > a:focus { - padding-left: 39px; -} -nav[data-toggle='toc'] .nav .nav > .active > a, -nav[data-toggle='toc'] .nav .nav > .active:hover > a, -nav[data-toggle='toc'] .nav .nav > .active:focus > a { - padding-left: 28px; - font-weight: 500; -} - -/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ -nav[data-toggle='toc'] .nav > .active > ul { - display: block; -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.js deleted file mode 100644 index 9311722b3c..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/bootstrap-toc.js +++ /dev/null @@ -1,159 +0,0 @@ -/*! - * Bootstrap Table of Contents v<%= version %> (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ -(function() { - 'use strict'; - - window.Toc = { - helpers: { - // return all matching elements in the set, or their descendants - findOrFilter: function($el, selector) { - // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ - // http://stackoverflow.com/a/12731439/358804 - var $descendants = $el.find(selector); - return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); - }, - - generateUniqueIdBase: function(el) { - var text = $(el).text(); - var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); - return anchor || el.tagName.toLowerCase(); - }, - - generateUniqueId: function(el) { - var anchorBase = this.generateUniqueIdBase(el); - for (var i = 0; ; i++) { - var anchor = anchorBase; - if (i > 0) { - // add suffix - anchor += '-' + i; - } - // check if ID already exists - if (!document.getElementById(anchor)) { - return anchor; - } - } - }, - - generateAnchor: function(el) { - if (el.id) { - return el.id; - } else { - var anchor = this.generateUniqueId(el); - el.id = anchor; - return anchor; - } - }, - - createNavList: function() { - return $(''); - }, - - createChildNavList: function($parent) { - var $childList = this.createNavList(); - $parent.append($childList); - return $childList; - }, - - generateNavEl: function(anchor, text) { - var $a = $(''); - $a.attr('href', '#' + anchor); - $a.text(text); - var $li = $('
  • '); - $li.append($a); - return $li; - }, - - generateNavItem: function(headingEl) { - var anchor = this.generateAnchor(headingEl); - var $heading = $(headingEl); - var text = $heading.data('toc-text') || $heading.text(); - return this.generateNavEl(anchor, text); - }, - - // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). - getTopLevel: function($scope) { - for (var i = 1; i <= 6; i++) { - var $headings = this.findOrFilter($scope, 'h' + i); - if ($headings.length > 1) { - return i; - } - } - - return 1; - }, - - // returns the elements for the top level, and the next below it - getHeadings: function($scope, topLevel) { - var topSelector = 'h' + topLevel; - - var secondaryLevel = topLevel + 1; - var secondarySelector = 'h' + secondaryLevel; - - return this.findOrFilter($scope, topSelector + ',' + secondarySelector); - }, - - getNavLevel: function(el) { - return parseInt(el.tagName.charAt(1), 10); - }, - - populateNav: function($topContext, topLevel, $headings) { - var $context = $topContext; - var $prevNav; - - var helpers = this; - $headings.each(function(i, el) { - var $newNav = helpers.generateNavItem(el); - var navLevel = helpers.getNavLevel(el); - - // determine the proper $context - if (navLevel === topLevel) { - // use top level - $context = $topContext; - } else if ($prevNav && $context === $topContext) { - // create a new level of the tree and switch to it - $context = helpers.createChildNavList($prevNav); - } // else use the current $context - - $context.append($newNav); - - $prevNav = $newNav; - }); - }, - - parseOps: function(arg) { - var opts; - if (arg.jquery) { - opts = { - $nav: arg - }; - } else { - opts = arg; - } - opts.$scope = opts.$scope || $(document.body); - return opts; - } - }, - - // accepts a jQuery object, or an options object - init: function(opts) { - opts = this.helpers.parseOps(opts); - - // ensure that the data attribute is in place for styling - opts.$nav.attr('data-toggle', 'toc'); - - var $topContext = this.helpers.createChildNavList(opts.$nav); - var topLevel = this.helpers.getTopLevel(opts.$scope); - var $headings = this.helpers.getHeadings(opts.$scope, topLevel); - this.helpers.populateNav($topContext, topLevel, $headings); - } - }; - - $(function() { - $('nav[data-toggle="toc"]').each(function(i, el) { - var $nav = $(el); - Toc.init($nav); - }); - }); -})(); diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.css deleted file mode 100644 index 5a859415c1..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.css +++ /dev/null @@ -1,60 +0,0 @@ -/*! - * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ - -/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ - -/* All levels of nav */ -nav[data-toggle='toc'] .nav > li > a { - display: block; - padding: 4px 20px; - font-size: 13px; - font-weight: 500; - color: #767676; -} -nav[data-toggle='toc'] .nav > li > a:hover, -nav[data-toggle='toc'] .nav > li > a:focus { - padding-left: 19px; - color: #563d7c; - text-decoration: none; - background-color: transparent; - border-left: 1px solid #563d7c; -} -nav[data-toggle='toc'] .nav > .active > a, -nav[data-toggle='toc'] .nav > .active:hover > a, -nav[data-toggle='toc'] .nav > .active:focus > a { - padding-left: 18px; - font-weight: bold; - color: #563d7c; - background-color: transparent; - border-left: 2px solid #563d7c; -} - -/* Nav: second level (shown on .active) */ -nav[data-toggle='toc'] .nav .nav { - display: none; /* Hide by default, but at >768px, show it */ - padding-bottom: 10px; -} -nav[data-toggle='toc'] .nav .nav > li > a { - padding-top: 1px; - padding-bottom: 1px; - padding-left: 30px; - font-size: 12px; - font-weight: normal; -} -nav[data-toggle='toc'] .nav .nav > li > a:hover, -nav[data-toggle='toc'] .nav .nav > li > a:focus { - padding-left: 29px; -} -nav[data-toggle='toc'] .nav .nav > .active > a, -nav[data-toggle='toc'] .nav .nav > .active:hover > a, -nav[data-toggle='toc'] .nav .nav > .active:focus > a { - padding-left: 28px; - font-weight: 500; -} - -/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ -nav[data-toggle='toc'] .nav > .active > ul { - display: block; -} diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.js deleted file mode 100644 index 1cdd573b20..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.js +++ /dev/null @@ -1,159 +0,0 @@ -/*! - * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ -(function() { - 'use strict'; - - window.Toc = { - helpers: { - // return all matching elements in the set, or their descendants - findOrFilter: function($el, selector) { - // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ - // http://stackoverflow.com/a/12731439/358804 - var $descendants = $el.find(selector); - return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); - }, - - generateUniqueIdBase: function(el) { - var text = $(el).text(); - var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); - return anchor || el.tagName.toLowerCase(); - }, - - generateUniqueId: function(el) { - var anchorBase = this.generateUniqueIdBase(el); - for (var i = 0; ; i++) { - var anchor = anchorBase; - if (i > 0) { - // add suffix - anchor += '-' + i; - } - // check if ID already exists - if (!document.getElementById(anchor)) { - return anchor; - } - } - }, - - generateAnchor: function(el) { - if (el.id) { - return el.id; - } else { - var anchor = this.generateUniqueId(el); - el.id = anchor; - return anchor; - } - }, - - createNavList: function() { - return $(''); - }, - - createChildNavList: function($parent) { - var $childList = this.createNavList(); - $parent.append($childList); - return $childList; - }, - - generateNavEl: function(anchor, text) { - var $a = $(''); - $a.attr('href', '#' + anchor); - $a.text(text); - var $li = $('
  • '); - $li.append($a); - return $li; - }, - - generateNavItem: function(headingEl) { - var anchor = this.generateAnchor(headingEl); - var $heading = $(headingEl); - var text = $heading.data('toc-text') || $heading.text(); - return this.generateNavEl(anchor, text); - }, - - // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). - getTopLevel: function($scope) { - for (var i = 1; i <= 6; i++) { - var $headings = this.findOrFilter($scope, 'h' + i); - if ($headings.length > 1) { - return i; - } - } - - return 1; - }, - - // returns the elements for the top level, and the next below it - getHeadings: function($scope, topLevel) { - var topSelector = 'h' + topLevel; - - var secondaryLevel = topLevel + 1; - var secondarySelector = 'h' + secondaryLevel; - - return this.findOrFilter($scope, topSelector + ',' + secondarySelector); - }, - - getNavLevel: function(el) { - return parseInt(el.tagName.charAt(1), 10); - }, - - populateNav: function($topContext, topLevel, $headings) { - var $context = $topContext; - var $prevNav; - - var helpers = this; - $headings.each(function(i, el) { - var $newNav = helpers.generateNavItem(el); - var navLevel = helpers.getNavLevel(el); - - // determine the proper $context - if (navLevel === topLevel) { - // use top level - $context = $topContext; - } else if ($prevNav && $context === $topContext) { - // create a new level of the tree and switch to it - $context = helpers.createChildNavList($prevNav); - } // else use the current $context - - $context.append($newNav); - - $prevNav = $newNav; - }); - }, - - parseOps: function(arg) { - var opts; - if (arg.jquery) { - opts = { - $nav: arg - }; - } else { - opts = arg; - } - opts.$scope = opts.$scope || $(document.body); - return opts; - } - }, - - // accepts a jQuery object, or an options object - init: function(opts) { - opts = this.helpers.parseOps(opts); - - // ensure that the data attribute is in place for styling - opts.$nav.attr('data-toggle', 'toc'); - - var $topContext = this.helpers.createChildNavList(opts.$nav); - var topLevel = this.helpers.getTopLevel(opts.$scope); - var $headings = this.helpers.getHeadings(opts.$scope, topLevel); - this.helpers.populateNav($topContext, topLevel, $headings); - } - }; - - $(function() { - $('nav[data-toggle="toc"]').each(function(i, el) { - var $nav = $(el); - Toc.init($nav); - }); - }); -})(); diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.css b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.css deleted file mode 100644 index 2d36ad199e..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */nav[data-toggle=toc] .nav>li>a{display:block;padding:4px 20px;font-size:13px;font-weight:500;color:#767676}nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{padding-left:19px;color:#563d7c;text-decoration:none;background-color:transparent;border-left:1px solid #563d7c}nav[data-toggle=toc] .nav>.active:focus>a,nav[data-toggle=toc] .nav>.active:hover>a,nav[data-toggle=toc] .nav>.active>a{padding-left:18px;font-weight:700;color:#563d7c;background-color:transparent;border-left:2px solid #563d7c}nav[data-toggle=toc] .nav .nav{display:none;padding-bottom:10px}nav[data-toggle=toc] .nav .nav>li>a{padding-top:1px;padding-bottom:1px;padding-left:30px;font-size:12px;font-weight:400}nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{padding-left:29px}nav[data-toggle=toc] .nav .nav>.active:focus>a,nav[data-toggle=toc] .nav .nav>.active:hover>a,nav[data-toggle=toc] .nav .nav>.active>a{padding-left:28px;font-weight:500}nav[data-toggle=toc] .nav>.active>ul{display:block} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.js deleted file mode 100644 index 35bae96628..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/dist/bootstrap-toc.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) - * Copyright 2015 Aidan Feldman - * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ -!function(){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var r=e.find(t);return e.filter(t).add(r).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){var t=$(e).text(),r=t.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g,"-");return r||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),r=0;;r++){var n=t;if(r>0&&(n+="-"+r),!document.getElementById(n))return n}},generateAnchor:function(e){if(e.id)return e.id;var t=this.generateUniqueId(e);return e.id=t,t},createNavList:function(){return $('')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var r=$("");r.attr("href","#"+e),r.text(t);var n=$("
  • ");return n.append(r),n},generateNavItem:function(e){var t=this.generateAnchor(e),r=$(e),n=r.data("toc-text")||r.text();return this.generateNavEl(t,n)},getTopLevel:function(e){for(var t=1;t<=6;t++){var r=this.findOrFilter(e,"h"+t);if(r.length>1)return t}return 1},getHeadings:function(e,t){var r="h"+t,n=t+1,a="h"+n;return this.findOrFilter(e,r+","+a)},getNavLevel:function(e){return parseInt(e.tagName.charAt(1),10)},populateNav:function(e,t,r){var n,a=e,i=this;r.each(function(r,o){var s=i.generateNavItem(o),u=i.getNavLevel(o);u===t?a=e:n&&a===e&&(a=i.createChildNavList(n)),a.append(s),n=s})},parseOps:function(e){var t;return t=e.jquery?{$nav:e}:e,t.$scope=t.$scope||$(document.body),t}},init:function(e){e=this.helpers.parseOps(e),e.$nav.attr("data-toggle","toc");var t=this.helpers.createChildNavList(e.$nav),r=this.helpers.getTopLevel(e.$scope),n=this.helpers.getHeadings(e.$scope,r);this.helpers.populateNav(t,r,n)}},$(function(){$('nav[data-toggle="toc"]').each(function(e,t){var r=$(t);Toc.init(r)})})}(); \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/gulpfile.js b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/gulpfile.js deleted file mode 100644 index 7cc796409f..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/gulpfile.js +++ /dev/null @@ -1,58 +0,0 @@ -var gulp = require('gulp'); -var del = require('del'); -var template = require('gulp-template'); -var minifyCss = require('gulp-minify-css'); -var rename = require('gulp-rename'); -var uglify = require('gulp-uglify'); -var jshint = require('gulp-jshint'); -var mochaPhantomJS = require('gulp-mocha-phantomjs'); -var pkg = require('./package.json'); - -gulp.task('clean', function () { - return del(['dist/*']); -}); - -gulp.task('build-css', ['clean'], function() { - return gulp.src('bootstrap-toc.css') - .pipe(template(pkg)) - .pipe(gulp.dest('dist')) - .pipe(minifyCss({compatibility: 'ie8'})) - .pipe(rename({ - extname: '.min.css' - })) - .pipe(gulp.dest('dist')); -}); - -gulp.task('build-js', ['clean'], function() { - return gulp.src('bootstrap-toc.js') - .pipe(template(pkg)) - .pipe(gulp.dest('dist')) - .pipe(uglify({ - preserveComments: 'license' - })) - .pipe(rename({ - extname: '.min.js' - })) - .pipe(gulp.dest('dist')); -}); - -gulp.task('js-lint', function () { - return gulp.src('bootstrap-toc.js') - .pipe(jshint()) - .pipe(jshint.reporter('default')) - .pipe(jshint.reporter('fail')); -}); - -gulp.task('test', function () { - return gulp.src('test/index.html') - .pipe(mochaPhantomJS()); -}); - -gulp.task('watch', function() { - gulp.watch('bootstrap-toc.js', ['js-lint', 'test']); - gulp.watch('test/*', ['test']); -}); - -gulp.task('build', ['build-css', 'build-js']); - -gulp.task('default', ['build', 'js-lint', 'test']); diff --git a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/index.md b/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/index.md deleted file mode 100644 index 453025d192..0000000000 --- a/modules/docs/src/Volo.Docs.Web/wwwroot/lib/bootstrap-toc/index.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -layout: default -permalink: / ---- - -# Table of Contents plugin for Bootstrap -{: .page-header} - -[![Build Status](https://travis-ci.org/afeld/bootstrap-toc.svg?branch=gh-pages)](https://travis-ci.org/afeld/bootstrap-toc) - -This [Bootstrap](http://getbootstrap.com/) plugin allows you to generate a table of contents for any page, based on the heading elements (`

    `, `

    `, etc.). It is meant to emulate the sidebar you see on [the Bootstrap documentation site](http://getbootstrap.com/css/). - -This page is an example of the plugin in action – the table of contents you see on the left (or top, on mobile) was automatically generated, without having to manually keep all of the navigation items in sync with the headings. - -## Usage - -On top of the normal Bootstrap setup (see their [Getting Started](http://getbootstrap.com/getting-started/) guide), you will need to include the Bootstrap Table of Contents stylesheet and JavaScript file. - -```html - - - - -``` - -[Unminified versions](https://github.com/afeld/bootstrap-toc/tree/gh-pages/dist) are also available. - -Next, pick one of the two options below. - -### Via data attributes - -*Simplest.* - -Create a `