diff --git a/src/SingleObserver/DomWrapper.tsx b/src/SingleObserver/DomWrapper.tsx deleted file mode 100644 index 83c7646..0000000 --- a/src/SingleObserver/DomWrapper.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; - -export interface DomWrapperProps { - children: React.ReactElement; -} - -/** - * Fallback to findDOMNode if origin ref do not provide any dom element - */ -export default class DomWrapper extends React.Component { - render() { - return this.props.children; - } -} diff --git a/src/SingleObserver/HTMLComment.tsx b/src/SingleObserver/HTMLComment.tsx new file mode 100644 index 0000000..b0712ef --- /dev/null +++ b/src/SingleObserver/HTMLComment.tsx @@ -0,0 +1,81 @@ +import React from "react"; + +export interface CommentProps { + data?: string; +} + +type ElementLike = { + setAttribute: () => boolean; + style: object; +}; + +const TagSymbol = `comment__`; + +const canUseDom = () => { + return !!( + typeof window !== "undefined" && + window.document && + window.document.createElement + ); +}; + +function intercept() { + const createElement = document.createElement; + + const reset = () => { + document.createElement = createElement; + }; + + //react 内部是用这个创建文本节点的 由于react本身不支持创建注释节点 这里hack一下 + document.createElement = function ( + tagName: string, + options?: ElementCreationOptions + ) { + if ( + tagName === "noscript" && + options?.is && + options.is.startsWith(TagSymbol) + ) { + const regex = new RegExp(`^${TagSymbol}(.*)$`); + const match = options?.is.match(regex); + if (match) { + const data = match[1].trim?.(); + const comment = document.createComment(data) as unknown as ElementLike; + comment.setAttribute = () => true; + comment.style = {}; + reset(); + return comment as unknown as HTMLElement; + } + } + return createElement.call(this, tagName, options); + }; +} + +function CommentRender( + { data = "" }: CommentProps, + ref: React.ForwardedRef +) { + const mounted = React.useRef(false); + if (!mounted.current) { + if (canUseDom()) { + intercept(); + } + mounted.current = true; + } + return ( +