print-of-dom
Version:
单独的对一个DOM进行打印,并且可以进行修改,过滤,删除的处理
1 lines • 4.8 kB
JavaScript
(()=>{"use strict";var e={d:(t,n)=>{for(var o in n)e.o(n,o)&&!e.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function n(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}e.d(t,{default:()=>r});class o{constructor(){this.print=this._print.bind(this)}_print(e,t){this.initOptions(t);const{debug:n}=this.options;try{e=this.getDom(e),this.setOwnerDocument(e)}catch(e){return void Promise.reject(e)}e!==this.ownerDocument.documentElement&&e!==this.ownerDocument||(e=this.ownerDocument.body);let o=this.cloneDom(e,((e,t)=>("CANVAS"===e.tagName&&(t=this.canvasToImage(e)),this.handler(e,t,{cssText:this.getDomComputedCssText(e),className:e.className}))));if(!o)return void Promise.reject("The root node cannot be empty.");o=this.wrapDoms(e,o);let r=this.createIframe(o);this.copyStyleEls(r);const s=this.iframeLoaded(r).then((()=>{r.contentWindow.print(),!n&&r.remove()}));return n&&(this.$debugDIframe&&this.$debugDIframe.remove(),this.$debugDIframe=r),s}initOptions(e){"function"==typeof e&&(e={handler:e}),this.options={wrap:!1,regExcludeAttr:null,handler:null,debug:!1,...e},this.options.regExcludeAttr&&(o.regExcludeAttr=this.options.regExcludeAttr)}getDom(e){if("string"==typeof e&&(e=document.querySelector(e)),!e)throw"target DOM not find.";return e}setOwnerDocument(e){if(!e.ownerDocument)throw"The ownerDocument of the target DOM cannot be null.";this.ownerDocument=e.ownerDocument}cloneDom(e,t){const n=[];let o;return function(e,t){let n,o,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"children",s=null,i=0,c=[];for(e=Array.isArray(e)?[...e]:[e],c.push({$root:!0,[r]:[...e]});e.length;)if(n=e[0],s=c[0],n===s)c.shift(),e.shift(),delete s.$currentIndex;else{"$currentIndex"in s?s.$currentIndex++:s.$currentIndex=0;const l=t(n,{index:i++,parent:s,currentIndex:s.$currentIndex,parents:c});if("break"===l)break;"continue"!==l&&(o=n[r])?(c.unshift(n),Array.prototype.unshift.apply(e,o)):e.shift()}c.forEach((e=>{delete e.$currentIndex}))}([e],((e,o)=>{let{parent:r}=o;if(e.nodeType===Node.COMMENT_NODE||"SCRIPT"===e.tagName)return;const s=t(e,e.cloneNode(!1));if(!s)return"continue";s.nodeType===Node.ELEMENT_NODE&&(e.PRINT_OF_DOM_CLONEDOM=s,n.push(e)),!r.$root&&r.PRINT_OF_DOM_CLONEDOM&&r.PRINT_OF_DOM_CLONEDOM.appendChild(s)}),"childNodes"),o=e.PRINT_OF_DOM_CLONEDOM,n.forEach((e=>{delete e.PRINT_OF_DOM_CLONEDOM})),o}getDomComputedCssText(e){let t="";if(e.nodeType===Node.ELEMENT_NODE){const n=getComputedStyle(e);let o=n.length;for(;o--;){const e=n.item(o);let r;this.testExcludeAttr(e)&&(r=n.getPropertyValue(e),t+=e+":"+r+";")}}return t}wrapDoms(e,t){if(this.options.wrap){const{body:n,documentElement:o}=this.ownerDocument;let r,s,i,c=e.parentNode;for(;c&&c!==n&&c!==o;)s=this.handler(c,c.cloneNode(!1),{cssText:"position: static;",className:c.className+" print-of-dom__wrap"}),s&&s.nodeType===Node.ELEMENT_NODE&&(r?s.appendChild(r):i=s,r=s),c=c.parentNode;if(s)return i.appendChild(t),s}return t}createIframe(e){const{ownerDocument:t}=this,n=t.createElement("iframe");if(n.className=o.CLASSNAME_IFRAME,n.style.cssText=this.options.debug?"":"position: absolute; z-index: -1; left: -9999px; top: -9999px;",n.width=t.documentElement.clientWidth,n.height=t.documentElement.clientHeight,t.body.appendChild(n),this.handler(t.documentElement,n.contentDocument.documentElement),this.handler(t.body,n.contentDocument.body),"BODY"===e.nodeName){const t=Array.from(e.childNodes);for(const e of t)n.contentDocument.body.appendChild(e)}else n.contentDocument.body.appendChild(e);return n}testExcludeAttr(e){return!o.regExcludeAttr.test(e)}handler(e,t,n){const{handler:o}=this.options;let r;if(n=n||{cssText:e.style.cssText,className:e.className},o&&(r=o(e,t,n),r?r instanceof Node?t=r:r instanceof Object&&(n=r):!1===r&&(t=null)),t&&t.nodeType===Node.ELEMENT_NODE&&(n.cssText&&(t.style.cssText=n.cssText),n.className))try{t.className=n.className}catch(e){}return t}copyStyleEls(e){const t=this.ownerDocument.styleSheets;let n=t.length;for(;n--;)e.contentDocument.head.appendChild(t.item(n).ownerNode.cloneNode(!0))}iframeLoaded(e){const t=Promise.all(Array.from(e.contentDocument.images).map((e=>new Promise((t=>{e.onload=t,e.onerror=t}))))),n=Promise.all(Array.from(e.contentDocument.querySelectorAll("link, style")).map((e=>new Promise((t=>{e.onload=t,e.onerror=t}))))),o=e.contentDocument.fonts.ready;return Promise.all([t,n,o]).then((e=>new Promise((t=>setTimeout(t,100,e)))))}canvasToImage(e){let t=new Image;return t.src=e.toDataURL("image/png",1),t}}n(o,"regExcludeAttr",/^(transition|scroll|overscroll|cursor|animation|inline-size|pointer-events)/),n(o,"CLASSNAME_IFRAME","print-of-dom__iframe");const r=(new o).print;window.printOfDom=t.default})();