fix: preserve cjk code block copy text
This commit is contained in:
@@ -796,6 +796,31 @@ describe('SingleEditorView', () => {
|
||||
expect(clipboardData.setData).toHaveBeenCalledWith('text/plain', json)
|
||||
})
|
||||
|
||||
it('copies CJK fenced code text from the selected DOM fragment when selection text is mojibake', async () => {
|
||||
const text = 'const label = "中文測試"'
|
||||
const { container } = renderEditorHarness()
|
||||
const { codeBlock, code } = createCodeBlockFixture(text)
|
||||
await act(async () => {
|
||||
container.appendChild(codeBlock)
|
||||
await Promise.resolve()
|
||||
})
|
||||
|
||||
const range = document.createRange()
|
||||
range.selectNodeContents(code)
|
||||
const getSelection = vi.spyOn(window, 'getSelection').mockReturnValue({
|
||||
rangeCount: 1,
|
||||
isCollapsed: false,
|
||||
getRangeAt: () => range,
|
||||
toString: () => 'const label = "䏿–‡æ¸¬è©¦"',
|
||||
} as Selection)
|
||||
|
||||
const clipboardData = { setData: vi.fn() }
|
||||
fireEvent.copy(code, { clipboardData })
|
||||
getSelection.mockRestore()
|
||||
|
||||
expect(clipboardData.setData).toHaveBeenCalledWith('text/plain', text)
|
||||
})
|
||||
|
||||
it('copies fenced code from the code-block action button', async () => {
|
||||
const json = '{\n "id": "Demo"\n}'
|
||||
const writeText = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
@@ -421,7 +421,7 @@ function selectedCodeBlockText(options: {
|
||||
const range = selectedCodeBlockRange(options)
|
||||
if (!range) return null
|
||||
|
||||
return options.selection?.toString() || range.cloneContents().textContent || ''
|
||||
return range.cloneContents().textContent || options.selection?.toString() || ''
|
||||
}
|
||||
|
||||
function selectedEditorRange(selection: Selection | null, container: HTMLElement): Range | null {
|
||||
|
||||
@@ -12,6 +12,7 @@ const CODE_COPY_NOTE_RELATIVE_PATH = path.join('note', 'fenced-code-copy.md')
|
||||
const CODE_COPY_NOTE_TITLE = 'Fenced Code Copy'
|
||||
const JSON_SNIPPET = '{\n "id": "Demo",\n "enabled": true\n}'
|
||||
const TYPESCRIPT_SNIPPET = 'const answer = 42\nconsole.log(answer)'
|
||||
const CJK_SNIPPET = 'const label = "中文測試"\nconsole.log(label)'
|
||||
const RICH_CODE_SELECTOR = '.bn-block-content[data-content-type="codeBlock"] pre code'
|
||||
|
||||
function writeCodeCopyFixtureNote(tempVaultDir: string) {
|
||||
@@ -35,6 +36,12 @@ Copy this TypeScript exactly:
|
||||
\`\`\`ts
|
||||
${TYPESCRIPT_SNIPPET}
|
||||
\`\`\`
|
||||
|
||||
Copy this CJK text exactly:
|
||||
|
||||
\`\`\`ts
|
||||
${CJK_SNIPPET}
|
||||
\`\`\`
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -101,6 +108,8 @@ async function selectRawEditorText(page: Page, text: string) {
|
||||
test.describe('Fenced code copy', () => {
|
||||
let tempVaultDir: string
|
||||
|
||||
test.setTimeout(30_000)
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.context().grantPermissions(['clipboard-read', 'clipboard-write'])
|
||||
tempVaultDir = createFixtureVaultCopy()
|
||||
@@ -112,14 +121,16 @@ test.describe('Fenced code copy', () => {
|
||||
removeFixtureVaultCopy(tempVaultDir)
|
||||
})
|
||||
|
||||
test('copies rich code blocks from the button and selections without escape backslashes', async ({ page }) => {
|
||||
test('copies rich code blocks from the button and selections without corruption', async ({ page }) => {
|
||||
const noteList = page.locator('[data-testid="note-list-container"]')
|
||||
const noteItem = noteList.getByText(CODE_COPY_NOTE_TITLE, { exact: true })
|
||||
await expect(noteItem).toBeVisible({ timeout: 10_000 })
|
||||
await noteItem.click()
|
||||
await expect(page.locator(RICH_CODE_SELECTOR)).toHaveCount(3, { timeout: 10_000 })
|
||||
|
||||
await expect.poll(() => copyRichCodeBlockFromButton(page, 0)).toBe(JSON_SNIPPET)
|
||||
await expect.poll(() => copyRichCodeBlockFromButton(page, 1)).toBe(TYPESCRIPT_SNIPPET)
|
||||
await expect.poll(() => copyRichCodeBlockFromButton(page, 2)).toBe(CJK_SNIPPET)
|
||||
|
||||
await selectRichCodeBlock(page, 0)
|
||||
await expect.poll(() => copySelectedText(page)).toBe(JSON_SNIPPET)
|
||||
@@ -127,6 +138,9 @@ test.describe('Fenced code copy', () => {
|
||||
await selectRichCodeBlock(page, 1)
|
||||
await expect.poll(() => copySelectedText(page)).toBe(TYPESCRIPT_SNIPPET)
|
||||
|
||||
await selectRichCodeBlock(page, 2)
|
||||
await expect.poll(() => copySelectedText(page)).toBe(CJK_SNIPPET)
|
||||
|
||||
await openCommandPalette(page)
|
||||
await executeCommand(page, 'Toggle Raw')
|
||||
await selectRawEditorText(page, JSON_SNIPPET)
|
||||
|
||||
Reference in New Issue
Block a user