Last active
June 19, 2020 20:35
Card link with image generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-ignore | |
import { getMetadata } from 'page-metadata-parser' | |
import he from 'he' | |
export function addImagedLinksToTextAreaOnPaste(el: HTMLTextAreaElement) { | |
const pasteEvent = async (ev: ClipboardEvent) => { | |
const { items } = ev.clipboardData || {} | |
if (items) { | |
for (const k of Object.keys(items)) { | |
const item = (items as any)[k] as DataTransferItem | |
if (item.type === 'text/plain') { | |
ev.preventDefault() | |
const { selectionStart } = el | |
item.getAsString(async (str) => { | |
if (isUrl(str)) { | |
const rawHtml = await fetch( | |
`https://cors-anywhere.herokuapp.com/${str}` | |
).then((r) => r.text()) | |
const div = document.createElement('div') | |
div.innerHTML = rawHtml | |
const meta = getMetadata(div, str) | |
div.remove() | |
const imgPos = meta.imgPos || 'left' | |
const img = ` | |
<img style="${ | |
imgPos === 'left' | |
? 'max-width: 200px; margin-right: 1em; width: 100%; height: auto;' | |
: 'margin-bottom: 1em; width: 100%; height: auto;' | |
}" ${ | |
meta | |
? meta.image | |
? `src="${encodeURI(meta.image)}" ` + | |
`alt="${he.encode(meta.title || meta.url)}" ` | |
: '' | |
: '' | |
} />` | |
const innerHTML = `${ | |
meta.image | |
? ` | |
<div style="${(imgPos === 'left' | |
? 'max-width: 200px; margin-right: 1em;' | |
: '') + | |
'display: flex; align-items: center; justify-content: center;' + | |
'overflow: hidden;'}">${img} | |
</div>` | |
: '' | |
} | |
<div> | |
${ | |
meta.title | |
? `<h3 style="color: darkblue; margin-block-start: 0;">${he.encode( | |
meta.title | |
)}</h3>` | |
: `<h6 style="color: darkblue; margin-block-start: 0;">${he.encode( | |
meta.url | |
)}</h6>` | |
} | |
${he.encode(meta.description || '')} | |
</div>` | |
const imagedLinkHtml = ` | |
<a is="a-card" style="${`flex-direction: ${ | |
imgPos === 'left' ? 'row' : 'column' | |
};` + | |
'display: flex;' + | |
'margin: 1em; padding: 1em;' + | |
'box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);'}" href="${encodeURI( | |
meta.url | |
)}" | |
rel="noopener" target="_blank"> | |
${innerHTML} | |
</a>` | |
const { value } = el | |
el.value = | |
value.substring(0, selectionStart) + | |
'\n' + | |
imagedLinkHtml + | |
'\n' + | |
value.substring(selectionStart) | |
} | |
}) | |
} else if (item.kind === 'file') { | |
const blob = item.getAsFile()! | |
ev.preventDefault() | |
const { selectionStart } = el | |
const reader = new FileReader() | |
reader.onload = function() { | |
const dataUrl = reader.result | |
const imageId = Math.random().toString(36).substring(2) | |
const { value } = el | |
el.value = | |
value.substring(0, selectionStart) + | |
`![clipboard ${new Date().toDateString()}][${imageId}]` + | |
value.substring(selectionStart) + | |
'\n' + | |
`[${imageId}]: ${dataUrl}` | |
} | |
reader.readAsDataURL(blob); | |
} | |
} | |
} | |
el.addEventListener('paste', pasteEvent) | |
return () => { | |
el.removeEventListener('paste', pasteEvent) | |
} | |
} | |
function isUrl(s: string) { | |
if (/^https?:\/\/[^ ]+$/.test(s)) { | |
try { | |
// eslint-disable-next-line no-new | |
new URL(s) | |
return true | |
} catch (_) {} | |
} | |
return false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment