From 24ff1454a10ce48ac61233849d6383c503a5e806 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 4 Aug 2020 09:47:42 +0200 Subject: [PATCH 1/2] (feat) better typings for actions #416 --- packages/svelte2tsx/src/htmlxtojsx.ts | 18 +++++++++--------- packages/svelte2tsx/svelte-shims.d.ts | 17 +++++++++++++++-- .../htmlx2jsx/samples/action-bare/expected.jsx | 2 +- .../samples/action-nested/expected.jsx | 6 ++++++ .../samples/action-nested/input.svelte | 6 ++++++ .../samples/action-params/expected.jsx | 2 +- .../samples/directive-quoted/expected.jsx | 2 +- 7 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/expected.jsx create mode 100644 packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/input.svelte diff --git a/packages/svelte2tsx/src/htmlxtojsx.ts b/packages/svelte2tsx/src/htmlxtojsx.ts index 39225bde1..0ec00a27c 100644 --- a/packages/svelte2tsx/src/htmlxtojsx.ts +++ b/packages/svelte2tsx/src/htmlxtojsx.ts @@ -72,15 +72,9 @@ export function convertHtmlxToJsx( if (attr.expression) { const on = 'on'; //for handler assignment, we changeIt to call to our __sveltets_ensureFunction - str.appendRight( - attr.start, `{__sveltets_instanceOf(${parent.name}).$` - ); + str.appendRight(attr.start, `{__sveltets_instanceOf(${parent.name}).$`); const eventNameIndex = htmlx.indexOf(':', attr.start) + 1; - str.overwrite( - htmlx.indexOf(on, attr.start) + on.length, - eventNameIndex, - `('` - ); + str.overwrite(htmlx.indexOf(on, attr.start) + on.length, eventNameIndex, `('`); const eventEnd = htmlx.lastIndexOf('=', attr.expression.start); str.overwrite(eventEnd, attr.expression.start, `', `); str.overwrite(attr.expression.end, attr.end, ')}'); @@ -103,7 +97,11 @@ export function convertHtmlxToJsx( }; const handleActionDirective = (attr: Node) => { - str.overwrite(attr.start, attr.start + 'use:'.length, '{...__sveltets_ensureAction('); + str.overwrite( + attr.start, + attr.start + 'use:'.length, + `{...__sveltets_ensureAction(__sveltets_mapElementTag('${currentElement}'),`, + ); if (!attr.expression) { str.appendLeft(attr.end, ')}'); @@ -431,7 +429,9 @@ export function convertHtmlxToJsx( } }; + let currentElement: string; const handleElement = (node: Node) => { + currentElement = node.name; //we just have to self close void tags since jsx always wants the /> const voidTags = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'.split( ',', diff --git a/packages/svelte2tsx/svelte-shims.d.ts b/packages/svelte2tsx/svelte-shims.d.ts index 0aa8a23f4..b2cbdc54b 100644 --- a/packages/svelte2tsx/svelte-shims.d.ts +++ b/packages/svelte2tsx/svelte-shims.d.ts @@ -9,7 +9,7 @@ declare module '*.svelte' { type AConstructorTypeOf = new (...args: any[]) => T; -type SvelteAction = (node: HTMLElement, ...args:U) => { +type SvelteAction = (node: El, ...args:U) => { update?: (...args:U) => void, destroy?: () => void } | void @@ -48,7 +48,11 @@ type SvelteOnAllEvent = SvelteOnEvent & SvelteRestEvent declare var process: NodeJS.Process & { browser: boolean } declare function __sveltets_ensureAnimation(animation: SvelteAnimation, ...args: U): {}; -declare function __sveltets_ensureAction(action: SvelteAction, ...args: U): {}; +declare function __sveltets_ensureAction( + el: El, + action: SvelteAction, + ...args: U +): {}; declare function __sveltets_ensureTransition(transition: SvelteTransition, ...args: U): {}; declare function __sveltets_ensureFunction(expression: (e: Event & { detail?: any }) => unknown ): {}; declare function __sveltets_ensureType(type: AConstructorTypeOf, el: T): {}; @@ -73,6 +77,15 @@ declare function __sveltets_mapBodyEvent( declare function __sveltets_mapElementEvent( event: K ): HTMLElementEventMap[K]; +declare function __sveltets_mapElementTag( + tag: K +): ElementTagNameMap[K]; +declare function __sveltets_mapElementTag( + tag: K +): SVGElementTagNameMap[K]; +declare function __sveltets_mapElementTag( + tag: any +): HTMLElement; declare function __sveltets_bubbleEventDef< T extends SvelteEventRecord, TEvent, diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/action-bare/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/action-bare/expected.jsx index b017249ec..c9312c246 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/action-bare/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/action-bare/expected.jsx @@ -1 +1 @@ -<>

Hello

+<>

Hello

diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/expected.jsx new file mode 100644 index 000000000..deb08b58b --- /dev/null +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/expected.jsx @@ -0,0 +1,6 @@ +<> +
+ +

+ +
\ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/input.svelte new file mode 100644 index 000000000..dcdcb07e5 --- /dev/null +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/action-nested/input.svelte @@ -0,0 +1,6 @@ + +
+ +

+ +
\ No newline at end of file diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/action-params/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/action-params/expected.jsx index 158196a31..1142ef70c 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/action-params/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/action-params/expected.jsx @@ -1 +1 @@ -<>

Hello

+<>

Hello

diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx index 667309112..0c8e2fdc5 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/directive-quoted/expected.jsx @@ -1,6 +1,6 @@ <>

console.log("click")}>Hello

{__sveltets_instanceOf(Component).$on('click', test)} - + From 740613d42fe4af92cdf0b7a585ba786cb754d4b3 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Tue, 4 Aug 2020 15:56:15 +0200 Subject: [PATCH 2/2] cleaner solution --- packages/svelte2tsx/src/htmlxtojsx.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/svelte2tsx/src/htmlxtojsx.ts b/packages/svelte2tsx/src/htmlxtojsx.ts index 0ec00a27c..891a2dad0 100644 --- a/packages/svelte2tsx/src/htmlxtojsx.ts +++ b/packages/svelte2tsx/src/htmlxtojsx.ts @@ -96,11 +96,11 @@ export function convertHtmlxToJsx( } }; - const handleActionDirective = (attr: Node) => { + const handleActionDirective = (attr: Node, parent: Node) => { str.overwrite( attr.start, attr.start + 'use:'.length, - `{...__sveltets_ensureAction(__sveltets_mapElementTag('${currentElement}'),`, + `{...__sveltets_ensureAction(__sveltets_mapElementTag('${parent.name}'),`, ); if (!attr.expression) { @@ -429,9 +429,7 @@ export function convertHtmlxToJsx( } }; - let currentElement: string; const handleElement = (node: Node) => { - currentElement = node.name; //we just have to self close void tags since jsx always wants the /> const voidTags = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'.split( ',', @@ -616,7 +614,7 @@ export function convertHtmlxToJsx( handleClassDirective(node); break; case 'Action': - handleActionDirective(node); + handleActionDirective(node, parent); break; case 'Transition': handleTransitionDirective(node);