Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions page/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const arrowBack = common.replace('{}', '0 0 24 24').replace('{}', 'M16.62 2.99a1
const arrowForward = common.replace('{}', '0 0 24 24').replace('{}', 'M7.38 21.01c.49.49 1.28.49 1.77 0l8.31-8.31a.996.996 0 0 0 0-1.41L9.15 2.98c-.49-.49-1.28-.49-1.77 0s-.49 1.28 0 1.77L14.62 12l-7.25 7.25c-.48.48-.48 1.28.01 1.76z')

function setCandidates(cands: Candidate[], highlighted: number, markText: string, pageable: boolean, hasPrev: boolean, hasNext: boolean, scrollState: SCROLL_STATE, scrollStart: boolean, scrollEnd: boolean) {
const isVertical = hoverables.classList.contains('fcitx-vertical')
resetMouseMoveState()
hideContextmenu()
setScrollState(scrollState)
Expand Down Expand Up @@ -158,7 +159,7 @@ function setCandidates(cands: Candidate[], highlighted: number, markText: string
const candidateInner = div('fcitx-candidate-inner', 'fcitx-hoverable-inner')

// Render placeholder for vertical/scroll non-highlighted candidates
if (hoverables.classList.contains('fcitx-vertical') || hoverables.classList.contains('fcitx-horizontal-scroll') || i === highlighted) {
if (isVertical || hoverables.classList.contains('fcitx-horizontal-scroll') || i === highlighted) {
const mark = div('fcitx-mark')
if (markText === '') {
mark.classList.add('fcitx-no-text')
Expand Down Expand Up @@ -194,12 +195,9 @@ function setCandidates(cands: Candidate[], highlighted: number, markText: string
candidate.append(candidateInner)
hoverables.append(candidate)

// No divider after last element in non-scroll mode,
// but for scroll mode it needs to fill the row when
// candidates are not enough.
if (scrollState === SCROLLING || i !== cands.length - 1) {
hoverables.append(divider())
}
// For horizontal/scroll mode it needs to fill the row when candidates are not enough.
// For vertical mode, this last divider is hidden.
hoverables.append(divider())
}

setActions(cands.map(c => c.actions))
Expand Down
6 changes: 5 additions & 1 deletion page/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ $color-transition: var(--color-transition, background-color 500ms ease, color 50
border-end-end-radius: calc($candidate-height / 2 + $border-width);
}

.fcitx-panel:has(.fcitx-horizontal-scroll) {
/* Apply to panel to restrict both candidates and preedit width. */
inline-size: calc($cell-width * var(--max-column, 6) + 10px /* 2px redundance + 8px scrollbar making default 400px */);
}

.fcitx-candidate-inner, .fcitx-preedit, .fcitx-aux-down, .fcitx-menu-item {
/* Make sure 🦦 takes equal width when vertical+vertical-rl. */
min-block-size: $text-content-size;
Expand Down Expand Up @@ -485,7 +490,6 @@ $color-transition: var(--color-transition, background-color 500ms ease, color 50

.fcitx-horizontal-scroll {
max-block-size: calc(var(--max-row, 6) * $candidate-height); /* If block-size, 2 rows will have 90px each. */
inline-size: calc($cell-width * var(--max-column, 6) + 10px /* 2px redundance + 8px scrollbar making default 400px */);
transition: var(--scroll-animation, max-block-size 300ms);

.fcitx-candidate {
Expand Down
19 changes: 18 additions & 1 deletion page/generic.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@

.fcitx-divider {
flex-direction: row;

&:last-child, &:has(+ .fcitx-divider-paging) {
display: none;
}
}
}

Expand All @@ -95,14 +99,27 @@
display: flex;
}

.fcitx-divider {
/* stylelint-disable-next-line no-descending-specificity */
.fcitx-divider {
flex-direction: column;

/* If the last row (either temporary with more candidates to come, or final when scroll ends)
is not full, it takes care of the last gap. JS is responsible for full rows. */
&:last-child {
flex-grow: 1;
}

&:has(+ .fcitx-divider-paging) {
flex-grow: 1;

.fcitx-divider-middle {
block-size: 0;
}

.fcitx-divider-side {
flex-grow: 1;
}
}
}
}

Expand Down
10 changes: 7 additions & 3 deletions page/macos.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@
inline-size: 100%;
}

.fcitx-hoverables.fcitx-horizontal-scroll .fcitx-divider-middle {
block-size: 100%;
}

.fcitx-hoverables.fcitx-horizontal .fcitx-divider {
inline-size: 0;

&.fcitx-divider-paging {
inline-size: 1px;
}

.fcitx-divider-middle {
block-size: 100%;
.fcitx-divider-middle {
block-size: 100%;
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions tests/customize/test-color.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ test('Indicator', async ({ page }) => {
DarkMode: { OverrideDefault: 'True', AuxColor: '#FF0000' },
LightMode: { OverrideDefault: 'True', AuxColor: '#00FF00' },
})
await updateInputPanel(page, '', 'en', '')
await updateInputPanel(page, '', 'en')
await expect(auxUp).toHaveCSS('color', 'rgb(255, 0, 0)')

await page.evaluate(() => window.fcitx.setTheme(1))
Expand All @@ -31,7 +31,7 @@ test('Preedit text', async ({ page }) => {
DarkMode: { OverrideDefault: 'True', PreeditColorPreCaret: '#FF0000', PreeditColorPostCaret: '#00FF00' },
LightMode: { OverrideDefault: 'True', PreeditColorPreCaret: '#0000FF', PreeditColorPostCaret: '#FFFF00' },
})
await updateInputPanel(page, PRE_CARET + CARET + POST_CARET, '', '')
await updateInputPanel(page, PRE_CARET + CARET + POST_CARET)
await expect(preCaret).toHaveCSS('color', 'rgb(255, 0, 0)')
await expect(postCaret).toHaveCSS('color', 'rgb(0, 255, 0)')

Expand All @@ -49,7 +49,7 @@ test('Preedit caret', async ({ page }) => {
LightMode: { OverrideDefault: 'True', PreeditColorCaret: '#00FF00' },
}
await setStyle(page, colorStyle)
await updateInputPanel(page, PRE_CARET + CARET + POST_CARET, '', '')
await updateInputPanel(page, PRE_CARET + CARET + POST_CARET)
await expect(caret).toHaveCSS('background-color', 'rgb(255, 0, 0)')

await page.evaluate(() => window.fcitx.setTheme(1))
Expand All @@ -58,7 +58,7 @@ test('Preedit caret', async ({ page }) => {
await setStyle(page, { ...colorStyle, Caret: {
Style: 'Text',
} })
await updateInputPanel(page, PRE_CARET + CARET_TEXT + POST_CARET, '', '')
await updateInputPanel(page, PRE_CARET + CARET_TEXT + POST_CARET)
await expect(caret).toHaveCSS('color', 'rgb(0, 255, 0)')

await page.evaluate(() => window.fcitx.setTheme(2))
Expand Down
42 changes: 41 additions & 1 deletion tests/test-corner-case.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Page } from '@playwright/test'
import test, { expect } from '@playwright/test'
import { candidate, followHostTheme, getBox, hover, init, panel, setCandidates, setStyle, transparent } from './util'
import { candidate, followHostTheme, getBox, hover, init, panel, scrollExpand, setCandidates, setStyle, transparent, updateInputPanel } from './util'

test('Horizontal multi-line candidate', async ({ page }) => {
await init(page)
Expand Down Expand Up @@ -109,3 +109,43 @@ test.describe('Ghost stripe override zero margin', () => {
})
}
})

const shortPreedit = '短'
const longPreedit = '长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长'

test('Extremely long preedit horizontal', async ({ page }) => {
await init(page)

const lastDivider = page.locator('.fcitx-divider').nth(-2)
const pagingDivider = page.locator('.fcitx-divider').nth(-1)
await updateInputPanel(page, shortPreedit)
await setCandidates(page, [{ text: '1' }], 0, '', true)
await expect(pagingDivider).toHaveCSS('width', '1px')
await expect(lastDivider, 'Last divider is hidden by default').toHaveCSS('width', '0px')

await updateInputPanel(page, longPreedit)
await expect(pagingDivider).toHaveCSS('width', '1px')
const box = await getBox(lastDivider)
expect(box.width, 'Last divider has width if preedit is too long').toBeGreaterThan(400)
await expect(lastDivider.locator('.fcitx-divider-middle'), 'Middle part that has divider color is hidden').toHaveCSS('height', '0px')
const upperSide = lastDivider.locator('.fcitx-divider-side').first()
const lowerSide = lastDivider.locator('.fcitx-divider-side').last()
await expect(upperSide, 'Side parts split divider evenly').toHaveCSS('height', '14px')
await expect(lowerSide).toHaveCSS('height', '14px')
await expect(upperSide, 'Divider has panel color').toHaveCSS('background-color', 'rgba(40, 40, 40, 0.71)')
await expect(lowerSide).toHaveCSS('background-color', 'rgba(40, 40, 40, 0.71)')
})

test('Extremely long preedit scroll', async ({ page }) => {
await init(page)

const header = page.locator('.fcitx-header')
await updateInputPanel(page, '短')
await scrollExpand(page, ['1'])
await expect(header).toHaveCSS('width', '400px')
await expect(header).toHaveCSS('height', '28px')

await updateInputPanel(page, longPreedit)
await expect(header).toHaveCSS('width', '400px')
await expect(header, 'Width is restricted so text is wrapped').toHaveCSS('height', '36px')
})
5 changes: 5 additions & 0 deletions tests/test-generic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ test('HTML structure', async ({ page }) => {
<div class="fcitx-text">测试</div>
</div>
</div>
<div class="fcitx-divider">
<div class="fcitx-divider-side"></div>
<div class="fcitx-divider-middle"></div>
<div class="fcitx-divider-side"></div>
</div>
</div>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions tests/test-header.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ test('Square when single character auxUp for macOS 15', async ({ page }) => {
const pane = panel(page)
const side = 32

await updateInputPanel(page, '', 'A', '')
await updateInputPanel(page, '', 'A')
await expect(pane).toHaveText('A')
let box = await getBox(pane)
expect(box.width).toEqual(side)
expect(box.height).toEqual(side)

await updateInputPanel(page, '', '拼', '')
await updateInputPanel(page, '', '拼')
await expect(pane).toHaveText('拼')
box = await getBox(pane)
expect(box.width).toEqual(side)
Expand All @@ -24,9 +24,9 @@ test('No text shift when preedit grows', async ({ page }) => {
await init(page)
const preedit = panel(page).locator('.fcitx-preedit')

await updateInputPanel(page, 'c', '', '')
await updateInputPanel(page, 'c')
const cBox = await getTextBox(preedit, 0)
await updateInputPanel(page, 'ce', '', '')
await updateInputPanel(page, 'ce')
const ceBox = await getTextBox(preedit, 0)
expect(ceBox).toEqual(cBox)
})
8 changes: 4 additions & 4 deletions tests/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ export async function followHostTheme(page: Page, system: string, version: numbe
return setStyle(page, { Size: { OverrideDefault: 'False' } })
}

export function updateInputPanel(page: Page, preedit: string, auxUp: string, auxDown: string) {
export function updateInputPanel(page: Page, preedit: string, auxUp: string = '', auxDown: string = '') {
return page.evaluate(({ preedit, auxUp, auxDown }) =>
window.fcitx.updateInputPanel(preedit, auxUp, auxDown), { preedit, auxUp, auxDown })
}

export function setCandidates(page: Page, cands: Partial<Candidate>[], highlighted: number, markText = '') {
return page.evaluate(({ cands, highlighted, markText }) =>
window.fcitx.setCandidates(cands.map(cand => ({ text: 'text', label: '1', comment: 'comment', actions: [], ...cand })), highlighted, markText, false, false, false, 0, false, false), { cands, highlighted, markText })
export function setCandidates(page: Page, cands: Partial<Candidate>[], highlighted: number, markText = '', pageable = false) {
return page.evaluate(({ cands, highlighted, markText, pageable }) =>
window.fcitx.setCandidates(cands.map(cand => ({ text: 'text', label: '1', comment: 'comment', actions: [], ...cand })), highlighted, markText, pageable, false, false, 0, false, false), { cands, highlighted, markText, pageable })
}

export async function scrollExpand(page: Page, texts: string[]) {
Expand Down