[fix] iOS safari clipboard / text position (#686)
* use idb for clipboard, too * Add warnings for firefox * remove logs * Update getTextSvgElement.ts
This commit is contained in:
parent
c3050db968
commit
60e936dfed
3 changed files with 53 additions and 31 deletions
17
packages/tldraw/src/state/IdbClipboard.ts
Normal file
17
packages/tldraw/src/state/IdbClipboard.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { get, set, del } from 'idb-keyval'
|
||||
|
||||
// Used for clipboard
|
||||
|
||||
const ID = 'tldraw_clipboard'
|
||||
|
||||
export async function getClipboard(): Promise<string | undefined> {
|
||||
return get(ID)
|
||||
}
|
||||
|
||||
export async function setClipboard(item: string): Promise<void> {
|
||||
return set(ID, item)
|
||||
}
|
||||
|
||||
export function clearClipboard(): Promise<void> {
|
||||
return del(ID)
|
||||
}
|
|
@ -80,6 +80,7 @@ import { ArrowTool } from './tools/ArrowTool'
|
|||
import { StickyTool } from './tools/StickyTool'
|
||||
import { StateManager } from './StateManager'
|
||||
import { clearPrevSize } from './shapes/shared/getTextSize'
|
||||
import { getClipboard, setClipboard } from './IdbClipboard'
|
||||
|
||||
const uuid = Utils.uniqueId()
|
||||
|
||||
|
@ -1778,11 +1779,13 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
|
||||
const tldrawString = `<tldraw>${jsonString}</tldraw>`
|
||||
|
||||
setClipboard(tldrawString)
|
||||
|
||||
if (e) {
|
||||
e.clipboardData?.setData('text/html', tldrawString)
|
||||
}
|
||||
|
||||
if (navigator.clipboard) {
|
||||
if (navigator.clipboard && window.ClipboardItem) {
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
'text/html': new Blob([tldrawString], { type: 'text/html' }),
|
||||
|
@ -1993,6 +1996,12 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
}
|
||||
}
|
||||
|
||||
getClipboard().then((clipboard) => {
|
||||
if (clipboard) {
|
||||
pasteAsHTML(clipboard)
|
||||
}
|
||||
})
|
||||
|
||||
if (navigator.clipboard) {
|
||||
const items = await navigator.clipboard.read()
|
||||
|
||||
|
@ -2000,16 +2009,27 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
|
||||
try {
|
||||
for (const item of items) {
|
||||
// First, look for tldraw json in html.
|
||||
// look for png data.
|
||||
|
||||
const htmlData = await item.getType('text/html')
|
||||
const pngData = await item.getType('text/png')
|
||||
|
||||
if (htmlData) {
|
||||
let html = await htmlData.text()
|
||||
pasteAsHTML(html)
|
||||
if (pngData) {
|
||||
const file = new File([pngData], 'image.png')
|
||||
this.addMediaFromFile(file)
|
||||
return
|
||||
}
|
||||
|
||||
// Next, look for plain text data.
|
||||
// look for svg data.
|
||||
|
||||
const svgData = await item.getType('image/svg+xml')
|
||||
|
||||
if (svgData) {
|
||||
const file = new File([svgData], 'image.svg')
|
||||
this.addMediaFromFile(file)
|
||||
return
|
||||
}
|
||||
|
||||
// look for plain text data.
|
||||
|
||||
const textData = await item.getType('text/plain')
|
||||
|
||||
|
@ -2026,26 +2046,6 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
// Next, look for png data.
|
||||
|
||||
const pngData = await item.getType('text/png')
|
||||
|
||||
if (pngData) {
|
||||
const file = new File([pngData], 'image.png')
|
||||
this.addMediaFromFile(file)
|
||||
return
|
||||
}
|
||||
|
||||
// Finally, look for svg data.
|
||||
|
||||
const svgData = await item.getType('image/svg+xml')
|
||||
|
||||
if (svgData) {
|
||||
const file = new File([svgData], 'image.svg')
|
||||
this.addMediaFromFile(file)
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// noop
|
||||
|
@ -2240,7 +2240,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
...this.clipboard,
|
||||
})
|
||||
|
||||
if (navigator.clipboard) {
|
||||
if (navigator.clipboard && window.ClipboardItem) {
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({
|
||||
'text/html': new Blob([tldrawString], { type: 'text/html' }),
|
||||
|
@ -2356,7 +2356,10 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
return
|
||||
}
|
||||
|
||||
if (!navigator.clipboard) return
|
||||
if (!(navigator.clipboard && window.ClipboardItem)) {
|
||||
console.warn('Sorry, your browser does not support copying images.')
|
||||
return
|
||||
}
|
||||
|
||||
const blob = await this.getImage(format, opts)
|
||||
|
||||
|
|
|
@ -12,10 +12,12 @@ export function getTextSvgElement(text: string, style: ShapeStyles, bounds: TLBo
|
|||
const textElm = document.createElementNS('http://www.w3.org/2000/svg', 'text')
|
||||
textElm.textContent = line
|
||||
textElm.setAttribute('y', LINE_HEIGHT * fontSize * (0.5 + i) + '')
|
||||
textElm.setAttribute('letter-spacing', '-0.03px')
|
||||
textElm.setAttribute('letter-spacing', fontSize * -0.03 + '')
|
||||
textElm.setAttribute('font-size', fontSize + 'px')
|
||||
textElm.setAttribute('font-family', getFontFace(style.font).slice(1, -1))
|
||||
textElm.setAttribute('text-align', getTextAlign(style.textAlign))
|
||||
textElm.setAttribute('text-align', getTextAlign(style.textAlign))
|
||||
textElm.setAttribute('alignment-baseline', 'central')
|
||||
g.appendChild(textElm)
|
||||
|
||||
return textElm
|
||||
|
@ -37,8 +39,8 @@ export function getTextSvgElement(text: string, style: ShapeStyles, bounds: TLBo
|
|||
break
|
||||
}
|
||||
case AlignStyle.Start: {
|
||||
g.setAttribute('text-align', 'left')
|
||||
g.setAttribute('text-anchor', 'start')
|
||||
g.setAttribute('alignment-baseline', 'central')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue