Path: blob/master/src/packages/frontend/editors/slate/elements/image/index.tsx
1698 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { load } from "cheerio";67import { useFileContext } from "@cocalc/frontend/lib/file-context";8import { dict } from "@cocalc/util/misc";9import { register, SlateElement } from "../register";1011export interface Image extends SlateElement {12type: "image";13isInline: true;14isVoid: true;15src: string;16alt?: string;17title?: string;18width?: string | number;19height?: string | number;20}2122export function toSlate({ type, children, token }) {23switch (type) {24// IMPORTANT: this only gets called with type != 'image'25// because of explicit code in ./html.tsx.26case "html_inline":27case "html_block":28// token.content will be a string like this:29// <img src='https://wstein.org/bella-and-william.jpg' width=200px title='my pup' />30// easiest way to parse this is with jquery style api but via cheerio (not by hand).31const $ = load("");32const elt = $(token.content);33const node = {34type: "image",35children,36isInline: true,37isVoid: true,38src: elt.attr("src") ?? "",39alt: elt.attr("alt") ?? "",40title: elt.attr("title") ?? "",41width: elt.attr("width"),42height: elt.attr("height"),43} as any;44if (type == "html_inline") {45return node;46}47return {48type: "paragraph",49children: [{ text: "" }, node, { text: "" }],50};51case "image":52const attrs = dict(token.attrs as any);53return {54type: "image",55children,56isInline: true,57isVoid: true,58src: attrs.src,59alt: attrs.alt,60title: attrs.title,61};62default:63throw Error("bug");64}65}6667register({68slateType: "image",69toSlate,70StaticElement: ({ attributes, element }) => {71const { urlTransform, reloadImages } = useFileContext();72const node = element as Image;73const { src, alt, title } = node;74return (75<img76{...attributes}77src={78(urlTransform?.(src, "img") ?? src) +79(reloadImages ? `?${Math.random()}` : "")80}81alt={alt}82title={title}83style={{84height: node.height,85width: node.width,86maxWidth: "100%",87maxHeight: "100%",88objectFit: "cover",89}}90/>91);92},93});949596