@tldraw/editor 3.12.0-canary.b1ca2fcd8c7d → 3.12.0-canary.c986b5185d4e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/editor/managers/FontManager.js +1 -1
- package/dist-cjs/lib/editor/managers/FontManager.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/editor/managers/FontManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/FontManager.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/lib/editor/managers/FontManager.ts +1 -1
- package/src/version.ts +3 -3
package/dist-cjs/index.js
CHANGED
|
@@ -34,7 +34,7 @@ class FontManager {
|
|
|
34
34
|
const shapeUtil = this.editor.getShapeUtil(shape);
|
|
35
35
|
return shapeUtil.getFontFaces(shape);
|
|
36
36
|
},
|
|
37
|
-
{ areResultsEqual: import_utils.areArraysShallowEqual }
|
|
37
|
+
{ areResultsEqual: import_utils.areArraysShallowEqual, areRecordsEqual: (a, b) => a.props === b.props }
|
|
38
38
|
);
|
|
39
39
|
this.shapeFontLoadStateCache = editor.store.createCache(
|
|
40
40
|
(id) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/editor/managers/FontManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { computed, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport { AtomMap } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport {\n\tareArraysShallowEqual,\n\tcompact,\n\tFileHelpers,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n} from '@tldraw/utils'\nimport { Editor } from '../Editor'\n\n/**\n * Represents the `src` property of a {@link TLFontFace}.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`} for details of the properties here.\n * @public\n */\nexport interface TLFontFaceSource {\n\t/**\n\t * A URL from which to load the font. If the value here is a key in\n\t * {@link tldraw#TLEditorAssetUrls.fonts}, the value from there will be used instead.\n\t */\n\turl: string\n\tformat?: string\n\ttech?: string\n}\n\n/**\n * A font face that can be used in the editor. The properties of this are largely the same as the\n * ones in the\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face | css `@font-face` rule}.\n * @public\n */\nexport interface TLFontFace {\n\t/**\n\t * How this font can be referred to in CSS.\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family | `font-family`}.\n\t */\n\treadonly family: string\n\t/**\n\t * The source of the font. This\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`}.\n\t */\n\treadonly src: TLFontFaceSource\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/ascent-override | `ascent-override`}.\n\t */\n\treadonly ascentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/descent-override | `descent-override`}.\n\t */\n\treadonly descentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch | `font-stretch`}.\n\t */\n\treadonly stretch?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-style | `font-style`}.\n\t */\n\treadonly style?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight | `font-weight`}.\n\t */\n\treadonly weight?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings | `font-feature-settings`}.\n\t */\n\treadonly featureSettings?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/line-gap-override | `line-gap-override`}.\n\t */\n\treadonly lineGapOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range | `unicode-range`}.\n\t */\n\treadonly unicodeRange?: string\n}\n\ninterface FontState {\n\treadonly state: 'loading' | 'ready' | 'error'\n\treadonly instance: FontFace\n\treadonly loadingPromise: Promise<void>\n}\n\n/** @public */\nexport class FontManager {\n\tconstructor(\n\t\tprivate readonly editor: Editor,\n\t\tprivate readonly assetUrls?: { [key: string]: string | undefined }\n\t) {\n\t\tthis.shapeFontFacesCache = editor.store.createComputedCache(\n\t\t\t'shape font faces',\n\t\t\t(shape: TLShape) => {\n\t\t\t\tconst shapeUtil = this.editor.getShapeUtil(shape)\n\t\t\t\treturn shapeUtil.getFontFaces(shape)\n\t\t\t},\n\t\t\t{ areResultsEqual: areArraysShallowEqual }\n\t\t)\n\n\t\tthis.shapeFontLoadStateCache = editor.store.createCache<(FontState | null)[], TLShape>(\n\t\t\t(id: TLShapeId) => {\n\t\t\t\tconst fontFacesComputed = computed('font faces', () => this.getShapeFontFaces(id))\n\t\t\t\treturn computed(\n\t\t\t\t\t'font load state',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst states = fontFacesComputed.get().map((face) => this.getFontState(face))\n\t\t\t\t\t\treturn states\n\t\t\t\t\t},\n\t\t\t\t\t{ isEqual: areArraysShallowEqual }\n\t\t\t\t)\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate readonly shapeFontFacesCache\n\tprivate readonly shapeFontLoadStateCache\n\n\tgetShapeFontFaces(shape: TLShape | TLShapeId): TLFontFace[] {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.shapeFontFacesCache.get(shapeId) ?? EMPTY_ARRAY\n\t}\n\n\ttrackFontsForShape(shape: TLShape | TLShapeId) {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\tthis.shapeFontLoadStateCache.get(shapeId)\n\t}\n\n\tasync loadRequiredFontsForCurrentPage(limit = Infinity) {\n\t\tconst neededFonts = new Set<TLFontFace>()\n\t\tfor (const shapeId of this.editor.getCurrentPageShapeIds()) {\n\t\t\tfor (const font of this.getShapeFontFaces(this.editor.getShape(shapeId)!)) {\n\t\t\t\tneededFonts.add(font)\n\t\t\t}\n\t\t}\n\n\t\tif (neededFonts.size > limit) {\n\t\t\treturn\n\t\t}\n\n\t\tconst promises = Array.from(neededFonts, (font) => this.ensureFontIsLoaded(font))\n\t\tawait Promise.all(promises)\n\t}\n\n\tprivate readonly fontStates = new AtomMap<TLFontFace, FontState>('font states')\n\tprivate getFontState(font: TLFontFace): FontState | null {\n\t\treturn this.fontStates.get(font) ?? null\n\t}\n\n\tensureFontIsLoaded(font: TLFontFace): Promise<void> {\n\t\tconst existingState = this.getFontState(font)\n\t\tif (existingState) return existingState.loadingPromise\n\n\t\tconst instance = this.findOrCreateFontFace(font)\n\t\tconst state: FontState = {\n\t\t\tstate: 'loading',\n\t\t\tinstance,\n\t\t\tloadingPromise: instance\n\t\t\t\t.load()\n\t\t\t\t.then(() => {\n\t\t\t\t\tdocument.fonts.add(instance)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'ready' }))\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(err)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'error' }))\n\t\t\t\t}),\n\t\t}\n\n\t\tthis.fontStates.set(font, state)\n\t\treturn state.loadingPromise\n\t}\n\n\tprivate fontsToLoad = new Set<TLFontFace>()\n\trequestFonts(fonts: TLFontFace[]) {\n\t\tif (!this.fontsToLoad.size) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tif (this.editor.isDisposed) return\n\t\t\t\tconst toLoad = this.fontsToLoad\n\t\t\t\tthis.fontsToLoad = new Set()\n\t\t\t\ttransact(() => {\n\t\t\t\t\tfor (const font of toLoad) {\n\t\t\t\t\t\tthis.ensureFontIsLoaded(font)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t\tfor (const font of fonts) {\n\t\t\tthis.fontsToLoad.add(font)\n\t\t}\n\t}\n\n\tprivate findOrCreateFontFace(font: TLFontFace) {\n\t\tfor (const existing of document.fonts) {\n\t\t\tif (\n\t\t\t\texisting.family === font.family &&\n\t\t\t\tobjectMapEntries(defaultFontFaceDescriptors).every(\n\t\t\t\t\t([key, defaultValue]) => existing[key] === (font[key] ?? defaultValue)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst instance = new FontFace(font.family, `url(${JSON.stringify(url)})`, {\n\t\t\t...mapObjectMapValues(defaultFontFaceDescriptors, (key) => font[key]),\n\t\t\tdisplay: 'swap',\n\t\t})\n\n\t\tdocument.fonts.add(instance)\n\n\t\treturn instance\n\t}\n\n\tasync toEmbeddedCssDeclaration(font: TLFontFace) {\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst dataUrl = await FileHelpers.urlToDataUrl(url)\n\n\t\tconst src = compact([\n\t\t\t`url(\"${dataUrl}\")`,\n\t\t\tfont.src.format ? `format(${font.src.format})` : null,\n\t\t\tfont.src.tech ? `tech(${font.src.tech})` : null,\n\t\t]).join(' ')\n\t\treturn compact([\n\t\t\t`@font-face {`,\n\t\t\t` font-family: \"${font.family}\";`,\n\t\t\tfont.ascentOverride ? ` ascent-override: ${font.ascentOverride};` : null,\n\t\t\tfont.descentOverride ? ` descent-override: ${font.descentOverride};` : null,\n\t\t\tfont.stretch ? ` font-stretch: ${font.stretch};` : null,\n\t\t\tfont.style ? ` font-style: ${font.style};` : null,\n\t\t\tfont.weight ? ` font-weight: ${font.weight};` : null,\n\t\t\tfont.featureSettings ? ` font-feature-settings: ${font.featureSettings};` : null,\n\t\t\tfont.lineGapOverride ? ` line-gap-override: ${font.lineGapOverride};` : null,\n\t\t\tfont.unicodeRange ? ` unicode-range: ${font.unicodeRange};` : null,\n\t\t\t` src: ${src};`,\n\t\t\t`}`,\n\t\t]).join('\\n')\n\t}\n}\n\n// From https://drafts.csswg.org/css-font-loading/#fontface-interface\nconst defaultFontFaceDescriptors = {\n\tstyle: 'normal',\n\tweight: 'normal',\n\tstretch: 'normal',\n\tunicodeRange: 'U+0-10FFFF',\n\tfeatureSettings: 'normal',\n\tascentOverride: 'normal',\n\tdescentOverride: 'normal',\n\tlineGapOverride: 'normal',\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAgD;AAChD,mBAAwB;AAExB,mBAMO;AA4EA,MAAM,YAAY;AAAA,EACxB,YACkB,QACA,WAChB;AAFgB;AACA;AAEjB,SAAK,sBAAsB,OAAO,MAAM;AAAA,MACvC;AAAA,MACA,CAAC,UAAmB;AACnB,cAAM,YAAY,KAAK,OAAO,aAAa,KAAK;AAChD,eAAO,UAAU,aAAa,KAAK;AAAA,MACpC;AAAA,MACA,EAAE,iBAAiB,
|
|
4
|
+
"sourcesContent": ["import { computed, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport { AtomMap } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport {\n\tareArraysShallowEqual,\n\tcompact,\n\tFileHelpers,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n} from '@tldraw/utils'\nimport { Editor } from '../Editor'\n\n/**\n * Represents the `src` property of a {@link TLFontFace}.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`} for details of the properties here.\n * @public\n */\nexport interface TLFontFaceSource {\n\t/**\n\t * A URL from which to load the font. If the value here is a key in\n\t * {@link tldraw#TLEditorAssetUrls.fonts}, the value from there will be used instead.\n\t */\n\turl: string\n\tformat?: string\n\ttech?: string\n}\n\n/**\n * A font face that can be used in the editor. The properties of this are largely the same as the\n * ones in the\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face | css `@font-face` rule}.\n * @public\n */\nexport interface TLFontFace {\n\t/**\n\t * How this font can be referred to in CSS.\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family | `font-family`}.\n\t */\n\treadonly family: string\n\t/**\n\t * The source of the font. This\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`}.\n\t */\n\treadonly src: TLFontFaceSource\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/ascent-override | `ascent-override`}.\n\t */\n\treadonly ascentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/descent-override | `descent-override`}.\n\t */\n\treadonly descentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch | `font-stretch`}.\n\t */\n\treadonly stretch?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-style | `font-style`}.\n\t */\n\treadonly style?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight | `font-weight`}.\n\t */\n\treadonly weight?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings | `font-feature-settings`}.\n\t */\n\treadonly featureSettings?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/line-gap-override | `line-gap-override`}.\n\t */\n\treadonly lineGapOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range | `unicode-range`}.\n\t */\n\treadonly unicodeRange?: string\n}\n\ninterface FontState {\n\treadonly state: 'loading' | 'ready' | 'error'\n\treadonly instance: FontFace\n\treadonly loadingPromise: Promise<void>\n}\n\n/** @public */\nexport class FontManager {\n\tconstructor(\n\t\tprivate readonly editor: Editor,\n\t\tprivate readonly assetUrls?: { [key: string]: string | undefined }\n\t) {\n\t\tthis.shapeFontFacesCache = editor.store.createComputedCache(\n\t\t\t'shape font faces',\n\t\t\t(shape: TLShape) => {\n\t\t\t\tconst shapeUtil = this.editor.getShapeUtil(shape)\n\t\t\t\treturn shapeUtil.getFontFaces(shape)\n\t\t\t},\n\t\t\t{ areResultsEqual: areArraysShallowEqual, areRecordsEqual: (a, b) => a.props === b.props }\n\t\t)\n\n\t\tthis.shapeFontLoadStateCache = editor.store.createCache<(FontState | null)[], TLShape>(\n\t\t\t(id: TLShapeId) => {\n\t\t\t\tconst fontFacesComputed = computed('font faces', () => this.getShapeFontFaces(id))\n\t\t\t\treturn computed(\n\t\t\t\t\t'font load state',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst states = fontFacesComputed.get().map((face) => this.getFontState(face))\n\t\t\t\t\t\treturn states\n\t\t\t\t\t},\n\t\t\t\t\t{ isEqual: areArraysShallowEqual }\n\t\t\t\t)\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate readonly shapeFontFacesCache\n\tprivate readonly shapeFontLoadStateCache\n\n\tgetShapeFontFaces(shape: TLShape | TLShapeId): TLFontFace[] {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.shapeFontFacesCache.get(shapeId) ?? EMPTY_ARRAY\n\t}\n\n\ttrackFontsForShape(shape: TLShape | TLShapeId) {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\tthis.shapeFontLoadStateCache.get(shapeId)\n\t}\n\n\tasync loadRequiredFontsForCurrentPage(limit = Infinity) {\n\t\tconst neededFonts = new Set<TLFontFace>()\n\t\tfor (const shapeId of this.editor.getCurrentPageShapeIds()) {\n\t\t\tfor (const font of this.getShapeFontFaces(this.editor.getShape(shapeId)!)) {\n\t\t\t\tneededFonts.add(font)\n\t\t\t}\n\t\t}\n\n\t\tif (neededFonts.size > limit) {\n\t\t\treturn\n\t\t}\n\n\t\tconst promises = Array.from(neededFonts, (font) => this.ensureFontIsLoaded(font))\n\t\tawait Promise.all(promises)\n\t}\n\n\tprivate readonly fontStates = new AtomMap<TLFontFace, FontState>('font states')\n\tprivate getFontState(font: TLFontFace): FontState | null {\n\t\treturn this.fontStates.get(font) ?? null\n\t}\n\n\tensureFontIsLoaded(font: TLFontFace): Promise<void> {\n\t\tconst existingState = this.getFontState(font)\n\t\tif (existingState) return existingState.loadingPromise\n\n\t\tconst instance = this.findOrCreateFontFace(font)\n\t\tconst state: FontState = {\n\t\t\tstate: 'loading',\n\t\t\tinstance,\n\t\t\tloadingPromise: instance\n\t\t\t\t.load()\n\t\t\t\t.then(() => {\n\t\t\t\t\tdocument.fonts.add(instance)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'ready' }))\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(err)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'error' }))\n\t\t\t\t}),\n\t\t}\n\n\t\tthis.fontStates.set(font, state)\n\t\treturn state.loadingPromise\n\t}\n\n\tprivate fontsToLoad = new Set<TLFontFace>()\n\trequestFonts(fonts: TLFontFace[]) {\n\t\tif (!this.fontsToLoad.size) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tif (this.editor.isDisposed) return\n\t\t\t\tconst toLoad = this.fontsToLoad\n\t\t\t\tthis.fontsToLoad = new Set()\n\t\t\t\ttransact(() => {\n\t\t\t\t\tfor (const font of toLoad) {\n\t\t\t\t\t\tthis.ensureFontIsLoaded(font)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t\tfor (const font of fonts) {\n\t\t\tthis.fontsToLoad.add(font)\n\t\t}\n\t}\n\n\tprivate findOrCreateFontFace(font: TLFontFace) {\n\t\tfor (const existing of document.fonts) {\n\t\t\tif (\n\t\t\t\texisting.family === font.family &&\n\t\t\t\tobjectMapEntries(defaultFontFaceDescriptors).every(\n\t\t\t\t\t([key, defaultValue]) => existing[key] === (font[key] ?? defaultValue)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst instance = new FontFace(font.family, `url(${JSON.stringify(url)})`, {\n\t\t\t...mapObjectMapValues(defaultFontFaceDescriptors, (key) => font[key]),\n\t\t\tdisplay: 'swap',\n\t\t})\n\n\t\tdocument.fonts.add(instance)\n\n\t\treturn instance\n\t}\n\n\tasync toEmbeddedCssDeclaration(font: TLFontFace) {\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst dataUrl = await FileHelpers.urlToDataUrl(url)\n\n\t\tconst src = compact([\n\t\t\t`url(\"${dataUrl}\")`,\n\t\t\tfont.src.format ? `format(${font.src.format})` : null,\n\t\t\tfont.src.tech ? `tech(${font.src.tech})` : null,\n\t\t]).join(' ')\n\t\treturn compact([\n\t\t\t`@font-face {`,\n\t\t\t` font-family: \"${font.family}\";`,\n\t\t\tfont.ascentOverride ? ` ascent-override: ${font.ascentOverride};` : null,\n\t\t\tfont.descentOverride ? ` descent-override: ${font.descentOverride};` : null,\n\t\t\tfont.stretch ? ` font-stretch: ${font.stretch};` : null,\n\t\t\tfont.style ? ` font-style: ${font.style};` : null,\n\t\t\tfont.weight ? ` font-weight: ${font.weight};` : null,\n\t\t\tfont.featureSettings ? ` font-feature-settings: ${font.featureSettings};` : null,\n\t\t\tfont.lineGapOverride ? ` line-gap-override: ${font.lineGapOverride};` : null,\n\t\t\tfont.unicodeRange ? ` unicode-range: ${font.unicodeRange};` : null,\n\t\t\t` src: ${src};`,\n\t\t\t`}`,\n\t\t]).join('\\n')\n\t}\n}\n\n// From https://drafts.csswg.org/css-font-loading/#fontface-interface\nconst defaultFontFaceDescriptors = {\n\tstyle: 'normal',\n\tweight: 'normal',\n\tstretch: 'normal',\n\tunicodeRange: 'U+0-10FFFF',\n\tfeatureSettings: 'normal',\n\tascentOverride: 'normal',\n\tdescentOverride: 'normal',\n\tlineGapOverride: 'normal',\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-cjs/version.js
CHANGED
|
@@ -22,10 +22,10 @@ __export(version_exports, {
|
|
|
22
22
|
version: () => version
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(version_exports);
|
|
25
|
-
const version = "3.12.0-canary.
|
|
25
|
+
const version = "3.12.0-canary.c986b5185d4e";
|
|
26
26
|
const publishDates = {
|
|
27
27
|
major: "2024-09-13T14:36:29.063Z",
|
|
28
|
-
minor: "2025-03-
|
|
29
|
-
patch: "2025-03-
|
|
28
|
+
minor: "2025-03-26T08:55:39.391Z",
|
|
29
|
+
patch: "2025-03-26T08:55:39.391Z"
|
|
30
30
|
};
|
|
31
31
|
//# sourceMappingURL=version.js.map
|
package/dist-cjs/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.c986b5185d4e'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-26T08:55:39.391Z',\n\tpatch: '2025-03-26T08:55:39.391Z',\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/index.mjs
CHANGED
|
@@ -17,7 +17,7 @@ class FontManager {
|
|
|
17
17
|
const shapeUtil = this.editor.getShapeUtil(shape);
|
|
18
18
|
return shapeUtil.getFontFaces(shape);
|
|
19
19
|
},
|
|
20
|
-
{ areResultsEqual: areArraysShallowEqual }
|
|
20
|
+
{ areResultsEqual: areArraysShallowEqual, areRecordsEqual: (a, b) => a.props === b.props }
|
|
21
21
|
);
|
|
22
22
|
this.shapeFontLoadStateCache = editor.store.createCache(
|
|
23
23
|
(id) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/editor/managers/FontManager.ts"],
|
|
4
|
-
"sourcesContent": ["import { computed, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport { AtomMap } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport {\n\tareArraysShallowEqual,\n\tcompact,\n\tFileHelpers,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n} from '@tldraw/utils'\nimport { Editor } from '../Editor'\n\n/**\n * Represents the `src` property of a {@link TLFontFace}.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`} for details of the properties here.\n * @public\n */\nexport interface TLFontFaceSource {\n\t/**\n\t * A URL from which to load the font. If the value here is a key in\n\t * {@link tldraw#TLEditorAssetUrls.fonts}, the value from there will be used instead.\n\t */\n\turl: string\n\tformat?: string\n\ttech?: string\n}\n\n/**\n * A font face that can be used in the editor. The properties of this are largely the same as the\n * ones in the\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face | css `@font-face` rule}.\n * @public\n */\nexport interface TLFontFace {\n\t/**\n\t * How this font can be referred to in CSS.\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family | `font-family`}.\n\t */\n\treadonly family: string\n\t/**\n\t * The source of the font. This\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`}.\n\t */\n\treadonly src: TLFontFaceSource\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/ascent-override | `ascent-override`}.\n\t */\n\treadonly ascentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/descent-override | `descent-override`}.\n\t */\n\treadonly descentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch | `font-stretch`}.\n\t */\n\treadonly stretch?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-style | `font-style`}.\n\t */\n\treadonly style?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight | `font-weight`}.\n\t */\n\treadonly weight?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings | `font-feature-settings`}.\n\t */\n\treadonly featureSettings?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/line-gap-override | `line-gap-override`}.\n\t */\n\treadonly lineGapOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range | `unicode-range`}.\n\t */\n\treadonly unicodeRange?: string\n}\n\ninterface FontState {\n\treadonly state: 'loading' | 'ready' | 'error'\n\treadonly instance: FontFace\n\treadonly loadingPromise: Promise<void>\n}\n\n/** @public */\nexport class FontManager {\n\tconstructor(\n\t\tprivate readonly editor: Editor,\n\t\tprivate readonly assetUrls?: { [key: string]: string | undefined }\n\t) {\n\t\tthis.shapeFontFacesCache = editor.store.createComputedCache(\n\t\t\t'shape font faces',\n\t\t\t(shape: TLShape) => {\n\t\t\t\tconst shapeUtil = this.editor.getShapeUtil(shape)\n\t\t\t\treturn shapeUtil.getFontFaces(shape)\n\t\t\t},\n\t\t\t{ areResultsEqual: areArraysShallowEqual }\n\t\t)\n\n\t\tthis.shapeFontLoadStateCache = editor.store.createCache<(FontState | null)[], TLShape>(\n\t\t\t(id: TLShapeId) => {\n\t\t\t\tconst fontFacesComputed = computed('font faces', () => this.getShapeFontFaces(id))\n\t\t\t\treturn computed(\n\t\t\t\t\t'font load state',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst states = fontFacesComputed.get().map((face) => this.getFontState(face))\n\t\t\t\t\t\treturn states\n\t\t\t\t\t},\n\t\t\t\t\t{ isEqual: areArraysShallowEqual }\n\t\t\t\t)\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate readonly shapeFontFacesCache\n\tprivate readonly shapeFontLoadStateCache\n\n\tgetShapeFontFaces(shape: TLShape | TLShapeId): TLFontFace[] {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.shapeFontFacesCache.get(shapeId) ?? EMPTY_ARRAY\n\t}\n\n\ttrackFontsForShape(shape: TLShape | TLShapeId) {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\tthis.shapeFontLoadStateCache.get(shapeId)\n\t}\n\n\tasync loadRequiredFontsForCurrentPage(limit = Infinity) {\n\t\tconst neededFonts = new Set<TLFontFace>()\n\t\tfor (const shapeId of this.editor.getCurrentPageShapeIds()) {\n\t\t\tfor (const font of this.getShapeFontFaces(this.editor.getShape(shapeId)!)) {\n\t\t\t\tneededFonts.add(font)\n\t\t\t}\n\t\t}\n\n\t\tif (neededFonts.size > limit) {\n\t\t\treturn\n\t\t}\n\n\t\tconst promises = Array.from(neededFonts, (font) => this.ensureFontIsLoaded(font))\n\t\tawait Promise.all(promises)\n\t}\n\n\tprivate readonly fontStates = new AtomMap<TLFontFace, FontState>('font states')\n\tprivate getFontState(font: TLFontFace): FontState | null {\n\t\treturn this.fontStates.get(font) ?? null\n\t}\n\n\tensureFontIsLoaded(font: TLFontFace): Promise<void> {\n\t\tconst existingState = this.getFontState(font)\n\t\tif (existingState) return existingState.loadingPromise\n\n\t\tconst instance = this.findOrCreateFontFace(font)\n\t\tconst state: FontState = {\n\t\t\tstate: 'loading',\n\t\t\tinstance,\n\t\t\tloadingPromise: instance\n\t\t\t\t.load()\n\t\t\t\t.then(() => {\n\t\t\t\t\tdocument.fonts.add(instance)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'ready' }))\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(err)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'error' }))\n\t\t\t\t}),\n\t\t}\n\n\t\tthis.fontStates.set(font, state)\n\t\treturn state.loadingPromise\n\t}\n\n\tprivate fontsToLoad = new Set<TLFontFace>()\n\trequestFonts(fonts: TLFontFace[]) {\n\t\tif (!this.fontsToLoad.size) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tif (this.editor.isDisposed) return\n\t\t\t\tconst toLoad = this.fontsToLoad\n\t\t\t\tthis.fontsToLoad = new Set()\n\t\t\t\ttransact(() => {\n\t\t\t\t\tfor (const font of toLoad) {\n\t\t\t\t\t\tthis.ensureFontIsLoaded(font)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t\tfor (const font of fonts) {\n\t\t\tthis.fontsToLoad.add(font)\n\t\t}\n\t}\n\n\tprivate findOrCreateFontFace(font: TLFontFace) {\n\t\tfor (const existing of document.fonts) {\n\t\t\tif (\n\t\t\t\texisting.family === font.family &&\n\t\t\t\tobjectMapEntries(defaultFontFaceDescriptors).every(\n\t\t\t\t\t([key, defaultValue]) => existing[key] === (font[key] ?? defaultValue)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst instance = new FontFace(font.family, `url(${JSON.stringify(url)})`, {\n\t\t\t...mapObjectMapValues(defaultFontFaceDescriptors, (key) => font[key]),\n\t\t\tdisplay: 'swap',\n\t\t})\n\n\t\tdocument.fonts.add(instance)\n\n\t\treturn instance\n\t}\n\n\tasync toEmbeddedCssDeclaration(font: TLFontFace) {\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst dataUrl = await FileHelpers.urlToDataUrl(url)\n\n\t\tconst src = compact([\n\t\t\t`url(\"${dataUrl}\")`,\n\t\t\tfont.src.format ? `format(${font.src.format})` : null,\n\t\t\tfont.src.tech ? `tech(${font.src.tech})` : null,\n\t\t]).join(' ')\n\t\treturn compact([\n\t\t\t`@font-face {`,\n\t\t\t` font-family: \"${font.family}\";`,\n\t\t\tfont.ascentOverride ? ` ascent-override: ${font.ascentOverride};` : null,\n\t\t\tfont.descentOverride ? ` descent-override: ${font.descentOverride};` : null,\n\t\t\tfont.stretch ? ` font-stretch: ${font.stretch};` : null,\n\t\t\tfont.style ? ` font-style: ${font.style};` : null,\n\t\t\tfont.weight ? ` font-weight: ${font.weight};` : null,\n\t\t\tfont.featureSettings ? ` font-feature-settings: ${font.featureSettings};` : null,\n\t\t\tfont.lineGapOverride ? ` line-gap-override: ${font.lineGapOverride};` : null,\n\t\t\tfont.unicodeRange ? ` unicode-range: ${font.unicodeRange};` : null,\n\t\t\t` src: ${src};`,\n\t\t\t`}`,\n\t\t]).join('\\n')\n\t}\n}\n\n// From https://drafts.csswg.org/css-font-loading/#fontface-interface\nconst defaultFontFaceDescriptors = {\n\tstyle: 'normal',\n\tweight: 'normal',\n\tstretch: 'normal',\n\tunicodeRange: 'U+0-10FFFF',\n\tfeatureSettings: 'normal',\n\tascentOverride: 'normal',\n\tdescentOverride: 'normal',\n\tlineGapOverride: 'normal',\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,UAAU,aAAa,gBAAgB;AAChD,SAAS,eAAe;AAExB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AA4EA,MAAM,YAAY;AAAA,EACxB,YACkB,QACA,WAChB;AAFgB;AACA;AAEjB,SAAK,sBAAsB,OAAO,MAAM;AAAA,MACvC;AAAA,MACA,CAAC,UAAmB;AACnB,cAAM,YAAY,KAAK,OAAO,aAAa,KAAK;AAChD,eAAO,UAAU,aAAa,KAAK;AAAA,MACpC;AAAA,MACA,EAAE,iBAAiB,
|
|
4
|
+
"sourcesContent": ["import { computed, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport { AtomMap } from '@tldraw/store'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport {\n\tareArraysShallowEqual,\n\tcompact,\n\tFileHelpers,\n\tmapObjectMapValues,\n\tobjectMapEntries,\n} from '@tldraw/utils'\nimport { Editor } from '../Editor'\n\n/**\n * Represents the `src` property of a {@link TLFontFace}.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`} for details of the properties here.\n * @public\n */\nexport interface TLFontFaceSource {\n\t/**\n\t * A URL from which to load the font. If the value here is a key in\n\t * {@link tldraw#TLEditorAssetUrls.fonts}, the value from there will be used instead.\n\t */\n\turl: string\n\tformat?: string\n\ttech?: string\n}\n\n/**\n * A font face that can be used in the editor. The properties of this are largely the same as the\n * ones in the\n * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face | css `@font-face` rule}.\n * @public\n */\nexport interface TLFontFace {\n\t/**\n\t * How this font can be referred to in CSS.\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family | `font-family`}.\n\t */\n\treadonly family: string\n\t/**\n\t * The source of the font. This\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src | `src`}.\n\t */\n\treadonly src: TLFontFaceSource\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/ascent-override | `ascent-override`}.\n\t */\n\treadonly ascentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/descent-override | `descent-override`}.\n\t */\n\treadonly descentOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch | `font-stretch`}.\n\t */\n\treadonly stretch?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-style | `font-style`}.\n\t */\n\treadonly style?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-weight | `font-weight`}.\n\t */\n\treadonly weight?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings | `font-feature-settings`}.\n\t */\n\treadonly featureSettings?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/line-gap-override | `line-gap-override`}.\n\t */\n\treadonly lineGapOverride?: string\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range | `unicode-range`}.\n\t */\n\treadonly unicodeRange?: string\n}\n\ninterface FontState {\n\treadonly state: 'loading' | 'ready' | 'error'\n\treadonly instance: FontFace\n\treadonly loadingPromise: Promise<void>\n}\n\n/** @public */\nexport class FontManager {\n\tconstructor(\n\t\tprivate readonly editor: Editor,\n\t\tprivate readonly assetUrls?: { [key: string]: string | undefined }\n\t) {\n\t\tthis.shapeFontFacesCache = editor.store.createComputedCache(\n\t\t\t'shape font faces',\n\t\t\t(shape: TLShape) => {\n\t\t\t\tconst shapeUtil = this.editor.getShapeUtil(shape)\n\t\t\t\treturn shapeUtil.getFontFaces(shape)\n\t\t\t},\n\t\t\t{ areResultsEqual: areArraysShallowEqual, areRecordsEqual: (a, b) => a.props === b.props }\n\t\t)\n\n\t\tthis.shapeFontLoadStateCache = editor.store.createCache<(FontState | null)[], TLShape>(\n\t\t\t(id: TLShapeId) => {\n\t\t\t\tconst fontFacesComputed = computed('font faces', () => this.getShapeFontFaces(id))\n\t\t\t\treturn computed(\n\t\t\t\t\t'font load state',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst states = fontFacesComputed.get().map((face) => this.getFontState(face))\n\t\t\t\t\t\treturn states\n\t\t\t\t\t},\n\t\t\t\t\t{ isEqual: areArraysShallowEqual }\n\t\t\t\t)\n\t\t\t}\n\t\t)\n\t}\n\n\tprivate readonly shapeFontFacesCache\n\tprivate readonly shapeFontLoadStateCache\n\n\tgetShapeFontFaces(shape: TLShape | TLShapeId): TLFontFace[] {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.shapeFontFacesCache.get(shapeId) ?? EMPTY_ARRAY\n\t}\n\n\ttrackFontsForShape(shape: TLShape | TLShapeId) {\n\t\tconst shapeId = typeof shape === 'string' ? shape : shape.id\n\t\tthis.shapeFontLoadStateCache.get(shapeId)\n\t}\n\n\tasync loadRequiredFontsForCurrentPage(limit = Infinity) {\n\t\tconst neededFonts = new Set<TLFontFace>()\n\t\tfor (const shapeId of this.editor.getCurrentPageShapeIds()) {\n\t\t\tfor (const font of this.getShapeFontFaces(this.editor.getShape(shapeId)!)) {\n\t\t\t\tneededFonts.add(font)\n\t\t\t}\n\t\t}\n\n\t\tif (neededFonts.size > limit) {\n\t\t\treturn\n\t\t}\n\n\t\tconst promises = Array.from(neededFonts, (font) => this.ensureFontIsLoaded(font))\n\t\tawait Promise.all(promises)\n\t}\n\n\tprivate readonly fontStates = new AtomMap<TLFontFace, FontState>('font states')\n\tprivate getFontState(font: TLFontFace): FontState | null {\n\t\treturn this.fontStates.get(font) ?? null\n\t}\n\n\tensureFontIsLoaded(font: TLFontFace): Promise<void> {\n\t\tconst existingState = this.getFontState(font)\n\t\tif (existingState) return existingState.loadingPromise\n\n\t\tconst instance = this.findOrCreateFontFace(font)\n\t\tconst state: FontState = {\n\t\t\tstate: 'loading',\n\t\t\tinstance,\n\t\t\tloadingPromise: instance\n\t\t\t\t.load()\n\t\t\t\t.then(() => {\n\t\t\t\t\tdocument.fonts.add(instance)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'ready' }))\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tconsole.error(err)\n\t\t\t\t\tthis.fontStates.update(font, (s) => ({ ...s, state: 'error' }))\n\t\t\t\t}),\n\t\t}\n\n\t\tthis.fontStates.set(font, state)\n\t\treturn state.loadingPromise\n\t}\n\n\tprivate fontsToLoad = new Set<TLFontFace>()\n\trequestFonts(fonts: TLFontFace[]) {\n\t\tif (!this.fontsToLoad.size) {\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tif (this.editor.isDisposed) return\n\t\t\t\tconst toLoad = this.fontsToLoad\n\t\t\t\tthis.fontsToLoad = new Set()\n\t\t\t\ttransact(() => {\n\t\t\t\t\tfor (const font of toLoad) {\n\t\t\t\t\t\tthis.ensureFontIsLoaded(font)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t\tfor (const font of fonts) {\n\t\t\tthis.fontsToLoad.add(font)\n\t\t}\n\t}\n\n\tprivate findOrCreateFontFace(font: TLFontFace) {\n\t\tfor (const existing of document.fonts) {\n\t\t\tif (\n\t\t\t\texisting.family === font.family &&\n\t\t\t\tobjectMapEntries(defaultFontFaceDescriptors).every(\n\t\t\t\t\t([key, defaultValue]) => existing[key] === (font[key] ?? defaultValue)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn existing\n\t\t\t}\n\t\t}\n\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst instance = new FontFace(font.family, `url(${JSON.stringify(url)})`, {\n\t\t\t...mapObjectMapValues(defaultFontFaceDescriptors, (key) => font[key]),\n\t\t\tdisplay: 'swap',\n\t\t})\n\n\t\tdocument.fonts.add(instance)\n\n\t\treturn instance\n\t}\n\n\tasync toEmbeddedCssDeclaration(font: TLFontFace) {\n\t\tconst url = this.assetUrls?.[font.src.url] ?? font.src.url\n\t\tconst dataUrl = await FileHelpers.urlToDataUrl(url)\n\n\t\tconst src = compact([\n\t\t\t`url(\"${dataUrl}\")`,\n\t\t\tfont.src.format ? `format(${font.src.format})` : null,\n\t\t\tfont.src.tech ? `tech(${font.src.tech})` : null,\n\t\t]).join(' ')\n\t\treturn compact([\n\t\t\t`@font-face {`,\n\t\t\t` font-family: \"${font.family}\";`,\n\t\t\tfont.ascentOverride ? ` ascent-override: ${font.ascentOverride};` : null,\n\t\t\tfont.descentOverride ? ` descent-override: ${font.descentOverride};` : null,\n\t\t\tfont.stretch ? ` font-stretch: ${font.stretch};` : null,\n\t\t\tfont.style ? ` font-style: ${font.style};` : null,\n\t\t\tfont.weight ? ` font-weight: ${font.weight};` : null,\n\t\t\tfont.featureSettings ? ` font-feature-settings: ${font.featureSettings};` : null,\n\t\t\tfont.lineGapOverride ? ` line-gap-override: ${font.lineGapOverride};` : null,\n\t\t\tfont.unicodeRange ? ` unicode-range: ${font.unicodeRange};` : null,\n\t\t\t` src: ${src};`,\n\t\t\t`}`,\n\t\t]).join('\\n')\n\t}\n}\n\n// From https://drafts.csswg.org/css-font-loading/#fontface-interface\nconst defaultFontFaceDescriptors = {\n\tstyle: 'normal',\n\tweight: 'normal',\n\tstretch: 'normal',\n\tunicodeRange: 'U+0-10FFFF',\n\tfeatureSettings: 'normal',\n\tascentOverride: 'normal',\n\tdescentOverride: 'normal',\n\tlineGapOverride: 'normal',\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,UAAU,aAAa,gBAAgB;AAChD,SAAS,eAAe;AAExB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AA4EA,MAAM,YAAY;AAAA,EACxB,YACkB,QACA,WAChB;AAFgB;AACA;AAEjB,SAAK,sBAAsB,OAAO,MAAM;AAAA,MACvC;AAAA,MACA,CAAC,UAAmB;AACnB,cAAM,YAAY,KAAK,OAAO,aAAa,KAAK;AAChD,eAAO,UAAU,aAAa,KAAK;AAAA,MACpC;AAAA,MACA,EAAE,iBAAiB,uBAAuB,iBAAiB,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,MAAM;AAAA,IAC1F;AAEA,SAAK,0BAA0B,OAAO,MAAM;AAAA,MAC3C,CAAC,OAAkB;AAClB,cAAM,oBAAoB,SAAS,cAAc,MAAM,KAAK,kBAAkB,EAAE,CAAC;AACjF,eAAO;AAAA,UACN;AAAA,UACA,MAAM;AACL,kBAAM,SAAS,kBAAkB,IAAI,EAAE,IAAI,CAAC,SAAS,KAAK,aAAa,IAAI,CAAC;AAC5E,mBAAO;AAAA,UACR;AAAA,UACA,EAAE,SAAS,sBAAsB;AAAA,QAClC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEiB;AAAA,EACA;AAAA,EAEjB,kBAAkB,OAA0C;AAC3D,UAAM,UAAU,OAAO,UAAU,WAAW,QAAQ,MAAM;AAC1D,WAAO,KAAK,oBAAoB,IAAI,OAAO,KAAK;AAAA,EACjD;AAAA,EAEA,mBAAmB,OAA4B;AAC9C,UAAM,UAAU,OAAO,UAAU,WAAW,QAAQ,MAAM;AAC1D,SAAK,wBAAwB,IAAI,OAAO;AAAA,EACzC;AAAA,EAEA,MAAM,gCAAgC,QAAQ,UAAU;AACvD,UAAM,cAAc,oBAAI,IAAgB;AACxC,eAAW,WAAW,KAAK,OAAO,uBAAuB,GAAG;AAC3D,iBAAW,QAAQ,KAAK,kBAAkB,KAAK,OAAO,SAAS,OAAO,CAAE,GAAG;AAC1E,oBAAY,IAAI,IAAI;AAAA,MACrB;AAAA,IACD;AAEA,QAAI,YAAY,OAAO,OAAO;AAC7B;AAAA,IACD;AAEA,UAAM,WAAW,MAAM,KAAK,aAAa,CAAC,SAAS,KAAK,mBAAmB,IAAI,CAAC;AAChF,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC3B;AAAA,EAEiB,aAAa,IAAI,QAA+B,aAAa;AAAA,EACtE,aAAa,MAAoC;AACxD,WAAO,KAAK,WAAW,IAAI,IAAI,KAAK;AAAA,EACrC;AAAA,EAEA,mBAAmB,MAAiC;AACnD,UAAM,gBAAgB,KAAK,aAAa,IAAI;AAC5C,QAAI,cAAe,QAAO,cAAc;AAExC,UAAM,WAAW,KAAK,qBAAqB,IAAI;AAC/C,UAAM,QAAmB;AAAA,MACxB,OAAO;AAAA,MACP;AAAA,MACA,gBAAgB,SACd,KAAK,EACL,KAAK,MAAM;AACX,iBAAS,MAAM,IAAI,QAAQ;AAC3B,aAAK,WAAW,OAAO,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,QAAQ,EAAE;AAAA,MAC/D,CAAC,EACA,MAAM,CAAC,QAAQ;AACf,gBAAQ,MAAM,GAAG;AACjB,aAAK,WAAW,OAAO,MAAM,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,QAAQ,EAAE;AAAA,MAC/D,CAAC;AAAA,IACH;AAEA,SAAK,WAAW,IAAI,MAAM,KAAK;AAC/B,WAAO,MAAM;AAAA,EACd;AAAA,EAEQ,cAAc,oBAAI,IAAgB;AAAA,EAC1C,aAAa,OAAqB;AACjC,QAAI,CAAC,KAAK,YAAY,MAAM;AAC3B,qBAAe,MAAM;AACpB,YAAI,KAAK,OAAO,WAAY;AAC5B,cAAM,SAAS,KAAK;AACpB,aAAK,cAAc,oBAAI,IAAI;AAC3B,iBAAS,MAAM;AACd,qBAAW,QAAQ,QAAQ;AAC1B,iBAAK,mBAAmB,IAAI;AAAA,UAC7B;AAAA,QACD,CAAC;AAAA,MACF,CAAC;AAAA,IACF;AACA,eAAW,QAAQ,OAAO;AACzB,WAAK,YAAY,IAAI,IAAI;AAAA,IAC1B;AAAA,EACD;AAAA,EAEQ,qBAAqB,MAAkB;AAC9C,eAAW,YAAY,SAAS,OAAO;AACtC,UACC,SAAS,WAAW,KAAK,UACzB,iBAAiB,0BAA0B,EAAE;AAAA,QAC5C,CAAC,CAAC,KAAK,YAAY,MAAM,SAAS,GAAG,OAAO,KAAK,GAAG,KAAK;AAAA,MAC1D,GACC;AACD,eAAO;AAAA,MACR;AAAA,IACD;AAEA,UAAM,MAAM,KAAK,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI;AACvD,UAAM,WAAW,IAAI,SAAS,KAAK,QAAQ,OAAO,KAAK,UAAU,GAAG,CAAC,KAAK;AAAA,MACzE,GAAG,mBAAmB,4BAA4B,CAAC,QAAQ,KAAK,GAAG,CAAC;AAAA,MACpE,SAAS;AAAA,IACV,CAAC;AAED,aAAS,MAAM,IAAI,QAAQ;AAE3B,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,yBAAyB,MAAkB;AAChD,UAAM,MAAM,KAAK,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI;AACvD,UAAM,UAAU,MAAM,YAAY,aAAa,GAAG;AAElD,UAAM,MAAM,QAAQ;AAAA,MACnB,QAAQ,OAAO;AAAA,MACf,KAAK,IAAI,SAAS,UAAU,KAAK,IAAI,MAAM,MAAM;AAAA,MACjD,KAAK,IAAI,OAAO,QAAQ,KAAK,IAAI,IAAI,MAAM;AAAA,IAC5C,CAAC,EAAE,KAAK,GAAG;AACX,WAAO,QAAQ;AAAA,MACd;AAAA,MACA,mBAAmB,KAAK,MAAM;AAAA,MAC9B,KAAK,iBAAiB,sBAAsB,KAAK,cAAc,MAAM;AAAA,MACrE,KAAK,kBAAkB,uBAAuB,KAAK,eAAe,MAAM;AAAA,MACxE,KAAK,UAAU,mBAAmB,KAAK,OAAO,MAAM;AAAA,MACpD,KAAK,QAAQ,iBAAiB,KAAK,KAAK,MAAM;AAAA,MAC9C,KAAK,SAAS,kBAAkB,KAAK,MAAM,MAAM;AAAA,MACjD,KAAK,kBAAkB,4BAA4B,KAAK,eAAe,MAAM;AAAA,MAC7E,KAAK,kBAAkB,wBAAwB,KAAK,eAAe,MAAM;AAAA,MACzE,KAAK,eAAe,oBAAoB,KAAK,YAAY,MAAM;AAAA,MAC/D,UAAU,GAAG;AAAA,MACb;AAAA,IACD,CAAC,EAAE,KAAK,IAAI;AAAA,EACb;AACD;AAGA,MAAM,6BAA6B;AAAA,EAClC,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,iBAAiB;AAClB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "3.12.0-canary.
|
|
1
|
+
const version = "3.12.0-canary.c986b5185d4e";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2024-09-13T14:36:29.063Z",
|
|
4
|
-
minor: "2025-03-
|
|
5
|
-
patch: "2025-03-
|
|
4
|
+
minor: "2025-03-26T08:55:39.391Z",
|
|
5
|
+
patch: "2025-03-26T08:55:39.391Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.12.0-canary.c986b5185d4e'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-26T08:55:39.391Z',\n\tpatch: '2025-03-26T08:55:39.391Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "A tiny little drawing app (editor).",
|
|
4
|
-
"version": "3.12.0-canary.
|
|
4
|
+
"version": "3.12.0-canary.c986b5185d4e",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"@tiptap/core": "^2.9.1",
|
|
49
49
|
"@tiptap/pm": "^2.9.1",
|
|
50
50
|
"@tiptap/react": "^2.9.1",
|
|
51
|
-
"@tldraw/state": "3.12.0-canary.
|
|
52
|
-
"@tldraw/state-react": "3.12.0-canary.
|
|
53
|
-
"@tldraw/store": "3.12.0-canary.
|
|
54
|
-
"@tldraw/tlschema": "3.12.0-canary.
|
|
55
|
-
"@tldraw/utils": "3.12.0-canary.
|
|
56
|
-
"@tldraw/validate": "3.12.0-canary.
|
|
51
|
+
"@tldraw/state": "3.12.0-canary.c986b5185d4e",
|
|
52
|
+
"@tldraw/state-react": "3.12.0-canary.c986b5185d4e",
|
|
53
|
+
"@tldraw/store": "3.12.0-canary.c986b5185d4e",
|
|
54
|
+
"@tldraw/tlschema": "3.12.0-canary.c986b5185d4e",
|
|
55
|
+
"@tldraw/utils": "3.12.0-canary.c986b5185d4e",
|
|
56
|
+
"@tldraw/validate": "3.12.0-canary.c986b5185d4e",
|
|
57
57
|
"@types/core-js": "^2.5.8",
|
|
58
58
|
"@use-gesture/react": "^10.3.1",
|
|
59
59
|
"classnames": "^2.5.1",
|
|
@@ -94,7 +94,7 @@ export class FontManager {
|
|
|
94
94
|
const shapeUtil = this.editor.getShapeUtil(shape)
|
|
95
95
|
return shapeUtil.getFontFaces(shape)
|
|
96
96
|
},
|
|
97
|
-
{ areResultsEqual: areArraysShallowEqual }
|
|
97
|
+
{ areResultsEqual: areArraysShallowEqual, areRecordsEqual: (a, b) => a.props === b.props }
|
|
98
98
|
)
|
|
99
99
|
|
|
100
100
|
this.shapeFontLoadStateCache = editor.store.createCache<(FontState | null)[], TLShape>(
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '3.12.0-canary.
|
|
4
|
+
export const version = '3.12.0-canary.c986b5185d4e'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-03-
|
|
8
|
-
patch: '2025-03-
|
|
7
|
+
minor: '2025-03-26T08:55:39.391Z',
|
|
8
|
+
patch: '2025-03-26T08:55:39.391Z',
|
|
9
9
|
}
|