@ifreeovo/highlight-dom
Version:
实现类似dom-inspector的高亮效果
91 lines (76 loc) • 13.5 kB
JavaScript
import{isFunction as t,isPrimitive as e,partial as o}from"radash";import{getMaxZIndex as i,$ as r,removeDom as s,getBoxModelHeight as n,getBoxModelWidth as d,calcTop as h,calcLeft as p,getElementInfo as a}from"./dom.js";import l from"./plugin.js";import"tapable";function c(t,e,o,i){if("a"===o&&!i)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===o?i:"a"===o?i.call(t):i?i.value:e.get(t)}var g;function m(o,...i){let r=o[0];for(let s=0,n=i.length;s<n;s++){const n=i[s];if(t(n))r+=n();else{if(!e(n))throw new Error(`不支持处理类型${Object.prototype.toString.call(n)}`);r+=n}r+=o[s+1]}return r}function $(t,e=""){return t.replace(/\.[\w-]+(?=[^{}]*\{)/g,(t=>`${t}-${e}`))}"function"==typeof SuppressedError&&SuppressedError;class f{constructor({zIndex:t=i()+1,portal:e=document.documentElement,cache:o=!0,hash:r,pluginManager:s=new l}={}){this.fragments="",g.set(this,new WeakMap),this.style="",this.tipFontSize="12px",this.tipBackgroundColor="#333740",this.tipTagColor="#e776e0",this.tipIdColor="#eba062",this.tipClassColor="#8dd2fb",this.tipLineColor="#fff",this.tipSizeColor="#fff",this.marginBackgroundColor="rgb(246 178 107 / 66%)",this.borderBackgroundColor="rgb(255 229 153 / 66%)",this.paddingBackgroundColor="rgb(147 196 125 / 55%)",this.contentBackgroundColor="rgb(111 169 220 / 66%)",this.pluginManager=s,this.pluginManager.hooks.beforeInitOverlay.call(this),this.zIndex=t,this.portal=e,this.cache=o,this.hash=r,this.createContainer(),this.createOverlayStyle(this.hash),this.pluginManager.hooks.afterInitOverlay.call(this)}static getInstance(t){return f.instance||(f.instance=new f(t)),f.instance}defineDefaultTheme(t){return $(m`
.dom-inspector {
position: fixed;
pointer-events: none;
transform-origin: 0 0;
}
.dom-inspector > div {
position: absolute;
pointer-events: none;
}
.dom-inspector-wrapper .tips {
position: fixed;
right: auto;
max-width: 100%;
padding: 3px 10px;
font-size: 0;
line-height: 18px;
pointer-events: none;
background-color: ${this.tipBackgroundColor};
border-radius: 4px;
}
.dom-inspector-wrapper .tips .tips-triangle {
position: absolute;
bottom: -16px;
left: 10px;
width: 0;
height: 0;
border-top: 8px solid ${this.tipBackgroundColor};
border-right: 8px solid transparent;
border-bottom: 8px solid transparent;
border-left: 8px solid transparent;
}
.dom-inspector-wrapper .reverse .tips-triangle {
top: -16px;
left: 10px;
border-top: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid ${this.tipBackgroundColor};
border-left: 8px solid transparent;
}
.dom-inspector-wrapper .tips > div {
display: inline-block;
overflow: auto;
font-family: Consolas, Menlo, Monaco, Courier, monospace;
font-size: ${this.tipFontSize};
vertical-align: middle;
}
.dom-inspector-wrapper .tips .tips-tag {
color: ${this.tipTagColor};
}
.dom-inspector-wrapper .tips .tips-id {
color: ${this.tipIdColor};
}
.dom-inspector-wrapper .tips .tips-class {
color: ${this.tipClassColor};
}
.dom-inspector-wrapper .tips .tips-line {
color: ${this.tipLineColor};
}
.dom-inspector-wrapper .tips .tips-size {
color: ${this.tipSizeColor};
}
.dom-inspector .dom-inspector-margin {
background-color: ${this.marginBackgroundColor};
}
.dom-inspector .dom-inspector-border {
background-color: ${this.borderBackgroundColor};
}
.dom-inspector .dom-inspector-padding {
background-color: ${this.paddingBackgroundColor};
}
.dom-inspector .dom-inspector-content {
background-color: ${this.contentBackgroundColor};
}
`,t)}createOverlayStyle(t){var e;const o=`tag-v-${t}`;if(r(`[${o}]`))return;const i=document.createElement("style");this.style=this.defineDefaultTheme(t),this.pluginManager.hooks.generateCss.call(this),i.setAttribute(o,""),i.textContent=this.style,null===(e=r("head"))||void 0===e||e.append(i)}clearCache(){!function(t,e,o,i,r){if("m"===i)throw new TypeError("Private method is not writable");if("a"===i&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!r:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");"a"===i?r.call(t,o):r?r.value=o:e.set(t,o)}(this,g,new WeakMap,"f")}removeContainer(){s(this.container),this.container=void 0,f.instance=void 0}createContainer(){if(this.container)return;const t=`dom-inspector-container-${this.hash}`,e=document.createElement("div");e.id=t,e.style.zIndex=this.zIndex.toString(),this.container=e,this.portal.appendChild(this.container)}createInspector(t){const{domInspector:e,domInspectorContent:o,domInspectorPaddingTop:i,domInspectorPaddingBottom:r,domInspectorPaddingRight:s,domInspectorPaddingLeft:n,domInspectorBorderTop:d,domInspectorBorderRight:h,domInspectorBorderBottom:p,domInspectorBorderLeft:a,domInspectorMarginTop:l,domInspectorMarginRight:c,domInspectorMarginBottom:g,domInspectorMarginLeft:m}=t;return`<div class="dom-inspector-${this.hash}" style="z-index: ${this.zIndex}; width: ${e.width}; height: ${e.height}; top: ${e.top}; left: ${e.left};">\n <div class="dom-inspector-content-${this.hash}" style="width: ${o.width}; height: ${o.height}; top: ${o.top}; left: ${o.left};"></div>\n <div class="dom-inspector-padding-${this.hash} dom-inspector-padding-top-${this.hash}" style="width: ${i.width}; height: ${i.height}; top: ${i.top}; left: ${i.left};"></div>\n <div class="dom-inspector-padding-${this.hash} dom-inspector-padding-right-${this.hash}" style="width: ${s.width}; height: ${s.height}; top: ${s.top}; left: ${s.left};"></div>\n <div class="dom-inspector-padding-${this.hash} dom-inspector-padding-bottom-${this.hash}" style="width: ${r.width}; height: ${r.height}; top: ${r.top}; left: ${r.left};"></div>\n <div class="dom-inspector-padding-${this.hash} dom-inspector-padding-left-${this.hash}" style="width: ${n.width}; height: ${n.height}; top: ${n.top}; left: ${n.left};"></div>\n <div class="dom-inspector-border-${this.hash} dom-inspector-border-top-${this.hash}" style="width: ${d.width}; height: ${d.height}; top: ${d.top}; left: ${d.left};"></div>\n <div class="dom-inspector-border-${this.hash} dom-inspector-border-right-${this.hash}" style="width: ${h.width}; height: ${h.height}; top: ${h.top}; left: ${h.left};"></div>\n <div class="dom-inspector-border-${this.hash} dom-inspector-border-bottom-${this.hash}" style="width: ${p.width}; height: ${p.height}; top: ${p.top}; left: ${p.left};"></div>\n <div class="dom-inspector-border-${this.hash} dom-inspector-border-left-${this.hash}" style="width: ${a.width}; height: ${a.height}; top: ${a.top}; left: ${a.left};"></div>\n <div class="dom-inspector-margin-${this.hash} dom-inspector-margin-top-${this.hash}" style="width: ${l.width}; height: ${l.height}; top: ${l.top}; left: ${l.left};"></div>\n <div class="dom-inspector-margin-${this.hash} dom-inspector-margin-right-${this.hash}" style="width: ${c.width}; height: ${c.height}; top: ${c.top}; left: ${c.left};"></div>\n <div class="dom-inspector-margin-${this.hash} dom-inspector-margin-bottom-${this.hash}" style="width:${g.width}; height: ${g.height}; top: ${g.top}; left: ${g.left}"></div>\n <div class="dom-inspector-margin-${this.hash} dom-inspector-margin-left-${this.hash}" style="width: ${m.width}; height: ${m.height}; top: ${m.top}; left: ${m.left};"></div>\n </div>`}createTips(t){const{id:e,tagName:o,classNames:i,size:r,style:s,left:n,tipsClass:d}=t;return`<div class="tips-${this.hash} ${d}" style="${s} ;left: ${n}; z-index: ${this.zIndex+1};">\n <div class="tips-tag-${this.hash}">${o}</div>\n <div class="tips-id-${this.hash}">${e}</div>\n <div class="tips-class-${this.hash}">${i}</div>\n <div class="tips-line-${this.hash}"> | </div>\n <div class="tips-size-${this.hash}">${r}</div>\n <div class="tips-triangle-${this.hash}"></div>\n </div>`}createWrap(t){return`<div style="z-index: ${this.zIndex}" class="dom-inspector-wrapper-${this.hash}">${t}</div>`}defineTemplate(){return t=>this.createWrap(this.createInspector(t)+this.createTips(t))}render(t,e){return t(e)}getInspectorData(t){const e=o(n,t),i=o(d,t),r=i("content"),s=e("content"),a=i("padding"),l=e("padding"),c=i("border"),g=e("border"),m=i("margin"),$=e("margin"),f=o(h,t),w=o(p,t);let x;if(t.isSVG){x={domInspector:{width:`${r}px`,height:`${s}px`,top:`${t.top}px`,left:`${t.left}px`},domInspectorContent:{width:`${r}px`,height:`${s}px`,top:"0px",left:"0px"}};["domInspectorPaddingTop","domInspectorPaddingBottom","domInspectorPaddingLeft","domInspectorPaddingRight","domInspectorBorderTop","domInspectorBorderBottom","domInspectorBorderLeft","domInspectorBorderRight","domInspectorMarginTop","domInspectorMarginBottom","domInspectorMarginLeft","domInspectorMarginRight"].forEach((t=>{x[t]={width:"0px",height:"0px",top:"0px",left:"0px"}}))}else x={domInspector:{width:`${m}px`,height:`${$}px`,top:`${t.top}px`,left:`${t.left}px`},domInspectorContent:{width:`${r}px`,height:`${s}px`,top:f("contentHeight"),left:w("contentWidth")},domInspectorPaddingTop:{width:`${a}px`,height:`${t.paddingTop}px`,top:f("paddingTop"),left:w("paddingLeft")},domInspectorPaddingBottom:{width:a-t.paddingRight+"px",height:`${t.paddingBottom}px`,top:f("paddingBottom"),left:w("paddingLeft")},domInspectorPaddingLeft:{width:`${t.paddingLeft}px`,height:l-t.paddingTop-t.paddingBottom+"px",top:f("contentHeight"),left:w("paddingLeft")},domInspectorPaddingRight:{width:`${t.paddingRight}px`,height:l-t.paddingTop+"px",top:f("contentHeight"),left:w("paddingRight")},domInspectorBorderTop:{width:`${c}px`,height:`${t.borderTopWidth}px`,top:f("borderTopWidth"),left:w("borderLeftWidth")},domInspectorBorderBottom:{width:c-t.borderRightWidth+"px",height:`${t.borderBottomWidth}px`,top:f("borderBottomWidth"),left:w("borderLeftWidth")},domInspectorBorderLeft:{width:`${t.borderLeftWidth}px`,height:g-t.borderTopWidth-t.borderBottomWidth+"px",top:f("paddingTop"),left:w("borderLeftWidth")},domInspectorBorderRight:{width:`${t.borderRightWidth}px`,height:g-t.borderTopWidth+"px",top:f("paddingTop"),left:w("borderRightWidth")},domInspectorMarginTop:{width:`${m}px`,height:`${t.marginTop}px`,top:f("marginTop"),left:w("marginLeft")},domInspectorMarginBottom:{width:m-t.marginRight+"px",height:`${t.marginBottom}px`,top:f("marginBottom"),left:w("marginLeft")},domInspectorMarginLeft:{width:`${t.marginLeft}px`,height:$-t.marginTop-t.marginBottom+"px",top:f("borderTopWidth"),left:w("marginLeft")},domInspectorMarginRight:{width:`${t.marginRight}px`,height:$-t.marginTop+"px",top:f("borderTopWidth"),left:w("marginRight")}};return x}getTipsData(t){const e=o(n,t),i=o(d,t),r={id:t.id?`#${t.id}`:"",tagName:t.tagName.toLowerCase(),classNames:[...t.classList].map((t=>`.${t}`)).join(""),size:`${i("border")}x${e("border")}`,tipsClass:"",style:"",left:"0px"};let s=0;return t.top>=32?(s=t.top-24-8,r.style=`bottom:${t.bottom+e("margin")+8}px;`):(s=n(t,"margin")+t.top+8,r.tipsClass=`reverse-${this.hash}`,r.style=`top:${s}px;`),r.left=`${t.left}px`,r}getData(t){return Object.assign(Object.assign({},this.getInspectorData(t)),this.getTipsData(t))}create(t){const e=a(t),o=this.getData(e);let i;const r=c(this,g,"f").get(t);r?i=r:(i=this.render(this.defineTemplate(),o),this.cache&&c(this,g,"f").set(t,i));const s={target:t,elementInfo:e,data:o,fragment:i};this.pluginManager.hooks.beforeCreateOverlay.call(this,s),this.fragments+=s.fragment,this.pluginManager.hooks.afterCreateOverlay.call(this)}mount(){var t;this.pluginManager.hooks.beforeMountOverlay.call(this);const e=document.createRange().createContextualFragment(this.fragments);this.fragments="",null===(t=this.container)||void 0===t||t.appendChild(e),this.pluginManager.hooks.afterMountOverlay.call(this)}}g=new WeakMap;export{f as default,m as styled,$ as transformCss};
//# sourceMappingURL=overlay.js.map