Skip to content

VOID Elements hardcoded for with non html langauges #123

@hahn-kev

Description

@hahn-kev

So I'm making a custom extension that's parsing xml, and I'm building my extension on top of this html language service, this has worked great in most places because I can just disable the default data provider and roll my own.

The problem I'm having is with fact.ts method isVoidElement. It has a hard coded list of elements that are void (for example <img>) and this is a problem in my case because an img tag is not void in my case. I'd really like to be able to customize void elements. I'd even be happy to make a PR for the change, but I'd like to figure out the best way to implement it. Up till now I've done a bit of a hack to access the hard coded list and modify it for my use case, but that's causing some problems at build time for me now and I'd like to find a better way to solve my problem.

What makes sense to me is to modify the custom data providers to be able to specify this.

Option 1

Modify HTMLDataV1 to have a string list identifying all the void tags. and add an api to IHTMLDataProvider to retrieve that list Like this:

export interface HTMLDataV1 {
	version: 1 | 1.1;
	tags?: ITagData[];
	globalAttributes?: IAttributeData[];
	valueSets?: IValueSet[];
	voidTags?: string[]; // <===== new line
}

export interface IHTMLDataProvider {
	getId(): string;
	isApplicable(languageId: string): boolean;

	provideTags(): ITagData[];
	provideAttributes(tag: string): IAttributeData[];
	provideValues(tag: string, attribute: string): IValueData[];
	provideVoidTags(): string[]; // <===== new line
}

Then in various places where isVoidElement we could provide the list of void elements using the HTML Data, similar to what we're doing already for stuff like autocomplete data.

The up side to this change is that it works very similar to how we already customize the language service and would be easy for developer discovery. The downside is that it would require the most work of the changes I'm going to suggest.

Option 2

export the VOID_ELEMENTS list in fact.js as part of the API for the language service. I've hacked together a work around by doing this myself but it doesn't always play nice. This would allow the end developer to modify the list as they desire.

The up side is that this is a very simple change that doesn't require changing very much code at all. The downside is that it's hard for a dev to discovery, it's inconsistent with how things have been done so far. It's also a SINGLETON, so there's various problems with that as well.

Option 3

define a new language service option to specify VOID elements.

This would be more difficult than option 2 but simpler than option 1 due to it being a single list that is always the same for a given instance of the service, it would also be decent for developer discovery as it's part of the options API exposed when consuming the service. The downside is that it's not at all consistent with how custom data has been handled in the past.

Please let me know what you think, and what direction would be the best to take, then I can start work on a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions