feat: add ToolbarScope parameter to editors for scoped toolbar contributions
- Introduce a new ToolbarScope parameter in SbMarkdownEditor, SbMarkEditor, and SbRichTextEditor to filter toolbar contributors based on context. - Update related services and interfaces to support scoped contributions, enhancing the flexibility of toolbar item management. - Add disposal handling in SbSelectOption to unregister options properly. - Implement CSS coverage fixes for various components to ensure consistent styling across the application.
This commit is contained in:
@@ -13,5 +13,6 @@
|
|||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<NoWarn>$(NoWarn);CS8601;CS8602;CS8603;CS8604;CS8613;CS8618;CS8619;CS8620;CS8625;CS8629;CS8632;CS8669;CS8609;CS8767</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
SourceLanguage="@ResolveSourceLanguage()"
|
SourceLanguage="@ResolveSourceLanguage()"
|
||||||
UseToolbarContributors="@UseToolbarContributors"
|
UseToolbarContributors="@UseToolbarContributors"
|
||||||
IncludeDefaultToolbarItems="@IncludeDefaultToolbarItems"
|
IncludeDefaultToolbarItems="@IncludeDefaultToolbarItems"
|
||||||
|
ToolbarScope="@ToolbarScope"
|
||||||
HideToolbar="@HideToolbar"
|
HideToolbar="@HideToolbar"
|
||||||
ToolbarItems="@ToolbarItems"
|
ToolbarItems="@ToolbarItems"
|
||||||
OnShortcut="@OnShortcut"
|
OnShortcut="@OnShortcut"
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ public partial class SbMarkEditor
|
|||||||
[Parameter] public string? SourceLanguage { get; set; }
|
[Parameter] public string? SourceLanguage { get; set; }
|
||||||
[Parameter] public bool UseToolbarContributors { get; set; }
|
[Parameter] public bool UseToolbarContributors { get; set; }
|
||||||
[Parameter] public bool IncludeDefaultToolbarItems { get; set; } = true;
|
[Parameter] public bool IncludeDefaultToolbarItems { get; set; } = true;
|
||||||
|
/// <summary>
|
||||||
|
/// Optional toolbar scope forwarded to <see cref="SbMarkdownEditor"/> to
|
||||||
|
/// filter which registered <see cref="IMdToolbarContributor"/> instances run.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter] public string? ToolbarScope { get; set; }
|
||||||
[Parameter] public bool HideToolbar { get; set; }
|
[Parameter] public bool HideToolbar { get; set; }
|
||||||
[Parameter] public IReadOnlyList<SbMarkdownToolbarItem>? ToolbarItems { get; set; }
|
[Parameter] public IReadOnlyList<SbMarkdownToolbarItem>? ToolbarItems { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnShortcut { get; set; }
|
[Parameter] public EventCallback<string> OnShortcut { get; set; }
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
[Parameter] public string? SourceLanguage { get; set; }
|
[Parameter] public string? SourceLanguage { get; set; }
|
||||||
[Parameter] public bool UseToolbarContributors { get; set; }
|
[Parameter] public bool UseToolbarContributors { get; set; }
|
||||||
[Parameter] public bool IncludeDefaultToolbarItems { get; set; } = true;
|
[Parameter] public bool IncludeDefaultToolbarItems { get; set; } = true;
|
||||||
|
/// <summary>
|
||||||
|
/// Optional toolbar scope that filters which <see cref="IMdToolbarContributor"/>
|
||||||
|
/// instances run for this editor. Contributors whose <c>Scope</c> is non-null
|
||||||
|
/// only execute when it matches this value. Contributors with a null scope
|
||||||
|
/// always run. This prevents page-specific toolbar items from leaking across
|
||||||
|
/// navigations within the same Blazor circuit.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter] public string? ToolbarScope { get; set; }
|
||||||
[Parameter] public bool HideToolbar { get; set; }
|
[Parameter] public bool HideToolbar { get; set; }
|
||||||
[Parameter] public IReadOnlyList<SbMarkdownToolbarItem>? ToolbarItems { get; set; }
|
[Parameter] public IReadOnlyList<SbMarkdownToolbarItem>? ToolbarItems { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnShortcut { get; set; }
|
[Parameter] public EventCallback<string> OnShortcut { get; set; }
|
||||||
@@ -56,6 +64,7 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
private SbMarkdownEditorMode _lastEditorMode;
|
private SbMarkdownEditorMode _lastEditorMode;
|
||||||
private string? _lastSourceLanguage;
|
private string? _lastSourceLanguage;
|
||||||
private bool _lastIncludeDefaultToolbarItems;
|
private bool _lastIncludeDefaultToolbarItems;
|
||||||
|
private string? _lastToolbarScope;
|
||||||
private List<SbMarkdownToolbarItem> _toolbarItems = new();
|
private List<SbMarkdownToolbarItem> _toolbarItems = new();
|
||||||
private bool _useFallback;
|
private bool _useFallback;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
@@ -88,6 +97,7 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
_lastEditorMode = EditorMode;
|
_lastEditorMode = EditorMode;
|
||||||
_lastSourceLanguage = SourceLanguage;
|
_lastSourceLanguage = SourceLanguage;
|
||||||
_lastIncludeDefaultToolbarItems = IncludeDefaultToolbarItems;
|
_lastIncludeDefaultToolbarItems = IncludeDefaultToolbarItems;
|
||||||
|
_lastToolbarScope = ToolbarScope;
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -115,11 +125,13 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
else if (Value != _lastRenderedValue ||
|
else if (Value != _lastRenderedValue ||
|
||||||
EditorMode != _lastEditorMode ||
|
EditorMode != _lastEditorMode ||
|
||||||
SourceLanguage != _lastSourceLanguage ||
|
SourceLanguage != _lastSourceLanguage ||
|
||||||
IncludeDefaultToolbarItems != _lastIncludeDefaultToolbarItems)
|
IncludeDefaultToolbarItems != _lastIncludeDefaultToolbarItems ||
|
||||||
|
ToolbarScope != _lastToolbarScope)
|
||||||
{
|
{
|
||||||
if (EditorMode != _lastEditorMode ||
|
if (EditorMode != _lastEditorMode ||
|
||||||
SourceLanguage != _lastSourceLanguage ||
|
SourceLanguage != _lastSourceLanguage ||
|
||||||
IncludeDefaultToolbarItems != _lastIncludeDefaultToolbarItems)
|
IncludeDefaultToolbarItems != _lastIncludeDefaultToolbarItems ||
|
||||||
|
ToolbarScope != _lastToolbarScope)
|
||||||
{
|
{
|
||||||
await ReinitializeEditorAsync();
|
await ReinitializeEditorAsync();
|
||||||
}
|
}
|
||||||
@@ -145,7 +157,8 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
_toolbarItems = await ToolbarService.GetToolbarItemsAsync(
|
_toolbarItems = await ToolbarService.GetToolbarItemsAsync(
|
||||||
editorId,
|
editorId,
|
||||||
includeDefaults: IncludeDefaultToolbarItems,
|
includeDefaults: IncludeDefaultToolbarItems,
|
||||||
includeContributors: true);
|
includeContributors: true,
|
||||||
|
scope: ToolbarScope);
|
||||||
}
|
}
|
||||||
else if (ToolbarItems != null)
|
else if (ToolbarItems != null)
|
||||||
{
|
{
|
||||||
@@ -261,6 +274,7 @@ public partial class SbMarkdownEditor : ComponentBase, IAsyncDisposable
|
|||||||
_lastEditorMode = EditorMode;
|
_lastEditorMode = EditorMode;
|
||||||
_lastSourceLanguage = SourceLanguage;
|
_lastSourceLanguage = SourceLanguage;
|
||||||
_lastIncludeDefaultToolbarItems = IncludeDefaultToolbarItems;
|
_lastIncludeDefaultToolbarItems = IncludeDefaultToolbarItems;
|
||||||
|
_lastToolbarScope = ToolbarScope;
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -382,6 +382,16 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public bool IncludeDefaultToolbarItems { get; set; } = true;
|
public bool IncludeDefaultToolbarItems { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Optional toolbar scope that filters which <see cref="IRteToolbarContributor"/>
|
||||||
|
/// instances run for this editor. Contributors whose <c>Scope</c> is non-null
|
||||||
|
/// only execute when it matches this value. Contributors with a null scope
|
||||||
|
/// always run. This prevents page-specific toolbar items from leaking across
|
||||||
|
/// navigations within the same Blazor circuit.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string? ToolbarScope { get; set; }
|
||||||
|
|
||||||
#region Localization Parameters
|
#region Localization Parameters
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -568,10 +578,11 @@
|
|||||||
// Get contributed items
|
// Get contributed items
|
||||||
_contributedToolbarItems = await _toolbarService.GetToolbarItemsAsync(
|
_contributedToolbarItems = await _toolbarService.GetToolbarItemsAsync(
|
||||||
_editorId,
|
_editorId,
|
||||||
IncludeDefaultToolbarItems);
|
IncludeDefaultToolbarItems,
|
||||||
|
ToolbarScope);
|
||||||
|
|
||||||
// Build a map of contributed items for click handling
|
// Build a map of contributed items for click handling
|
||||||
var contributedItems = await _toolbarService.GetContributedItemsAsync(_editorId);
|
var contributedItems = await _toolbarService.GetContributedItemsAsync(_editorId, ToolbarScope);
|
||||||
_contributedItemsMap = contributedItems
|
_contributedItemsMap = contributedItems
|
||||||
.Where(item => item.OnClickAsync != null)
|
.Where(item => item.OnClickAsync != null)
|
||||||
.ToDictionary(item => item.Id, item => item);
|
.ToDictionary(item => item.Id, item => item);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@namespace SufiChain.SufiBlazor.Components.Forms
|
@namespace SufiChain.SufiBlazor.Components.Forms
|
||||||
@typeparam TValue
|
@typeparam TValue
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
@* This component is used as a child of SbSelect to define options declaratively. *@
|
@* This component is used as a child of SbSelect to define options declaratively. *@
|
||||||
@* It registers itself with the parent SbSelect via cascading parameter. *@
|
@* It registers itself with the parent SbSelect via cascading parameter. *@
|
||||||
@@ -54,4 +55,9 @@
|
|||||||
Disabled = Disabled
|
Disabled = Disabled
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Context?.UnregisterOption(Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,15 +220,36 @@
|
|||||||
|
|
||||||
void ISbSelectOptionContext<TValue>.RegisterOption(SbSelectOptionInfo<TValue> option)
|
void ISbSelectOptionContext<TValue>.RegisterOption(SbSelectOptionInfo<TValue> option)
|
||||||
{
|
{
|
||||||
if (!_options.Any(o => EqualityComparer<TValue>.Default.Equals(o.Value, option.Value)))
|
// Update existing entry in place so Text/ChildContent changes propagate;
|
||||||
|
// otherwise add. We must NOT clear _options here or in OnParametersSet,
|
||||||
|
// because Blazor skips calling OnParametersSet on SbSelectOption children
|
||||||
|
// whose parameters haven't changed, which would leave _options empty and
|
||||||
|
// cause GetDisplayText to fall back to Value.ToString() (e.g. a Guid).
|
||||||
|
var existingIndex = _options.FindIndex(o =>
|
||||||
|
EqualityComparer<TValue>.Default.Equals(o.Value, option.Value));
|
||||||
|
if (existingIndex >= 0)
|
||||||
|
{
|
||||||
|
_options[existingIndex] = option;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_options.Add(option);
|
_options.Add(option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ISbSelectOptionContext<TValue>.UnregisterOption(TValue? value)
|
||||||
|
{
|
||||||
|
var index = _options.FindIndex(o =>
|
||||||
|
EqualityComparer<TValue>.Default.Equals(o.Value, value));
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
_options.RemoveAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_options.Clear();
|
// Intentionally do NOT clear _options here. See RegisterOption note above.
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<SbSelectOptionInfo<TValue>> FilteredOptions
|
private IEnumerable<SbSelectOptionInfo<TValue>> FilteredOptions
|
||||||
|
|||||||
@@ -15,6 +15,15 @@ public interface IMdToolbarContributor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int Order => 100;
|
int Order => 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The toolbar scope this contributor belongs to. When non-null, the
|
||||||
|
/// contributor only runs on editors whose <c>ToolbarScope</c> parameter
|
||||||
|
/// matches this value. When null (default), the contributor runs on every
|
||||||
|
/// editor instance — use this for self-filtering contributors (e.g. ones
|
||||||
|
/// that check a host registration) or for globally-applicable items.
|
||||||
|
/// </summary>
|
||||||
|
string? Scope => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configure the toolbar by adding custom items to the context.
|
/// Configure the toolbar by adding custom items to the context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -30,6 +39,13 @@ public class MdToolbarContext
|
|||||||
public IServiceProvider ServiceProvider { get; }
|
public IServiceProvider ServiceProvider { get; }
|
||||||
public string? EditorId { get; set; }
|
public string? EditorId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scope declared by the editor instance via its <c>ToolbarScope</c>
|
||||||
|
/// parameter. Contributors whose <see cref="IMdToolbarContributor.Scope"/>
|
||||||
|
/// is non-null only run when this value matches.
|
||||||
|
/// </summary>
|
||||||
|
public string? Scope { get; set; }
|
||||||
|
|
||||||
public MdToolbarContext(IServiceProvider serviceProvider)
|
public MdToolbarContext(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
ServiceProvider = serviceProvider;
|
ServiceProvider = serviceProvider;
|
||||||
|
|||||||
@@ -16,6 +16,15 @@ public interface IRteToolbarContributor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int Order => 100;
|
int Order => 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The toolbar scope this contributor belongs to. When non-null, the
|
||||||
|
/// contributor only runs on editors whose <c>ToolbarScope</c> parameter
|
||||||
|
/// matches this value. When null (default), the contributor runs on every
|
||||||
|
/// editor instance — use this for self-filtering contributors or for
|
||||||
|
/// globally-applicable items (e.g. culture-aware font selectors).
|
||||||
|
/// </summary>
|
||||||
|
string? Scope => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configure the toolbar by adding custom items to the context.
|
/// Configure the toolbar by adding custom items to the context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -43,6 +52,13 @@ public class RteToolbarContext
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string? EditorId { get; set; }
|
public string? EditorId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The scope declared by the editor instance via its <c>ToolbarScope</c>
|
||||||
|
/// parameter. Contributors whose <see cref="IRteToolbarContributor.Scope"/>
|
||||||
|
/// is non-null only run when this value matches.
|
||||||
|
/// </summary>
|
||||||
|
public string? Scope { get; set; }
|
||||||
|
|
||||||
public RteToolbarContext(IServiceProvider serviceProvider)
|
public RteToolbarContext(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
ServiceProvider = serviceProvider;
|
ServiceProvider = serviceProvider;
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ public class MdToolbarService : IMdToolbarService
|
|||||||
public async Task<List<SbMarkdownToolbarItem>> GetToolbarItemsAsync(
|
public async Task<List<SbMarkdownToolbarItem>> GetToolbarItemsAsync(
|
||||||
string? editorId = null,
|
string? editorId = null,
|
||||||
bool? includeDefaults = null,
|
bool? includeDefaults = null,
|
||||||
bool includeContributors = true)
|
bool includeContributors = true,
|
||||||
|
string? scope = null)
|
||||||
{
|
{
|
||||||
var shouldIncludeDefaults = includeDefaults ?? _options.IncludeDefaultItems;
|
var shouldIncludeDefaults = includeDefaults ?? _options.IncludeDefaultItems;
|
||||||
var allItems = new List<MdToolbarContributedItem>();
|
var allItems = new List<MdToolbarContributedItem>();
|
||||||
@@ -36,8 +37,12 @@ public class MdToolbarService : IMdToolbarService
|
|||||||
|
|
||||||
if (includeContributors)
|
if (includeContributors)
|
||||||
{
|
{
|
||||||
var context = new MdToolbarContext(_serviceProvider) { EditorId = editorId };
|
var context = new MdToolbarContext(_serviceProvider)
|
||||||
foreach (var contributor in GetContributors().OrderBy(c => c.Order))
|
{
|
||||||
|
EditorId = editorId,
|
||||||
|
Scope = scope
|
||||||
|
};
|
||||||
|
foreach (var contributor in GetContributors(scope).OrderBy(c => c.Order))
|
||||||
{
|
{
|
||||||
await contributor.ConfigureToolbarAsync(context);
|
await contributor.ConfigureToolbarAsync(context);
|
||||||
}
|
}
|
||||||
@@ -80,11 +85,12 @@ public class MdToolbarService : IMdToolbarService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IMdToolbarContributor> GetContributors()
|
private IEnumerable<IMdToolbarContributor> GetContributors(string? scope)
|
||||||
{
|
{
|
||||||
foreach (var contributorType in _options.Contributors)
|
foreach (var contributorType in _options.Contributors)
|
||||||
{
|
{
|
||||||
if (_serviceProvider.GetService(contributorType) is IMdToolbarContributor contributor)
|
if (_serviceProvider.GetService(contributorType) is IMdToolbarContributor contributor
|
||||||
|
&& (contributor.Scope == null || string.Equals(contributor.Scope, scope, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
yield return contributor;
|
yield return contributor;
|
||||||
}
|
}
|
||||||
@@ -122,6 +128,7 @@ public interface IMdToolbarService
|
|||||||
Task<List<SbMarkdownToolbarItem>> GetToolbarItemsAsync(
|
Task<List<SbMarkdownToolbarItem>> GetToolbarItemsAsync(
|
||||||
string? editorId = null,
|
string? editorId = null,
|
||||||
bool? includeDefaults = null,
|
bool? includeDefaults = null,
|
||||||
bool includeContributors = true);
|
bool includeContributors = true,
|
||||||
|
string? scope = null);
|
||||||
Task ExecuteItemActionAsync(MdToolbarContributedItem item, MdToolbarActionContext actionContext);
|
Task ExecuteItemActionAsync(MdToolbarContributedItem item, MdToolbarActionContext actionContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,11 @@ public class RteToolbarService : IRteToolbarService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="editorId">The editor instance ID.</param>
|
/// <param name="editorId">The editor instance ID.</param>
|
||||||
/// <param name="includeDefaults">Whether to include default toolbar items.</param>
|
/// <param name="includeDefaults">Whether to include default toolbar items.</param>
|
||||||
|
/// <param name="scope">Optional toolbar scope that filters which contributors run.</param>
|
||||||
public async Task<List<SbEditorToolbarItem>> GetToolbarItemsAsync(
|
public async Task<List<SbEditorToolbarItem>> GetToolbarItemsAsync(
|
||||||
string? editorId = null,
|
string? editorId = null,
|
||||||
bool? includeDefaults = null)
|
bool? includeDefaults = null,
|
||||||
|
string? scope = null)
|
||||||
{
|
{
|
||||||
var shouldIncludeDefaults = includeDefaults ?? _options.IncludeDefaultItems;
|
var shouldIncludeDefaults = includeDefaults ?? _options.IncludeDefaultItems;
|
||||||
var allItems = new List<RteToolbarContributedItem>();
|
var allItems = new List<RteToolbarContributedItem>();
|
||||||
@@ -42,9 +44,13 @@ public class RteToolbarService : IRteToolbarService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get contributed items from all registered contributors
|
// Get contributed items from all registered contributors
|
||||||
var context = new RteToolbarContext(_serviceProvider) { EditorId = editorId };
|
var context = new RteToolbarContext(_serviceProvider)
|
||||||
|
{
|
||||||
|
EditorId = editorId,
|
||||||
|
Scope = scope
|
||||||
|
};
|
||||||
|
|
||||||
var contributors = GetContributors();
|
var contributors = GetContributors(scope);
|
||||||
foreach (var contributor in contributors.OrderBy(c => c.Order))
|
foreach (var contributor in contributors.OrderBy(c => c.Order))
|
||||||
{
|
{
|
||||||
await contributor.ConfigureToolbarAsync(context);
|
await contributor.ConfigureToolbarAsync(context);
|
||||||
@@ -84,11 +90,17 @@ public class RteToolbarService : IRteToolbarService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the contributed items only (without defaults).
|
/// Get the contributed items only (without defaults).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<List<RteToolbarContributedItem>> GetContributedItemsAsync(string? editorId = null)
|
public async Task<List<RteToolbarContributedItem>> GetContributedItemsAsync(
|
||||||
|
string? editorId = null,
|
||||||
|
string? scope = null)
|
||||||
{
|
{
|
||||||
var context = new RteToolbarContext(_serviceProvider) { EditorId = editorId };
|
var context = new RteToolbarContext(_serviceProvider)
|
||||||
|
{
|
||||||
|
EditorId = editorId,
|
||||||
|
Scope = scope
|
||||||
|
};
|
||||||
|
|
||||||
var contributors = GetContributors();
|
var contributors = GetContributors(scope);
|
||||||
foreach (var contributor in contributors.OrderBy(c => c.Order))
|
foreach (var contributor in contributors.OrderBy(c => c.Order))
|
||||||
{
|
{
|
||||||
await contributor.ConfigureToolbarAsync(context);
|
await contributor.ConfigureToolbarAsync(context);
|
||||||
@@ -110,12 +122,13 @@ public class RteToolbarService : IRteToolbarService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IRteToolbarContributor> GetContributors()
|
private IEnumerable<IRteToolbarContributor> GetContributors(string? scope)
|
||||||
{
|
{
|
||||||
foreach (var contributorType in _options.Contributors)
|
foreach (var contributorType in _options.Contributors)
|
||||||
{
|
{
|
||||||
var contributor = _serviceProvider.GetService(contributorType) as IRteToolbarContributor;
|
var contributor = _serviceProvider.GetService(contributorType) as IRteToolbarContributor;
|
||||||
if (contributor != null)
|
if (contributor != null
|
||||||
|
&& (contributor.Scope == null || string.Equals(contributor.Scope, scope, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
yield return contributor;
|
yield return contributor;
|
||||||
}
|
}
|
||||||
@@ -201,12 +214,17 @@ public interface IRteToolbarService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get all toolbar items including default and contributed items.
|
/// Get all toolbar items including default and contributed items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<List<SbEditorToolbarItem>> GetToolbarItemsAsync(string? editorId = null, bool? includeDefaults = null);
|
Task<List<SbEditorToolbarItem>> GetToolbarItemsAsync(
|
||||||
|
string? editorId = null,
|
||||||
|
bool? includeDefaults = null,
|
||||||
|
string? scope = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the contributed items only (without defaults).
|
/// Get the contributed items only (without defaults).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<List<RteToolbarContributedItem>> GetContributedItemsAsync(string? editorId = null);
|
Task<List<RteToolbarContributedItem>> GetContributedItemsAsync(
|
||||||
|
string? editorId = null,
|
||||||
|
string? scope = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Execute a contributed toolbar item's click handler.
|
/// Execute a contributed toolbar item's click handler.
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ internal interface ISbSelectOptionContext<TValue>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="option">The option information to register.</param>
|
/// <param name="option">The option information to register.</param>
|
||||||
void RegisterOption(SbSelectOptionInfo<TValue> option);
|
void RegisterOption(SbSelectOptionInfo<TValue> option);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a previously registered option (e.g. when its SbSelectOption is disposed).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value of the option to unregister.</param>
|
||||||
|
void UnregisterOption(TValue? value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
<!-- Generate XML documentation -->
|
<!-- Generate XML documentation -->
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user