Skip to content

Commit

Permalink
fix: textarea with null value
Browse files Browse the repository at this point in the history
  • Loading branch information
Varixo committed Dec 27, 2024
1 parent bfb07d9 commit ef92d10
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-trains-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@qwik.dev/core': patch
---

fix: textarea with null value
10 changes: 5 additions & 5 deletions packages/qwik/src/core/client/vnode-diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ import {
} from '../signal/signal-subscriber';
import { serializeAttribute } from '../shared/utils/styles';
import { QError, qError } from '../shared/error/error';
import { getFileNameFromJsx } from '../shared/utils/jsx-filename';
import { getFileLocationFromJsx } from '../shared/utils/jsx-filename';

export type ComponentQueue = Array<VNode>;

Expand Down Expand Up @@ -660,13 +660,13 @@ export const vnode_diff = (
}

if (elementName === 'textarea' && key === 'value') {
if (typeof value !== 'string') {
if (value && typeof value !== 'string') {
if (isDev) {
throw qError(QError.wrongTextareaValue, [currentFile]);
throw qError(QError.wrongTextareaValue, [currentFile, value]);
}
continue;
}
(element as HTMLTextAreaElement).value = escapeHTML(value);
(element as HTMLTextAreaElement).value = escapeHTML((value as string) || '');
continue;
}

Expand Down Expand Up @@ -712,7 +712,7 @@ export const vnode_diff = (
vCurrent && vnode_isElementVNode(vCurrent) && elementName === vnode_getElementName(vCurrent);
const jsxKey: string | null = jsx.key;
let needsQDispatchEventPatch = false;
const currentFile = getFileNameFromJsx(jsx.dev);
const currentFile = getFileLocationFromJsx(jsx.dev);
if (!isSameElementName || jsxKey !== getKey(vCurrent)) {
// So we have a key and it does not match the current node.
// We need to do a forward search to find it.
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik/src/core/shared/error/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const codeToText = (code: number, ...parts: any[]): string => {
'Serialization Error: Serialization of data type {{0}} is not implemented', // 37
'Serialization Error: Unvisited {{0}}', // 38
'Serialization Error: Missing QRL chunk for {{0}}', // 39
'{{0}}\nThe value of the textarea must be a string', // 40
'{{0}}\nThe value of the textarea must be a string found {{1}}', // 40
'Unable to find q:container', // 41
"Element must have 'q:container' attribute.", // 42
'Unknown vnode type {{0}}.', // 43
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik/src/core/shared/utils/jsx-filename.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { DevJSX } from '../jsx/types/jsx-node';

export function getFileNameFromJsx(jsxDev?: DevJSX): string | null {
export function getFileLocationFromJsx(jsxDev?: DevJSX): string | null {
if (!jsxDev) {
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/qwik/src/core/ssr/ssr-render-jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import type { ISsrComponentFrame, ISsrNode, SSRContainer, SsrAttrs } from './ssr
import { qInspector } from '../shared/utils/qdev';
import { serializeAttribute } from '../shared/utils/styles';
import { QError, qError } from '../shared/error/error';
import { getFileNameFromJsx } from '../shared/utils/jsx-filename';
import { getFileLocationFromJsx } from '../shared/utils/jsx-filename';

class ParentComponentData {
constructor(
Expand Down Expand Up @@ -183,7 +183,7 @@ function processJSXNode(
appendClassIfScopedStyleExists(jsx, options.styleScoped);
let qwikInspectorAttrValue: string | null = null;
if (isDev && jsx.dev && jsx.type !== 'head') {
qwikInspectorAttrValue = getFileNameFromJsx(jsx.dev);
qwikInspectorAttrValue = getFileLocationFromJsx(jsx.dev);
if (qInspector) {
appendQwikInspectorAttribute(jsx, qwikInspectorAttrValue);
}
Expand Down
22 changes: 21 additions & 1 deletion packages/qwik/src/core/tests/component.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
useTask$,
useVisibleTask$,
type JSXOutput,
type PropsOf,
type Signal as SignalType,
} from '@qwik.dev/core';
import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
Expand Down Expand Up @@ -480,6 +481,25 @@ describe.each([
await expect(document.querySelector('textarea')).toMatchDOM(<textarea>value 123!</textarea>);
});

it('should render textarea without error', async () => {
const Textarea = component$<PropsOf<'textarea'>>(
({ ['bind:value']: valueSig, value, ...props }) => {
return (
<>
<textarea {...props} value={valueSig ? valueSig.value : value} />
</>
);
}
);

const Cmp = component$(() => {
return <Textarea />;
});

const { document } = await render(<Cmp />, { debug });
await expect(document.querySelector('textarea')).toMatchDOM(<textarea></textarea>);
});

it('should not render textarea value for non-text value', async () => {
const qErrorSpy = vi.spyOn(qError, 'qError');
const Cmp = component$(() => {
Expand All @@ -502,7 +522,7 @@ describe.each([
);
} catch (e) {
expect((e as Error).message).toBeDefined();
expect(qErrorSpy).toHaveBeenCalledWith(QError.wrongTextareaValue);
expect(qErrorSpy).toHaveBeenCalledWith(QError.wrongTextareaValue, expect.anything());
}
});

Expand Down
6 changes: 3 additions & 3 deletions packages/qwik/src/server/ssr-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1176,13 +1176,13 @@ class SSRContainer extends _SharedContainer implements ISSRContainer {
}

if (tag === 'textarea' && key === 'value') {
if (typeof value !== 'string') {
if (value && typeof value !== 'string') {
if (isDev) {
throw qError(QError.wrongTextareaValue, [currentFile]);
throw qError(QError.wrongTextareaValue, [currentFile, value]);
}
continue;
}
innerHTML = escapeHTML(value);
innerHTML = escapeHTML(value || '');
key = QContainerAttr;
value = QContainerValue.TEXT;
}
Expand Down

0 comments on commit ef92d10

Please sign in to comment.