1/* 2 * html.ts 3 * 4 * Copyright (C) 2021 by RStudio, PBC 5 * 6 * Unless you have received this program directly from RStudio pursuant 7 * to the terms of a commercial license agreement with RStudio, then 8 * this program is licensed to you under the terms of version 3 of the 9 * GNU Affero General Public License. This program is distributed WITHOUT 10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, 11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the 12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. 13 * 14 */ 15 16import { Node as ProsemirrorNode, Schema, DOMSerializer, Fragment } from 'prosemirror-model'; 17 18export const kHTMLCommentRegEx = /(?:^|[^`])(<!--([\s\S]*?)-->)/; 19 20export function isHTMLComment(html: string) { 21 return !!html.match(kHTMLCommentRegEx); 22} 23 24export function isSingleLineHTML(html: string) { 25 return html.trimRight().split('\n').length === 1; 26} 27 28export function asHTMLTag( 29 tag: string, 30 attribs: { [key: string]: string }, 31 selfClosing = false, 32 noEmptyAttribs = false, 33) { 34 const attribsHTML = Object.keys(attribs) 35 .filter(name => !noEmptyAttribs || attribs[name]) 36 .map(name => `${name}="${escapeHTMLAttribute(attribs[name])}"`) 37 .join(' '); 38 return `<${tag} ${attribsHTML}${selfClosing ? '/' : ''}>`; 39} 40 41export function escapeHTMLAttribute(value: string) { 42 return value 43 .replace(/&/g, '&') // must be first replacement 44 .replace(/'/g, ''') 45 .replace(/"/g, '"') 46 .replace(/</g, '<') 47 .replace(/>/g, '>'); 48} 49 50export function nodeToHTML(schema: Schema, node: ProsemirrorNode) { 51 return generateHTML(() => DOMSerializer.fromSchema(schema).serializeNode(node)); 52} 53 54export function fragmentToHTML(schema: Schema, fragment: Fragment) { 55 return generateHTML(() => DOMSerializer.fromSchema(schema).serializeFragment(fragment)); 56} 57 58function generateHTML(generator: () => Node | DocumentFragment) { 59 const div = document.createElement('div'); 60 const output = generator(); 61 div.appendChild(output); 62 return div.innerHTML; 63} 64