Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
47 changes: 47 additions & 0 deletions playwright/rendering-modes/core.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ const readLatestWorkspaceSnapshot = async (page: import('@playwright/test').Page

return {
renderMode: typeof latest.renderMode === 'string' ? latest.renderMode : '',
fontCssUrl: typeof latest.fontCssUrl === 'string' ? latest.fontCssUrl : '',
styleLanguage:
typeof primaryStylesTab?.language === 'string' ? primaryStylesTab.language : '',
}
Expand All @@ -147,6 +148,12 @@ const readPreviewUserStyleText = async (page: import('@playwright/test').Page) =
})
}

const readPreviewBodyFontFamily = async (page: import('@playwright/test').Page) => {
return getPreviewFrame(page)
.locator('html')
.evaluate(() => getComputedStyle(document.body).fontFamily || '')
}

test.beforeEach(async ({ page }) => {
await resetWorkbenchStorage(page)
})
Expand Down Expand Up @@ -228,6 +235,46 @@ test('reactJsx tag interpolation renders memo and forwardRef components', async
.toBe(0)
})

test('workspace font CSS URL applies to preview and persists per workspace', async ({
page,
}) => {
await waitForInitialRender(page)

await page.getByRole('button', { name: 'Workspaces' }).click()

const fontCssUrlInput = page.getByRole('textbox', {
name: 'Workspace Font CSS URL',
})
await fontCssUrlInput.fill(
'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap',
)
await fontCssUrlInput.press('Tab')

await expect
.poll(async () => (await readPreviewBodyFontFamily(page)).toLowerCase())
.toContain('ibm plex sans')

Comment thread
knightedcodemonkey marked this conversation as resolved.
await expect
.poll(async () => {
const snapshot = await readLatestWorkspaceSnapshot(page)
return snapshot?.fontCssUrl ?? ''
})
.toBe(
'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap',
)

await page.reload()
await waitForInitialRender(page)
await page.getByRole('button', { name: 'Workspaces' }).click()

await expect(fontCssUrlInput).toHaveValue(
'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap',
)
await expect
.poll(async () => (await readPreviewBodyFontFamily(page)).toLowerCase())
.toContain('ibm plex sans')
})

test('react mode keeps App.ts entry but surfaces rename guidance until compatible', async ({
page,
}) => {
Expand Down
40 changes: 40 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ import { createGitHubPrDrawer } from './modules/github/pr/drawer/controller/crea
import { createLayoutThemeController } from './modules/ui/layout-theme.js'
import { createLintDiagnosticsController } from './modules/diagnostics/lint-diagnostics.js'
import { createPreviewBackgroundController } from './modules/preview/preview-background.js'
import {
createPreviewFontController,
defaultPreviewFontCssUrl,
normalizePreviewFontCssUrl,
} from './modules/preview/preview-font.js'
import { getReactEntryTabCompatibilityError } from './modules/preview/preview-entry-resolver.js'
import { createRenderRuntimeController } from './modules/preview/render-runtime.js'
import { createTypeDiagnosticsController } from './modules/diagnostics/type-diagnostics.js'
Expand Down Expand Up @@ -151,6 +156,8 @@ const workspacesInitialize = document.getElementById('workspaces-initialize')
const workspacesShare = document.getElementById('workspaces-share')
const workspacesNew = document.getElementById('workspaces-new')
const workspacesSelect = document.getElementById('workspaces-select')
const workspacesFontCssUrlInput = document.getElementById('workspaces-font-css-url')
const workspacesFontCssUrlLoad = document.getElementById('workspaces-font-css-url-load')
const workspacesOpen = document.getElementById('workspaces-open')
const workspacesRename = document.getElementById('workspaces-rename')
const workspacesRemove = document.getElementById('workspaces-remove')
Expand Down Expand Up @@ -349,6 +356,20 @@ const previewBackground = createPreviewBackgroundController({
},
})

const previewFont = createPreviewFontController({
previewFontCssUrlInput: workspacesFontCssUrlInput,
getDefaultPreviewFontCssUrl: () => defaultPreviewFontCssUrl,
onFontConfigChange: ({ fontCssUrl, fontFamily }) => {
if (renderRuntime && typeof renderRuntime.updatePreviewFont === 'function') {
renderRuntime.updatePreviewFont({ fontCssUrl, fontFamily })
}

if (typeof queueWorkspaceSave === 'function') {
queueWorkspaceSave()
}
},
})

const layoutTheme = createLayoutThemeController({
appThemeButtons,
syncPreviewBackgroundPickerFromTheme: () =>
Expand Down Expand Up @@ -757,7 +778,9 @@ const workspaceSyncController = createWorkspaceSyncController({
getActiveWorkspaceRecordId: () => activeWorkspaceRecordId,
getActiveWorkspaceCreatedAt: () => activeWorkspaceCreatedAt,
getRenderModeValue: () => renderMode.value,
getPreviewFontCssUrlValue: () => previewFont.getPreviewFontCssUrl(),
normalizeRenderMode: mode => normalizeRenderMode(mode),
normalizePreviewFontCssUrl,
})

const getTypecheckSourcePath = () =>
Expand Down Expand Up @@ -891,10 +914,15 @@ const {
workspaceTabsState,
resolveWorkspaceActiveTabId,
normalizeRenderMode: mode => normalizeRenderMode(mode),
normalizePreviewFontCssUrl,
getRenderModeValue: () => renderMode.value,
getPreviewFontCssUrlValue: () => previewFont.getPreviewFontCssUrl(),
setRenderModeValue: value => {
renderMode.value = value
},
setPreviewFontCssUrlValue: (value, options) => {
previewFont.applyPreviewFontCssUrl(value, options)
},
getActiveWorkspaceTab,
onActiveWorkspaceTabChange: (_tab, { changed } = {}) => {
syncDiagnosticsDrawerLayout()
Expand Down Expand Up @@ -1201,6 +1229,8 @@ const githubWorkflows = createGitHubWorkflowsSetup({
workspacesShare,
workspacesNew,
workspacesSelect,
workspacesFontCssUrlInput,
workspacesFontCssUrlLoad,
workspacesOpen,
workspacesRename,
workspacesRemove,
Expand All @@ -1220,6 +1250,14 @@ const githubWorkflows = createGitHubWorkflowsSetup({
listLocalContextRecords,
refreshLocalContextOptions,
applyWorkspaceRecord,
applyWorkspaceFontCssUrl: async fontCssUrl => {
previewFont.applyPreviewFontCssUrl(fontCssUrl, {
emitChange: true,
syncInputValue: true,
})
await flushWorkspaceSave({ preserveRecordId: true })
return true
Comment thread
knightedcodemonkey marked this conversation as resolved.
Outdated
},
syncActiveWorkspaceRepositoryScope,
forkWorkspaceFromCurrentState,
flushWorkspaceSave,
Expand Down Expand Up @@ -1424,6 +1462,7 @@ const runtimeCoreOptions = createRuntimeCoreOptions({
getRenderRuntime: () => renderRuntime,
getPreviewHost: () => previewHost,
previewBackground,
previewFont,
clearDiagnosticsScope,
clearConfirmDialog,
clearConfirmTitle,
Expand Down Expand Up @@ -1602,6 +1641,7 @@ bindAppEventsAndStart({
typeDiagnostics,
clipboardSupported,
previewBackground,
previewFont,
initializeCodeEditors,
},
})
20 changes: 20 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,26 @@ <h2 id="workspaces-title">Workspaces</h2>
</div>
</div>

<div class="workspaces-drawer__font-row">
<label
class="github-pr-field github-pr-field--full"
for="workspaces-font-css-url"
>
<span>Font CSS URL</span>
<input
id="workspaces-font-css-url"
type="text"
autocomplete="off"
spellcheck="false"
aria-label="Workspace Font CSS URL"
Comment thread
knightedcodemonkey marked this conversation as resolved.
Outdated
placeholder="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap"
/>
</label>
<button class="render-button" id="workspaces-font-css-url-load" type="button">
Load
</button>
</div>

<label class="github-pr-field github-pr-field--full" for="workspaces-select">
<span>Workspace</span>
<select id="workspaces-select" aria-label="Stored workspace">
Expand Down
2 changes: 2 additions & 0 deletions src/modules/app-core/app-bindings-startup.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const bindAppEventsAndStart = ({
typeDiagnostics,
clipboardSupported,
previewBackground,
previewFont,
initializeCodeEditors,
} = startup

Expand Down Expand Up @@ -495,6 +496,7 @@ const bindAppEventsAndStart = ({
syncDiagnosticsDrawerLayout()
renderRuntime.setStyleCompiling(false)
setCdnLoading(true)
previewFont.initializePreviewFontInput()
previewBackground.initializePreviewBackgroundPicker()
const workspaceRestoreReady = (async () => {
try {
Expand Down
5 changes: 5 additions & 0 deletions src/modules/app-core/app-composition-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const createRuntimeCoreOptions = ({
getRenderRuntime,
getPreviewHost,
previewBackground,
previewFont,
clearDiagnosticsScope,
clearConfirmDialog,
clearConfirmTitle,
Expand Down Expand Up @@ -99,6 +100,8 @@ const createRuntimeCoreOptions = ({
getWorkspaceTabs: () => buildWorkspaceTabsSnapshot(),
getPreviewHost,
getPreviewBackgroundColor: () => previewBackground.getPreviewBackgroundColor(),
getPreviewFontCssUrl: () => previewFont.getPreviewFontCssUrl(),
getPreviewFontFamily: () => previewFont.getPreviewFontFamily(),
clearStyleDiagnostics: () => clearDiagnosticsScope('styles'),
setStyleDiagnosticsDetails,
setStatus,
Expand Down Expand Up @@ -280,6 +283,7 @@ const createAppStartupBindingsOptions = ({
setTypeDiagnosticsDetails,
setCdnLoading,
previewBackground,
previewFont,
loadPreferredWorkspaceContext,
initializeCodeEditors,
getActiveWorkspaceTab,
Expand Down Expand Up @@ -376,6 +380,7 @@ const createAppStartupBindingsOptions = ({
setTypeDiagnosticsDetails,
setCdnLoading,
previewBackground,
previewFont,
loadPreferredWorkspaceContext,
initializeCodeEditors,
getActiveWorkspaceTab,
Expand Down
1 change: 1 addition & 0 deletions src/modules/app-core/github-workflows-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const createGitHubWorkflowsSetup = ({
getWorkspaceTabContexts: actions.getWorkspaceTabContexts,
applyWorkspaceTabContent: actions.applyWorkspaceTabContent,
scheduleRender: actions.scheduleRender,
applyWorkspaceFontCssUrl: workspace.applyWorkspaceFontCssUrl,
})

export { createGitHubWorkflowsSetup }
27 changes: 27 additions & 0 deletions src/modules/app-core/github-workflows.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const initializeGitHubWorkflows = ({
workspacesShare,
workspacesNew,
workspacesSelect,
workspacesFontCssUrlInput,
workspacesFontCssUrlLoad,
workspacesOpen,
workspacesRename,
workspacesRemove,
Expand All @@ -59,6 +61,7 @@ const initializeGitHubWorkflows = ({
listLocalContextRecords,
refreshLocalContextOptions,
applyWorkspaceRecord,
applyWorkspaceFontCssUrl,
syncActiveWorkspaceRepositoryScope,
forkWorkspaceFromCurrentState,
flushWorkspaceSave,
Expand Down Expand Up @@ -432,6 +435,8 @@ const initializeGitHubWorkflows = ({
shareButton: workspacesShare,
newButton: workspacesNew,
selectInput: workspacesSelect,
fontCssUrlInput: workspacesFontCssUrlInput,
fontCssUrlLoadButton: workspacesFontCssUrlLoad,
openButton: workspacesOpen,
renameButton: workspacesRename,
removeButton: workspacesRemove,
Expand Down Expand Up @@ -540,8 +545,30 @@ const initializeGitHubWorkflows = ({
return false
}
},
onLoadFontCssUrl: async fontCssUrl => {
if (typeof applyWorkspaceFontCssUrl !== 'function') {
return false
}

try {
await applyWorkspaceFontCssUrl(fontCssUrl)
if (typeof scheduleRender === 'function') {
await Promise.resolve(scheduleRender())
}
return true
} catch {
workspacesDrawerController?.setStatus('Could not load font CSS URL.', 'error')
return false
}
},
onOpenSelected: async workspaceId => {
try {
try {
await flushWorkspaceSave?.({ preserveRecordId: true })
} catch {
/* Save failures are surfaced via saver onError; continue with open attempt. */
}

const record = await workspaceStorage.getWorkspaceById(workspaceId)
if (!record) {
await refreshLocalContextOptions()
Expand Down
18 changes: 18 additions & 0 deletions src/modules/app-core/workspace-context-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ const createWorkspaceContextController = ({
workspaceTabsState,
resolveWorkspaceActiveTabId,
normalizeRenderMode,
normalizePreviewFontCssUrl,
getRenderModeValue,
getPreviewFontCssUrlValue,
setRenderModeValue,
setPreviewFontCssUrlValue,
onWorkspaceRecordApplied,
getActiveWorkspaceTab,
loadWorkspaceTabIntoEditor,
Expand Down Expand Up @@ -140,6 +143,21 @@ const createWorkspaceContextController = ({
setRenderModeValue(nextRenderMode)
}

if (typeof setPreviewFontCssUrlValue === 'function') {
const nextPreviewFontCssUrl = normalizePreviewFontCssUrl(
workspace.fontCssUrl ?? workspace.previewFontCssUrl,
)
const currentPreviewFontCssUrl = normalizePreviewFontCssUrl(
getPreviewFontCssUrlValue?.(),
)
if (currentPreviewFontCssUrl !== nextPreviewFontCssUrl) {
setPreviewFontCssUrlValue(nextPreviewFontCssUrl, {
emitChange: true,
syncInputValue: true,
})
}
}

const activeTab = getActiveWorkspaceTab()
if (activeTab) {
loadWorkspaceTabIntoEditor(activeTab)
Expand Down
6 changes: 6 additions & 0 deletions src/modules/app-core/workspace-controllers-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ const createWorkspaceControllersSetup = ({
workspaceTabsState,
resolveWorkspaceActiveTabId,
normalizeRenderMode,
normalizePreviewFontCssUrl,
getRenderModeValue,
getPreviewFontCssUrlValue,
setRenderModeValue,
setPreviewFontCssUrlValue,
onWorkspaceRecordApplied,
getActiveWorkspaceTab,
onActiveWorkspaceTabChange,
Expand Down Expand Up @@ -222,8 +225,11 @@ const createWorkspaceControllersSetup = ({
workspaceTabsState,
resolveWorkspaceActiveTabId,
normalizeRenderMode,
normalizePreviewFontCssUrl,
getRenderModeValue,
getPreviewFontCssUrlValue,
setRenderModeValue,
setPreviewFontCssUrlValue,
onWorkspaceRecordApplied,
getActiveWorkspaceTab,
loadWorkspaceTabIntoEditor,
Expand Down
3 changes: 3 additions & 0 deletions src/modules/app-core/workspace-sync-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const createWorkspaceSyncController = ({
getActiveWorkspaceRecordId,
getActiveWorkspaceCreatedAt,
getRenderModeValue,
getPreviewFontCssUrlValue = () => '',
normalizeRenderMode,
normalizePreviewFontCssUrl = value => value,
}) => {
const removedWorkspaceTabPathsByWorkspaceKey = new Map()

Expand Down Expand Up @@ -399,6 +401,7 @@ const createWorkspaceSyncController = ({
prTitle: normalizedPrTitle,
prContextState: requestedPrContextState,
renderMode: normalizeRenderMode(getRenderModeValue()),
fontCssUrl: normalizePreviewFontCssUrl(getPreviewFontCssUrlValue()),
tabs: buildWorkspaceTabsSnapshot(),
activeTabId: workspaceTabsState.getActiveTabId(),
createdAt: getActiveWorkspaceCreatedAt() ?? Date.now(),
Expand Down
Loading
Loading