Skip to content

Commit ff06bbc

Browse files
refactor: address pr comments.
1 parent f4f3b35 commit ff06bbc

6 files changed

Lines changed: 83 additions & 69 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,4 @@ Never:
102102
- Edit generated output folders unless explicitly requested.
103103
- Modify node_modules or lockfiles unless explicitly requested.
104104
- Reintroduce cross-workspace overwrite/delete behavior with any changes.
105+
- Use eslint disable comments.

playwright/rendering-modes/core.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,12 @@ test('workspace font CSS URL applies to preview and persists per workspace', asy
243243
await page.getByRole('button', { name: 'Workspaces' }).click()
244244

245245
const fontCssUrlInput = page.getByRole('textbox', {
246-
name: 'Workspace Google Fonts CSS URL',
246+
name: 'Workspace font stylesheet URL',
247247
})
248248
await fontCssUrlInput.fill(
249249
'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap',
250250
)
251-
await fontCssUrlInput.press('Tab')
251+
await page.getByRole('button', { name: 'Load', exact: true }).click()
252252

253253
await expect
254254
.poll(async () => (await readPreviewBodyFontFamily(page)).toLowerCase())

src/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -811,14 +811,14 @@ <h2 id="workspaces-title">Workspaces</h2>
811811
class="github-pr-field github-pr-field--full"
812812
for="workspaces-font-css-url"
813813
>
814-
<span>Google Fonts CSS URL</span>
814+
<span>Font Stylesheet URL</span>
815815
<input
816816
id="workspaces-font-css-url"
817817
type="text"
818818
autocomplete="off"
819819
spellcheck="false"
820-
aria-label="Workspace Google Fonts CSS URL"
821-
placeholder="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&display=swap"
820+
aria-label="Workspace font stylesheet URL"
821+
placeholder="https://cdn.example.com/fonts.css"
822822
/>
823823
</label>
824824
<button class="render-button" id="workspaces-font-css-url-load" type="button">

src/modules/preview-runtime/iframe-preview-executor.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,13 @@ const createIframeShellDocument = ({ channelId, parentOrigin, importMap }) => {
115115
}
116116
}
117117
118-
const __knightedToBaseStyles = (hostPadding, fontCssUrl = '') => {
118+
const __knightedToBaseStyles = hostPadding => {
119119
const resolvedPadding =
120120
typeof hostPadding === 'string' && hostPadding.trim().length > 0
121121
? hostPadding.trim()
122122
: '18px'
123-
const resolvedFontCssUrl = __knightedNormalizeFontCssUrl(fontCssUrl)
124-
const escapedFontCssUrl = resolvedFontCssUrl.replace(/"/g, '\\"')
125-
const fontImportRule = resolvedFontCssUrl
126-
? '@import url("' + escapedFontCssUrl + '");'
127-
: ''
128123
129124
return [
130-
fontImportRule,
131125
'html, body {',
132126
' margin: 0;',
133127
' min-height: 100%;',
@@ -151,6 +145,50 @@ const createIframeShellDocument = ({ channelId, parentOrigin, importMap }) => {
151145
].join('\\n')
152146
}
153147
148+
const __knightedSyncFontStylesheetLink = ({
149+
normalizedFontCssUrl = '',
150+
baseStyleElement,
151+
}) => {
152+
const linkId = 'knighted-preview-font-stylesheet'
153+
const existingLink = document.getElementById(linkId)
154+
const hasNormalizedFontCssUrl =
155+
typeof normalizedFontCssUrl === 'string' &&
156+
normalizedFontCssUrl.length > 0
157+
158+
if (!hasNormalizedFontCssUrl) {
159+
if (existingLink instanceof HTMLLinkElement) {
160+
existingLink.remove()
161+
}
162+
return
163+
}
164+
165+
let linkElement = existingLink
166+
if (!(linkElement instanceof HTMLLinkElement)) {
167+
linkElement = document.createElement('link')
168+
linkElement.id = linkId
169+
linkElement.rel = 'stylesheet'
170+
}
171+
172+
if (linkElement.getAttribute('href') !== normalizedFontCssUrl) {
173+
linkElement.setAttribute('href', normalizedFontCssUrl)
174+
}
175+
176+
const shouldInsertBeforeBase =
177+
baseStyleElement instanceof HTMLStyleElement &&
178+
baseStyleElement.parentNode === document.head
179+
180+
if (shouldInsertBeforeBase) {
181+
if (linkElement !== baseStyleElement.previousSibling) {
182+
document.head.insertBefore(linkElement, baseStyleElement)
183+
}
184+
return
185+
}
186+
187+
if (linkElement.parentNode !== document.head) {
188+
document.head.append(linkElement)
189+
}
190+
}
191+
154192
const __knightedApplyVisualConfig = ({
155193
cssText = '',
156194
userStyleSheets = [],
@@ -239,9 +277,13 @@ const createIframeShellDocument = ({ channelId, parentOrigin, importMap }) => {
239277
document.head.insertBefore(baseStyleElement, firstUserStyleElement)
240278
}
241279
280+
__knightedSyncFontStylesheetLink({
281+
normalizedFontCssUrl: __knightedState.visualConfig.fontCssUrl,
282+
baseStyleElement,
283+
})
284+
242285
baseStyleElement.textContent = __knightedToBaseStyles(
243286
__knightedState.visualConfig.hostPadding,
244-
__knightedState.visualConfig.fontCssUrl,
245287
)
246288
247289
for (let index = 0; index < userStyleElements.length; index += 1) {

src/modules/preview/preview-font.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ export const createPreviewFontController = ({
9292
emitChange: true,
9393
syncInputValue: true,
9494
})
95-
96-
previewFontCssUrlInput.addEventListener('change', () => {
97-
applyPreviewFontCssUrl(previewFontCssUrlInput.value, {
98-
emitChange: true,
99-
syncInputValue: true,
100-
})
101-
})
10295
}
10396

10497
return {

src/modules/workspace/workspace-storage.js

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { cdnImports, importFromCdnWithFallback } from '../cdn.js'
2-
import { defaultFontCssUrl, normalizeFontCssUrl } from '../font-css-url.js'
2+
import { normalizeFontCssUrl } from '../font-css-url.js'
33
import { toWorkspaceRecordKey } from './workspace-tab-helpers.js'
44

55
const workspaceDbName = 'knighted-develop-workspaces'
@@ -24,8 +24,8 @@ const toTabRole = value => {
2424

2525
const normalizeRenderMode = value => (value === 'react' ? 'react' : 'dom')
2626

27-
const normalizePreviewFontCssUrl = value =>
28-
normalizeFontCssUrl(value, { fallback: defaultFontCssUrl })
27+
const normalizeStoredPreviewFontCssUrl = value =>
28+
normalizeFontCssUrl(value, { fallback: '' })
2929

3030
const toSyncTimestamp = value =>
3131
Number.isFinite(value) && value > 0 ? Math.max(0, Number(value)) : null
@@ -116,7 +116,9 @@ const normalizeWorkspaceRecord = record => {
116116
? record.prContextState.trim()
117117
: 'inactive',
118118
renderMode: normalizeRenderMode(record.renderMode),
119-
fontCssUrl: normalizePreviewFontCssUrl(record.fontCssUrl ?? record.previewFontCssUrl),
119+
fontCssUrl: normalizeStoredPreviewFontCssUrl(
120+
record.fontCssUrl ?? record.previewFontCssUrl,
121+
),
120122
tabs: normalizedTabs,
121123
activeTabId: typeof record.activeTabId === 'string' ? record.activeTabId : null,
122124
schemaVersion:
@@ -173,62 +175,38 @@ const hasOwnRecordValue = (record, key) =>
173175
Boolean(record) && Object.prototype.hasOwnProperty.call(record, key)
174176

175177
const backfillWorkspaceFontCssUrlField = async db => {
176-
const records = await db.getAllFromIndex(
177-
workspaceStoreName,
178-
workspaceByLastModifiedIndexName,
179-
)
180-
if (!Array.isArray(records) || records.length === 0) {
181-
return
182-
}
183-
184-
const candidateRecordIds = records
185-
.filter(record => {
186-
if (!record || typeof record !== 'object') {
187-
return false
188-
}
178+
const transaction = db.transaction(workspaceStoreName, 'readwrite')
179+
const index = transaction.store.index(workspaceByLastModifiedIndexName)
180+
const processCursor = async cursor => {
181+
if (!cursor) {
182+
return
183+
}
189184

190-
const normalizedFontCssUrl = normalizePreviewFontCssUrl(
185+
const record = cursor.value
186+
if (record && typeof record === 'object') {
187+
const normalizedFontCssUrl = normalizeStoredPreviewFontCssUrl(
191188
record.fontCssUrl ?? record.previewFontCssUrl,
192189
)
193-
194-
return (
190+
const shouldPersistFontCssUrl =
195191
!hasOwnRecordValue(record, 'fontCssUrl') ||
196192
typeof record.fontCssUrl !== 'string' ||
197193
record.fontCssUrl !== normalizedFontCssUrl
198-
)
199-
})
200-
.map(record => (typeof record?.id === 'string' ? record.id : ''))
201-
.filter(Boolean)
202-
203-
if (candidateRecordIds.length === 0) {
204-
return
205-
}
206194

207-
await Promise.all(
208-
candidateRecordIds.map(async recordId => {
209-
const record = await db.get(workspaceStoreName, recordId)
210-
if (!record || typeof record !== 'object') {
211-
return
195+
if (shouldPersistFontCssUrl) {
196+
await cursor.update({
197+
...record,
198+
fontCssUrl: normalizedFontCssUrl,
199+
})
212200
}
201+
}
213202

214-
const normalizedFontCssUrl = normalizePreviewFontCssUrl(
215-
record.fontCssUrl ?? record.previewFontCssUrl,
216-
)
217-
const shouldPersistFontCssUrl =
218-
!hasOwnRecordValue(record, 'fontCssUrl') ||
219-
typeof record.fontCssUrl !== 'string' ||
220-
record.fontCssUrl !== normalizedFontCssUrl
203+
const nextCursor = await cursor.continue()
204+
await processCursor(nextCursor)
205+
}
221206

222-
if (!shouldPersistFontCssUrl) {
223-
return
224-
}
207+
await processCursor(await index.openCursor())
225208

226-
await db.put(workspaceStoreName, {
227-
...record,
228-
fontCssUrl: normalizedFontCssUrl,
229-
})
230-
}),
231-
)
209+
await transaction.done
232210
}
233211

234212
export const createWorkspaceStorageAdapter = ({ loadRuntime } = {}) => {

0 commit comments

Comments
 (0)