Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 43x 43x 42x 42x 43x 42x 42x 285x 147x 147x 53x 138x 107x 42x 42x 42x 42x 39x 42x 46x 42x 42x 42x 42x 42x 42x 42x 17x 17x 17x 25x 42x 42x 47x | import { isBlockElement, isNodeOfType, toArray } from 'roosterjs-content-model-dom'; import { retrieveCssRules } from '../createModelFromHtml/convertInlineCss'; import type { ClipboardData } from 'roosterjs-content-model-types'; import type { CssRule } from '../createModelFromHtml/convertInlineCss'; const START_FRAGMENT = '<!--StartFragment-->'; const END_FRAGMENT = '<!--EndFragment-->'; /** * @internal */ export interface HtmlFromClipboard { metadata: Record<string, string>; globalCssRules: CssRule[]; htmlBefore?: string; htmlAfter?: string; containsBlockElements?: boolean; } /** * @internal */ export function retrieveHtmlInfo( doc: Document | null, clipboardData: Partial<ClipboardData> ): HtmlFromClipboard { let result: HtmlFromClipboard = { metadata: {}, globalCssRules: [], }; if (doc) { result = { ...retrieveHtmlStrings(clipboardData), globalCssRules: retrieveCssRules(doc), metadata: retrieveMetadata(doc), containsBlockElements: checkBlockElements(doc), }; clipboardData.htmlFirstLevelChildTags = retrieveTopLevelTags(doc); } return result; } function retrieveTopLevelTags(doc: Document): string[] { const topLevelTags: string[] = []; for (let child = doc.body.firstChild; child; child = child.nextSibling) { if (isNodeOfType(child, 'TEXT_NODE')) { const trimmedString = child.nodeValue?.replace(/(\r\n|\r|\n)/gm, '').trim(); if (trimmedString) { topLevelTags.push(''); // Push an empty string as tag for text node } } else if (isNodeOfType(child, 'ELEMENT_NODE')) { topLevelTags.push(child.tagName); } } return topLevelTags; } function retrieveMetadata(doc: Document): Record<string, string> { const result: Record<string, string> = {}; const attributes = doc.querySelector('html')?.attributes; (attributes ? toArray(attributes) : []).forEach(attr => { result[attr.name] = attr.value; }); toArray(doc.querySelectorAll('meta')).forEach(meta => { result[meta.name] = meta.content; }); return result; } function retrieveHtmlStrings( clipboardData: Partial<ClipboardData> ): { htmlBefore: string; htmlAfter: string; } { const rawHtml = clipboardData.rawHtml ?? ''; const startIndex = rawHtml.indexOf(START_FRAGMENT); const endIndex = rawHtml.lastIndexOf(END_FRAGMENT); let htmlBefore = ''; let htmlAfter = ''; if (startIndex >= 0 && endIndex >= startIndex + START_FRAGMENT.length) { htmlBefore = rawHtml.substring(0, startIndex); htmlAfter = rawHtml.substring(endIndex + END_FRAGMENT.length); clipboardData.html = rawHtml.substring(startIndex + START_FRAGMENT.length, endIndex); } else { clipboardData.html = rawHtml; } return { htmlBefore, htmlAfter }; } function checkBlockElements(doc: Document): boolean { const elements = toArray(doc.body.querySelectorAll('*')); return elements.some(el => isNodeOfType(el, 'ELEMENT_NODE') && isBlockElement(el)); } |