Route open providers by request mode
This commit is contained in:
parent
f87f8235bd
commit
fb68c54409
|
|
@ -97,8 +97,8 @@ Frontend bundles are mounted with a plugin-scoped API created by
|
|||
a concrete editor plugin.
|
||||
|
||||
Editor/viewer plugins contribute providers with `contributes.openProviders`.
|
||||
Workbench selects by resource kind, extension/mime, context (`generic-text`,
|
||||
`generic-markdown`, `notes-markdown`), user preference, priority, then
|
||||
Workbench selects by resource kind, request mode, extension/mime, context
|
||||
(`generic-text`, `generic-markdown`, `notes-markdown`), user preference, priority, then
|
||||
deterministic `pluginId/providerId` tie-break. If nothing matches, Workbench
|
||||
shows `no-provider` fallback instead of a core editor.
|
||||
|
||||
|
|
|
|||
|
|
@ -317,7 +317,8 @@ the Workbench helper.
|
|||
{
|
||||
"kind": "vault-file",
|
||||
"extensions": [".md", ".markdown"],
|
||||
"contexts": ["generic-markdown", "notes-markdown"]
|
||||
"contexts": ["generic-markdown", "notes-markdown"],
|
||||
"modes": ["view"]
|
||||
},
|
||||
{
|
||||
"kind": "vault-file",
|
||||
|
|
@ -333,7 +334,7 @@ the Workbench helper.
|
|||
```
|
||||
|
||||
Selection uses enabled loaded/degraded provider plugins, resource kind,
|
||||
extension/mime, context, user preference, priority, then deterministic
|
||||
request mode, extension/mime, context, user preference, priority, then deterministic
|
||||
`pluginId/providerId` fallback. If nothing matches, Workbench returns
|
||||
`status: "no-provider"` and shows the fallback view instead of a core editor.
|
||||
|
||||
|
|
|
|||
|
|
@ -339,8 +339,10 @@
|
|||
function providerSupports(provider, request) {
|
||||
var ext = requestExtension(request);
|
||||
var contextName = requestContextName(request);
|
||||
var mode = String((request && request.mode) || 'view').toLowerCase();
|
||||
return (provider.supports || []).some(function (support) {
|
||||
if (support.kind && support.kind !== request.kind) return false;
|
||||
if (support.modes && support.modes.length && support.modes.map(function (m) { return String(m).toLowerCase(); }).indexOf(mode) === -1) return false;
|
||||
if (support.extensions && support.extensions.length && support.extensions.map(function (e) { return String(e).toLowerCase(); }).indexOf(ext) === -1) return false;
|
||||
if (support.contexts && support.contexts.length && support.contexts.indexOf(contextName) === -1) return false;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export namespace api {
|
|||
mime?: string[];
|
||||
extensions?: string[];
|
||||
contexts?: string[];
|
||||
modes?: string[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new FlatOpenProviderSupport(source);
|
||||
|
|
@ -36,6 +37,7 @@ export namespace api {
|
|||
this.mime = source["mime"];
|
||||
this.extensions = source["extensions"];
|
||||
this.contexts = source["contexts"];
|
||||
this.modes = source["modes"];
|
||||
}
|
||||
}
|
||||
export class FlatOpenProvider {
|
||||
|
|
@ -534,6 +536,7 @@ export namespace plugin {
|
|||
mime?: string[];
|
||||
extensions?: string[];
|
||||
contexts?: string[];
|
||||
modes?: string[];
|
||||
|
||||
static createFrom(source: any = {}) {
|
||||
return new OpenProviderSupport(source);
|
||||
|
|
@ -545,6 +548,7 @@ export namespace plugin {
|
|||
this.mime = source["mime"];
|
||||
this.extensions = source["extensions"];
|
||||
this.contexts = source["contexts"];
|
||||
this.modes = source["modes"];
|
||||
}
|
||||
}
|
||||
export class ContributionOpenProvider {
|
||||
|
|
@ -1159,4 +1163,3 @@ export namespace workspace {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ type FlatOpenProviderSupport struct {
|
|||
Mime []string `json:"mime,omitempty"`
|
||||
Extensions []string `json:"extensions,omitempty"`
|
||||
Contexts []string `json:"contexts,omitempty"`
|
||||
Modes []string `json:"modes,omitempty"`
|
||||
}
|
||||
|
||||
type FlatOpenProvider struct {
|
||||
|
|
@ -316,7 +317,7 @@ func buildContributionSummary(r *contribution.Registry) ContributionSummary {
|
|||
for i, v := range regOpenProviders {
|
||||
supports := make([]FlatOpenProviderSupport, len(v.Item.Supports))
|
||||
for j, s := range v.Item.Supports {
|
||||
supports[j] = FlatOpenProviderSupport{Kind: s.Kind, Mime: s.Mime, Extensions: s.Extensions, Contexts: s.Contexts}
|
||||
supports[j] = FlatOpenProviderSupport{Kind: s.Kind, Mime: s.Mime, Extensions: s.Extensions, Contexts: s.Contexts, Modes: s.Modes}
|
||||
}
|
||||
openProviders[i] = FlatOpenProvider{
|
||||
PluginID: v.PluginID,
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ type OpenProviderSupport struct {
|
|||
Mime []string `json:"mime,omitempty"`
|
||||
Extensions []string `json:"extensions,omitempty"`
|
||||
Contexts []string `json:"contexts,omitempty"`
|
||||
Modes []string `json:"modes,omitempty"`
|
||||
}
|
||||
|
||||
// ContributionOpenProvider represents an editor/viewer provider contribution.
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ func providerMatches(request OpenResourceRequest, provider plugin.ContributionOp
|
|||
if support.Kind != request.Kind {
|
||||
continue
|
||||
}
|
||||
if !supportMatchesMode(request, support) {
|
||||
continue
|
||||
}
|
||||
if !supportMatchesExtensionOrMime(request, support) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -179,6 +182,19 @@ func providerMatches(request OpenResourceRequest, provider plugin.ContributionOp
|
|||
return false
|
||||
}
|
||||
|
||||
func supportMatchesMode(request OpenResourceRequest, support plugin.OpenProviderSupport) bool {
|
||||
if len(support.Modes) == 0 {
|
||||
return true
|
||||
}
|
||||
mode := strings.ToLower(request.Mode)
|
||||
for _, supported := range support.Modes {
|
||||
if strings.ToLower(supported) == mode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func supportMatchesExtensionOrMime(request OpenResourceRequest, support plugin.OpenProviderSupport) bool {
|
||||
hasExtensionRules := len(support.Extensions) > 0
|
||||
hasMimeRules := len(support.Mime) > 0
|
||||
|
|
|
|||
|
|
@ -91,6 +91,47 @@ func TestSelectProviderFallsBackByPriorityThenID(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSelectProviderHonorsSupportModes(t *testing.T) {
|
||||
r := NewRouter(Preferences{})
|
||||
providers := []contribution.ContributionOpenProvider{
|
||||
provider("preview.plugin", "markdown.preview", 100, "MarkdownPreview", plugin.OpenProviderSupport{
|
||||
Kind: "vault-file",
|
||||
Extensions: []string{".md"},
|
||||
Contexts: []string{ContextGenericMarkdown},
|
||||
Modes: []string{"view"},
|
||||
}),
|
||||
provider("editor.plugin", "markdown.editor", 50, "MarkdownEditor", plugin.OpenProviderSupport{
|
||||
Kind: "vault-file",
|
||||
Extensions: []string{".md"},
|
||||
Contexts: []string{ContextGenericMarkdown},
|
||||
}),
|
||||
}
|
||||
|
||||
viewProvider, err := r.SelectProvider(OpenResourceRequest{
|
||||
Kind: "vault-file",
|
||||
Path: "Docs/readme.md",
|
||||
Mode: "view",
|
||||
}, providers)
|
||||
if err != nil {
|
||||
t.Fatalf("SelectProvider(view): %v", err)
|
||||
}
|
||||
if viewProvider.Item.ID != "markdown.preview" {
|
||||
t.Fatalf("view provider = %q, want markdown.preview", viewProvider.Item.ID)
|
||||
}
|
||||
|
||||
editProvider, err := r.SelectProvider(OpenResourceRequest{
|
||||
Kind: "vault-file",
|
||||
Path: "Docs/readme.md",
|
||||
Mode: "edit",
|
||||
}, providers)
|
||||
if err != nil {
|
||||
t.Fatalf("SelectProvider(edit): %v", err)
|
||||
}
|
||||
if editProvider.Item.ID != "markdown.editor" {
|
||||
t.Fatalf("edit provider = %q, want markdown.editor", editProvider.Item.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectProviderTieBreaksByPluginIDThenProviderID(t *testing.T) {
|
||||
r := NewRouter(Preferences{})
|
||||
providers := []contribution.ContributionOpenProvider{
|
||||
|
|
|
|||
Loading…
Reference in New Issue