@@ -17,7 +17,6 @@ import {hideElements} from "../ui/hideElements";
1717import { avRender } from "../render/av/render" ;
1818import { cellScrollIntoView , getCellText } from "../render/av/cell" ;
1919import { getContenteditableElement } from "../wysiwyg/getBlock" ;
20- import { escapeAttr } from "../../util/escape" ;
2120
2221export const getTextStar = ( blockElement : HTMLElement ) => {
2322 const dataType = blockElement . dataset . type ;
@@ -321,8 +320,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
321320 }
322321 // 剪切复制中首位包含空格或仅有空格 https://github.com/siyuan-note/siyuan/issues/5667
323322 if ( ! siyuanHTML ) {
324- // 从网页复制时,浏览器已经将符合条件的回车符转换为空格写入剪贴板了,其他回车符都是多余的,需移除
325- // 否则 new DOMParser().parseFromString(textHTML, "text/html") 之后所有的单独回车符都会转换为换行符,产生多余的换行
323+ // 需移除回车符,否则 new DOMParser().parseFromString(textHTML, "text/html") 之后所有单独的回车符都会转换为换行符,产生多余的换行
326324 textHTML = textHTML . replace ( / \r / g, "" ) ;
327325 // process word
328326 const doc = new DOMParser ( ) . parseFromString ( textHTML , "text/html" ) ;
@@ -510,17 +508,17 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
510508 }
511509 }
512510 if ( isHTML ) {
513- // 不能用 new DOMParser().parseFromString(textHTML, "text/html"),否则之后 getComputedStyle() 无效
514- const element = document . createElement ( "div" ) ;
515- element . style . visibility = "hidden" ;
516- element . style . position = "absolute" ;
517- document . body . appendChild ( element ) ;
518- element . innerHTML = textHTML ;
519-
520511 const tempElement = document . createElement ( "div" ) ;
521- tempElement . innerHTML = processHTMLElement ( element ) ;
522- element . remove ( ) ;
523-
512+ tempElement . innerHTML = textHTML . replace ( / \n / g, "<br>" ) ;
513+ tempElement . querySelectorAll ( "[style]" ) . forEach ( ( e ) => {
514+ e . removeAttribute ( "style" ) ;
515+ } ) ;
516+ // 移除空的 A 标签
517+ tempElement . querySelectorAll ( "a" ) . forEach ( ( e ) => {
518+ if ( e . innerHTML . trim ( ) === "" ) {
519+ e . remove ( ) ;
520+ }
521+ } ) ;
524522 // https://github.com/siyuan-note/siyuan/issues/14625#issuecomment-2869618067
525523 let linkElement ;
526524 if ( tempElement . childElementCount === 1 && tempElement . childNodes . length === 1 ) {
@@ -612,74 +610,3 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
612610 scrollCenter ( protyle , undefined , false , "smooth" ) ;
613611 }
614612} ;
615-
616- const processHTMLElement = ( element : Element ) => {
617- let html = "" ;
618- // 遍历所有子节点
619- Array . from ( element . childNodes ) . forEach ( node => {
620- if ( node . nodeType === 3 ) {
621- // 处理文本节点
622- const whiteSpace = getComputedStyle ( element ) . whiteSpace ;
623- html += processTextByWhiteSpace ( node . textContent , whiteSpace ) ;
624- } else if ( node . nodeType === 1 ) {
625- // 处理元素节点
626- const childElement = node as HTMLElement ;
627- const tagName = childElement . tagName . toLowerCase ( ) ;
628- if ( new Set ( [ "area" , "base" , "br" , "col" , "embed" , "hr" , "img" , "input" ,
629- "link" , "meta" , "param" , "source" , "track" , "wbr" ] ) . has ( tagName ) ) {
630- // 空元素不能存在子节点、不能有结束标签
631- childElement . removeAttribute ( "style" ) ;
632- html += childElement . outerHTML ;
633- } else if ( tagName === "a" && ( node as HTMLElement ) . innerHTML . trim ( ) === "" ) {
634- // 过滤空的 A 标签
635- } else {
636- // 递归处理元素节点
637- const attrs = getAttributes ( childElement ) ;
638- const processedInnerHTML = processHTMLElement ( childElement ) ;
639- html += `<${ tagName } ${ attrs } >${ processedInnerHTML } </${ tagName } >` ;
640- }
641- }
642- } ) ;
643-
644- return html ;
645- } ;
646-
647- // 根据 white-space 属性处理文本中的空白字符 https://github.com/siyuan-note/siyuan/issues/14775
648- const processTextByWhiteSpace = ( text : string , whiteSpace : string ) => {
649- // 替换不使用'\s',因为它包含不断行空白字符等其他字符
650- // 替换不使用'\r',因为换行符在前面已经移除
651- // 行末的空白字符会被 Lute 移除,这里无需处理
652- switch ( whiteSpace ) {
653- default :
654- case "normal" :
655- case "nowrap" :
656- // 合并相连的空白符为一个空格(空格、制表符、换行符)
657- // return text.replace(/[ \t\n]+/g, " ");
658- // 前面不知道哪个步骤已经合并空白符
659- // return text;
660- /* falls through */
661- case "pre-line" :
662- // 合并其他相连的空白符为一个空格,保留换行(换行符转换为<br>)
663- // text = text.replace(/[ \t]+/g, " ");
664- // 前面不知道哪个步骤已经合并空白符
665- /* falls through */
666- case "pre" :
667- case "pre-wrap" :
668- case "break-spaces" :
669- // 不合并其他空白符,保留换行(换行符转换为<br>)
670- return text . replace ( / \n / g, "<br>" ) ;
671- }
672- } ;
673-
674- const getAttributes = ( element : Element ) => {
675- const attrs : string [ ] = [ ] ;
676- for ( let i = 0 ; i < element . attributes . length ; i ++ ) {
677- const attr = element . attributes [ i ] ;
678- // 顺便移除 style 属性
679- if ( attr . name . toLowerCase ( ) === "style" ) {
680- continue ;
681- }
682- attrs . push ( `${ attr . name } ="${ escapeAttr ( attr . value ) } "` ) ;
683- }
684- return attrs . length > 0 ? " " + attrs . join ( " " ) : "" ;
685- } ;
0 commit comments