Repository: apache/superset
File: superset-frontend/plugins/plugin-chart-table/src/TableChart.tsx (TypeScript)

Code before:
        value={current}
        onChange={e => {
          onChange(Number((e.target as HTMLSelectElement).value));
        }}
        aria-label={t('Show entries per page')}
      >
        {options.map(option => {
          const [size, text] = Array.isArray(option)
            ? option
            : [option, option];
          return (
            <option key={size} value={size}>
              {text}
            </option>
          );
        })}
      </select>{' '}
      {t('entries per page')}
    </span>
  );
}

const getNoResultsMessage = (filter: string) =>
  filter ? t('No matching records found') : t('No records found');

const isHtml = (value: any): boolean => {
  if (typeof value !== 'string') {
    return false;
  }
  return value.includes('<') && value.includes('>');
};

const stripHtmlAndGetValue = (value: any): string | number | boolean => {
  // Create a temporary DOM element to parse the HTML
  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = value;

  // Get the text content (this removes all HTML tags)
  const textContent = tempDiv.textContent || tempDiv.innerText || '';

  return textContent.trim();
};

export default function TableChart<D extends DataRecord = DataRecord>(
  props: TableChartTransformedProps<D> & {
    sticky?: DataTableProps<D>['sticky'];
  },
) {
  const {
    timeGrain,
    height,

Review comment (security):
 comment crafted with Claude -> 

---
Hi @amaannawab923, thanks for working on this fix!

  For handling HTML content in table cells, we already have comprehensive HTML utilities available in the codebase that should be used:

  📍 HTML Utilities Location: @superset-ui/core/src/utils/html

  Key functions available:
  - removeHTMLTags(str) - Strips all HTML tags from a string (useful for getting plain text for context menu operations)
  - sanitizeHtml(htmlString) - Safely sanitizes HTML content using XSS filtering
  - isProbablyHTML(text) - Detects if a string contains valid HTML
  - safeHtmlSpan(possiblyHtmlString) - Returns a safe React component for rendering HTML

  The table chart already uses these utilities in superset-frontend/plugins/plugin-chart-table/src/utils/formatValue.ts:54 for sanitizing HTML content when allowRenderHtml is enabled.

  For the context menu issue with HTML <a> tags, you might want to use removeHTMLTags() to extract the plain text value for drill-down operations. This is already being done in the drill detail menu items (see
  DrillDetailMenuItems.tsx:93).

  Example usage:
  import { removeHTMLTags } from '@superset-ui/core';

  // When handling context menu for HTML cells
  const plainTextValue = removeHTMLTags(htmlCellValue);

  This approach ensures consistency with how HTML is handled throughout the codebase and maintains proper security sanitization.

Code after:
}: SearchInputProps) {
  return (
    <Space direction="horizontal" size={4} className="dt-global-filter">
      {t('Search')}
      <Input
        aria-label={t('Search %s records', count)}
        placeholder={tn('%s record', '%s records...', count, count)}
        value={value}
        onChange={onChange}
        onBlur={onBlur}
        ref={inputRef}
      />
    </Space>
  );
}

function SelectPageSize({
  options,
  current,
  onChange,
}: SelectPageSizeRendererProps) {
  const { Option } = Select;

  return (
    <span className="dt-select-page-size">
      <VisuallyHidden htmlFor="pageSizeSelect">
        {t('Select page size')}
      </VisuallyHidden>
      {t('Show')}{' '}
      <Select<number>
        id="pageSizeSelect"
        value={current}
        onChange={value => onChange(value)}
        size="small"
        css={(theme: SupersetTheme) => css`
          width: ${theme.sizeUnit * 18}px;
        `}
        aria-label={t('Show entries per page')}
      >
        {options.map(option => {
          const [size, text] = Array.isArray(option)
            ? option
            : [option, option];
          return (
            <Option key={size} value={Number(size)}>
              {text}
            </Option>
          );
        })}
      </Select>{' '}
      {t('entries per page')}