diff --git a/packages/language-server/src/plugins/html/dataProvider.ts b/packages/language-server/src/plugins/html/dataProvider.ts index 3031552c4..f52076c6a 100644 --- a/packages/language-server/src/plugins/html/dataProvider.ts +++ b/packages/language-server/src/plugins/html/dataProvider.ts @@ -2,52 +2,60 @@ import { IAttributeData, ITagData, newHTMLDataProvider } from 'vscode-html-langu import { htmlData } from 'vscode-html-languageservice/lib/umd/languageFacts/data/webCustomData'; import { unique } from '../../utils'; -const svelteEvents = [ - ...(htmlData.globalAttributes?.filter(isEvent).map(mapToSvelteEvent) ?? []), +const svelteEvents: IAttributeData[] = [ { name: 'on:introstart', - description: 'Available when element has transition' + description: 'Available when element has transition.', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#transition-events" + } + ] }, { name: 'on:introend', - description: 'Available when element has transition' + description: 'Available when element has transition.', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#transition-events" + } + ] }, { name: 'on:outrostart', - description: 'Available when element has transition' + description: 'Available when element has transition.', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#transition-events" + } + ] }, { name: 'on:outroend', - description: 'Available when element has transition' - }, - // Pointer events - { name: 'on:pointercancel' }, - { name: 'on:pointerdown' }, - { name: 'on:pointerenter' }, - { name: 'on:pointerleave' }, - { name: 'on:pointermove' }, - { name: 'on:pointerout' }, - { name: 'on:pointerover' }, - { name: 'on:pointerup' }, - // Mouse events - { name: 'on:mouseenter' }, - { name: 'on:mouseleave' }, - // Other - { name: 'on:hashchange' }, - { name: 'on:visibilitychange' } + description: 'Available when element has transition.', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#transition-events" + } + ] + } ]; const svelteAttributes: IAttributeData[] = [ { name: 'bind:innerHTML', - description: 'Available when contenteditable=true' + description: 'Available when `contenteditable=true`' }, { name: 'bind:textContent', - description: 'Available when contenteditable=true' + description: 'Available when `contenteditable=true`' }, { name: 'bind:innerText', - description: 'Available when contenteditable=true' + description: 'Available when `contenteditable=true`' }, { name: 'bind:clientWidth', @@ -84,7 +92,7 @@ const svelteAttributes: IAttributeData[] = [ { name: 'bind:this', description: - 'To get a reference to a DOM node, use bind:this. If used on a component, gets a reference to that component instance.' + 'To get a reference to a DOM node, use `bind:this`. If used on a component, gets a reference to that component instance.' } ]; const sveltekitAttributes: IAttributeData[] = [ @@ -92,13 +100,25 @@ const sveltekitAttributes: IAttributeData[] = [ name: 'data-sveltekit-keepfocus', description: 'SvelteKit-specific attribute. Currently focused element will retain focus after navigation. Otherwise, focus will be reset to the body.', - valueSet: 'v' + valueSet: 'v', + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-keepfocus" + } + ] }, { name: 'data-sveltekit-noscroll', description: 'SvelteKit-specific attribute. Will prevent scrolling after the link is clicked.', - valueSet: 'v' + valueSet: 'v', + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-noscroll" + } + ] }, { name: 'data-sveltekit-preload-code', @@ -111,6 +131,12 @@ const sveltekitAttributes: IAttributeData[] = [ { name: 'hover' }, { name: 'tap' }, { name: 'off' } + ], + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-preload-code" + } ] }, { @@ -118,19 +144,37 @@ const sveltekitAttributes: IAttributeData[] = [ description: "SvelteKit-specific attribute. Will cause SvelteKit to run the page's load function as soon as the user hovers over the link (on a desktop) or touches it (on mobile), rather than waiting for the click event to trigger navigation.", valueSet: 'v', - values: [{ name: 'hover' }, { name: 'tap' }, { name: 'off' }] + values: [{ name: 'hover' }, { name: 'tap' }, { name: 'off' }], + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-preload-data" + } + ] }, { name: 'data-sveltekit-reload', description: 'SvelteKit-specific attribute. Will cause SvelteKit to do a normal browser navigation which results in a full page reload.', - valueSet: 'v' + valueSet: 'v', + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-reload" + } + ] }, { name: 'data-sveltekit-replacestate', description: 'SvelteKit-specific attribute. Will replace the current `history` entry rather than creating a new one with `pushState` when the link is clicked.', - valueSet: 'v' + valueSet: 'v', + references: [ + { + name: "SvelteKit Reference", + url: "https://kit.svelte.dev/docs/link-options#data-sveltekit-replacestate" + } + ] } ]; @@ -139,7 +183,13 @@ const svelteTags: ITagData[] = [ name: 'svelte:self', description: 'Allows a component to include itself, recursively.\n\nIt cannot appear at the top level of your markup; it must be inside an if or each block to prevent an infinite loop.', - attributes: [] + attributes: [], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-self' + } + ] }, { name: 'svelte:component', @@ -151,6 +201,12 @@ const svelteTags: ITagData[] = [ description: 'Component to render.\n\nWhen this property changes, the component is destroyed and recreated.\nIf this is falsy, no component is rendered.' } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-component' + } ] }, { @@ -163,6 +219,12 @@ const svelteTags: ITagData[] = [ description: 'DOM element to render.\n\nWhen this property changes, the element is destroyed and recreated.\nIf this is falsy, no element is rendered.' } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-element' + } ] }, { @@ -196,14 +258,26 @@ const svelteTags: ITagData[] = [ }, { name: 'bind:online', - description: 'An alias for window.navigator.onLine' + description: 'An alias for `window.navigator.onLine`.', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine" + } + ] + } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-window' } ] }, { name: 'svelte:document', description: - "As with , this element allows you to add listeners to events on document, such as visibilitychange, which don't fire on window.", + "As with ``, this element allows you to add listeners to events on document, such as `visibilitychange`, which don't fire on window.", attributes: [ { name: 'bind:fullscreenElement', @@ -213,65 +287,140 @@ const svelteTags: ITagData[] = [ { name: 'bind:visibilityState', description: 'Bind to visibility of the document. (read-only)' + }, + { + name: 'onfullscreenchange', + description: 'Function to call when the document enters or exits full screen mode.', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenchange_event" + } + ] + }, + { + name: 'onfullscreenerror', + description: 'Function to call when an error occurs while trying to enter full screen mode.', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenerror_event" + } + ] + }, + { + name: "onvisibilitychange", + description: "Function to call when the visibility of the document changes.", + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event" + } + ] + }, + { + name: 'onsecuritypolicyviolation', + description: 'Function to call when a security policy is violated.', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Document/securitypolicyviolation_event" + } + ] + }, + { + name: 'onselectionchange', + description: 'Function to call when the selection changes.', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/Document/selectionchange_event" + } + ] + } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-document' } ] }, { name: 'svelte:body', description: - "As with , this element allows you to add listeners to events on document.body, such as mouseenter and mouseleave which don't fire on window.", - attributes: [] + "As with ``, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave` which don't fire on window.", + attributes: htmlData.tags!.find((tag) => tag.name === 'body')!.attributes + .filter(isEvent), + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-body' + } + ] }, { name: 'svelte:head', description: - 'This element makes it possible to insert elements into document.head. During server-side rendering, head content exposed separately to the main html content.', - attributes: [] + 'This element makes it possible to insert elements into `document.head`. During server-side rendering, head content exposed separately to the main html content.', + attributes: [], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-head' + } + ] }, { name: 'svelte:options', - description: 'Provides a place to specify per-component compiler options', + description: 'Provides a place to specify per-component compiler options.', attributes: [ { name: 'immutable', description: - 'If true, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.', + 'If `true`, tells the compiler that you promise not to mutate any objects. This allows it to be less conservative about checking whether values have changed.', values: [ { name: '{true}', description: - 'You never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed' + 'You never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed.' }, { name: '{false}', description: - 'The default. Svelte will be more conservative about whether or not mutable objects have changed' + 'Svelte will be more conservative about whether or not mutable objects have changed. (default)' } ] }, { name: 'accessors', description: - "If true, getters and setters will be created for the component's props. If false, they will only be created for readonly exported values (i.e. those declared with const, class and function). If compiling with customElement: true this option defaults to true.", + "If `true`, getters and setters will be created for the component's props. If `false`, they will only be created for readonly exported values (i.e. those declared with `const`, `class` and `function`). If compiling with `customElement: true` this option defaults to `true`.", values: [ { name: '{true}', - description: "Adds getters and setters for the component's props" + description: "Adds getters and setters for the component's props." }, { name: '{false}', - description: 'The default.' + description: '(default)' } ] }, { name: 'namespace', - description: 'The namespace where this component will be used, most commonly "svg"' + description: 'The namespace where this component will be used, most commonly `"svg"`' }, { name: 'tag', description: 'The name to use when compiling this component as a custom element' } + ], + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/special-elements#svelte-options" + } ] }, { @@ -283,133 +432,360 @@ const svelteTags: ITagData[] = [ name: 'slot', description: 'The name of the named slot that should be targeted.' } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#svelte-fragment' + } ] }, { name: 'slot', description: - 'Components can have child content, in the same way that elements can.\n\nThe content is exposed in the child component using the element, which can contain fallback content that is rendered if no children are provided.', + 'Components can have child content, in the same way that elements can.\n\nThe content is exposed in the child component using the `` element, which can contain fallback content that is rendered if no children are provided.', attributes: [ { name: 'name', description: 'Named slots allow consumers to target specific areas. They can also have fallback content.' } + ], + references: [ + { + name: 'Svelte Reference', + url: 'https://svelte.dev/docs/special-elements#slot' + } ] } ]; +const svelteMediaReference = { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#media-element-bindings" +}; const mediaAttributes: IAttributeData[] = [ { name: 'bind:duration', - description: 'The total duration of the video, in seconds. (readonly)' + description: 'The total duration of the video, in seconds. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration" + } + ] }, { name: 'bind:buffered', - description: 'An array of {start, end} objects. (readonly)' + description: 'An array of {start, end} objects. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered" + } + ] }, { name: 'bind:seekable', - description: 'An array of {start, end} objects. (readonly)' + description: 'An array of `{start, end}` objects. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekable" + } + ] }, { name: 'bind:played', - description: 'An array of {start, end} objects. (readonly)' + description: 'An array of `{start, end}` objects. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/played" + } + ] }, { name: 'bind:seeking', - description: 'boolean. (readonly)' + description: 'boolean. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking" + } + ] }, { name: 'bind:ended', - description: 'boolean. (readonly)' + description: 'boolean. (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended" + } + ] }, { name: 'bind:currentTime', - description: 'The current point in the video, in seconds.' + description: 'The current point in the video, in seconds.', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime" + } + ] }, { name: 'bind:playbackRate', - description: "how fast or slow to play the video, where 1 is 'normal'" + description: "How fast or slow to play the video, where `1.0` is \"normal speed\"", + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate" + } + ] }, { - name: 'bind:paused' + name: 'bind:paused', + description: 'boolean.', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused" + } + ] }, { name: 'bind:volume', - description: 'A value between 0 and 1' + description: 'A value between `0.0` and `1.0`.', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume" + } + ] }, { - name: 'bind:muted' + name: 'bind:muted', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted" + } + ] }, { - name: 'bind:readyState' + name: 'bind:readyState', + description: 'A number between `0` and `4` (included). (readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState" + } + ] } ]; const videoAttributes: IAttributeData[] = [ { name: 'bind:videoWidth', - description: 'readonly' + description: '(readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoWidth" + } + ] }, { name: 'bind:videoHeight', - description: 'readonly' + description: '(readonly)', + references: [ + svelteMediaReference, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoHeight" + } + ] } ]; const indeterminateAttribute: IAttributeData = { name: 'indeterminate', - description: 'Available for type="checkbox"' + description: 'Available for `type="checkbox"`', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#indeterminate_state_checkboxes" + } + ] }; -const addAttributes: Record = { +const attributesOverrides: Record = { select: [{ name: 'bind:value' }], input: [ { name: 'bind:value' }, - { name: 'bind:group', description: 'Available for type="radio" and type="checkbox"' }, - { name: 'bind:checked', description: 'Available for type="checkbox"' }, - { name: 'bind:files', description: 'Available for type="file" (readonly)' }, + { name: 'bind:group', description: 'Available for `type="radio"` and `type="checkbox"`' }, + { name: 'bind:checked', description: 'Available for `type="checkbox"`' }, + { name: 'bind:files', description: 'Available for `type="file"` (readonly)' }, indeterminateAttribute, { ...indeterminateAttribute, name: 'bind:indeterminate' } ], - img: [{ name: 'bind:naturalWidth' }, { name: 'bind:naturalHeight' }], + img: [ + { + name: 'bind:naturalWidth', + description: 'The intrinsic width of the image, in CSS pixels. (readonly)', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#image-element-bindings" + }, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth" + } + ] + }, + { + name: 'bind:naturalHeight', + description: 'The intrinsic height of the image, in CSS pixels. (readonly)', + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/element-directives#image-element-bindings" + }, + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight" + } + ] + } + ], textarea: [{ name: 'bind:value' }], video: [...mediaAttributes, ...videoAttributes], - audio: [...mediaAttributes], + audio: mediaAttributes, details: [ { - name: 'bind:open' + name: 'bind:open', + references: [ + { + name: "MDN Reference", + url: "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#open" + } + ] + } + ], + style: [ + { + name: 'lang', + description: 'Use a preprocessor.', + values: [ + { + name: 'css', + description: 'CSS' + }, + { + name: 'sass', + description: 'Sass' + }, + { + name: 'scss', + description: 'SCSS' + }, + { + name: 'less', + description: 'Less' + }, + { + name: 'stylus', + description: 'Stylus' + }, + { + name: 'postcss', + description: 'PostCSS' + } + ], + references: [ + { + name: "Svelte Reference", + url: "https://svelte.dev/docs/svelte-compiler#preprocess" + } + ] } ], script: [ { name: 'generics', description: - 'Generics used within the components. Only available when using TypeScript.' + 'Generics used within the components. Only available when using TypeScript.', + references: [ + { + name: "Svelte RFC", + url: "https://github.com/dummdidumm/rfcs/blob/ts-typedefs-within-svelte-components/text/ts-typing-props-slots-events.md#generics" + } + ] + }, + { + name: 'context', + description: "A `