web-shield.js
Version:
Content security library to prevent downloading videos, copying text, and saving images
25 lines (22 loc) • 13.5 kB
JavaScript
"use strict";var d=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames,g=Object.getOwnPropertySymbols;var S=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var w=(o,e,t)=>e in o?d(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t,l=(o,e)=>{for(var t in e||(e={}))S.call(e,t)&&w(o,t,e[t]);if(g)for(var t of g(e))x.call(e,t)&&w(o,t,e[t]);return o};var D=(o,e)=>{for(var t in e)d(o,t,{get:e[t],enumerable:!0})},T=(o,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of L(e))!S.call(o,n)&&n!==t&&d(o,n,{get:()=>e[n],enumerable:!(r=O(e,n))||r.enumerable});return o};var k=o=>T(d({},"__esModule",{value:!0}),o);var I={};D(I,{ImageShield:()=>y,TextShield:()=>u,VideoShield:()=>v,default:()=>M});module.exports=k(I);function s(o,e=document){try{return Array.from(e.querySelectorAll(o))}catch(t){return console.warn(`web-shield: Error with selector "${o}"`,t),[]}}function a(o,e,t){try{return o.addEventListener(e,t),!0}catch(r){return console.warn(`web-shield: Error adding ${e} event listener`,r),!1}}var p=class{constructor(e={}){this.eventListeners=[];this.styleElement=null;this.mutationObserver=null;this.options=l({preventRightClick:!0,hideControls:!1,disableDevTools:!0,targetSelector:"video",observeDynamicContent:!0},e),this.initialize()}initialize(){try{if(typeof document=="undefined")return;let e=this.options.targetSelector||"video";this.protectVideoElements(e),this.options.disableDevTools&&this.interceptMediaElements(),this.options.observeDynamicContent&&this.setupMutationObserver()}catch(e){console.error("web-shield: Error initializing VideoShield",e)}}protectVideoElements(e){try{s(e).forEach(t=>{if(t instanceof HTMLVideoElement&&(this.options.hideControls&&(t.controls=!1),this.options.preventRightClick)){let r=n=>(n.preventDefault(),!1);a(t,"contextmenu",r),this.eventListeners.push({element:t,type:"contextmenu",handler:r})}})}catch(t){console.error("web-shield: Error protecting video elements",t)}}interceptMediaElements(){try{let e=this.options.targetSelector||"video",t=e.split(",").map(r=>r.trim()+"::-webkit-media-controls-enclosure, "+r.trim()+"::-webkit-media-controls-panel, "+r.trim()+"::-webkit-media-controls-overlay-play-button").join(", ");this.styleElement=document.createElement("style"),this.styleElement.innerHTML=`
/* Chrome, Safari, and Opera */
${t},
/* Firefox */
${e.split(",").map(r=>r.trim()+"::-moz-media-controls").join(", ")},
/* Edge and IE */
${e.split(",").map(r=>r.trim()+"::-ms-media-controls, "+r.trim()+"::-ms-media-controls-play-pause").join(", ")},
/* Generic */
${e.split(",").map(r=>r.trim()+"::media-controls").join(", ")} {
display: none !important;
opacity: 0 !important;
visibility: hidden !important;
}
`,document.head.appendChild(this.styleElement)}catch(e){console.error("web-shield: Error setting up video style protection",e)}}setupMutationObserver(){try{if(!window.MutationObserver)return;let e=this.options.targetSelector||"video";this.mutationObserver=new MutationObserver(t=>{t.forEach(r=>{r.type==="childList"&&r.addedNodes.length>0&&r.addedNodes.forEach(n=>{n.nodeType===Node.ELEMENT_NODE&&(n.matches&&n.matches(e)&&this.protectVideoElements(e),n.hasChildNodes()&&this.protectVideoElements(e))})})}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}catch(e){console.error("web-shield: Error setting up mutation observer for videos",e)}}disable(){try{this.eventListeners.forEach(({element:e,type:t,handler:r})=>{try{e.removeEventListener(t,r)}catch(n){console.warn(`web-shield: Error removing ${t} event listener`,n)}}),this.eventListeners=[],this.styleElement&&this.styleElement.remove(),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),s("video").forEach(e=>{e instanceof HTMLVideoElement&&(e.controls=!0)})}catch(e){console.error("web-shield: Error disabling VideoShield",e)}}},v=p;var m=class{constructor(e={}){this.eventListeners=[];this.styleElement=null;this.mutationObserver=null;this.options=l({preventSelection:!0,preventCopy:!0,preventPrintScreen:!1,targetSelector:"p, h1, h2, h3, h4, h5, h6, span, div",observeDynamicContent:!0},e),this.initialize()}initialize(){try{if(typeof document=="undefined")return;this.options.preventSelection&&this.applySelectionProtection(),this.options.preventCopy&&this.applyCopyProtection(),this.options.preventPrintScreen&&this.applyPrintScreenProtection(),this.options.observeDynamicContent&&this.setupMutationObserver()}catch(e){console.error("web-shield: Error initializing TextShield",e)}}applySelectionProtection(){try{this.styleElement=document.createElement("style"),this.styleElement.innerHTML=`
.web-shield-text {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
`,document.head.appendChild(this.styleElement);let e=this.options.targetSelector||"p, h1, h2, h3, h4, h5, h6, span, div";this.protectTextElements(e);let t=r=>{if(r.target instanceof Element){let n=r.target;for(;n;){if(n.matches&&n.matches(e))return r.preventDefault(),!1;n=n.parentElement}}};a(document,"selectstart",t),this.eventListeners.push({element:document,type:"selectstart",handler:t})}catch(e){console.error("web-shield: Error applying selection protection",e)}}protectTextElements(e){try{s(e).forEach(t=>{t.classList.add("web-shield-text")})}catch(t){console.error("web-shield: Error protecting text elements",t)}}applyCopyProtection(){try{let e=this.options.targetSelector||"p, h1, h2, h3, h4, h5, h6, span, div",t=r=>{if(window.getSelection){let n=window.getSelection();if(n&&n.rangeCount>0){let i=n.getRangeAt(0),E=document.createElement("div");if(E.appendChild(i.cloneContents()),E.querySelectorAll(e).length>0||r.target instanceof Element&&function(C){let c=C;for(;c;){if(c.matches&&c.matches(e))return!0;c=c.parentElement}return!1}(r.target))return r.preventDefault(),!1}}};a(document,"copy",t),a(document,"cut",t),this.eventListeners.push({element:document,type:"copy",handler:t},{element:document,type:"cut",handler:t})}catch(e){console.error("web-shield: Error applying copy protection",e)}}applyPrintScreenProtection(){try{let e=t=>{try{let r=t;if(r.key==="PrintScreen"||r.ctrlKey&&r.key==="p"||r.ctrlKey&&r.shiftKey&&r.key==="I")return t.preventDefault(),!1}catch(r){console.error("web-shield: Error in keydown handler",r)}};a(document,"keydown",e),this.eventListeners.push({element:document,type:"keydown",handler:e})}catch(e){console.error("web-shield: Error applying print screen protection",e)}}setupMutationObserver(){try{if(!window.MutationObserver)return;let e=this.options.targetSelector||"p, h1, h2, h3, h4, h5, h6, span, div";this.mutationObserver=new MutationObserver(t=>{t.forEach(r=>{r.type==="childList"&&r.addedNodes.length>0&&r.addedNodes.forEach(n=>{n.nodeType===Node.ELEMENT_NODE&&(n.matches&&n.matches(e)&&n.classList.add("web-shield-text"),s(e,n).forEach(i=>{i.classList.add("web-shield-text")}))})})}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}catch(e){console.error("web-shield: Error setting up mutation observer",e)}}disable(){try{this.styleElement&&this.styleElement.remove(),s(".web-shield-text").forEach(e=>{e.classList.remove("web-shield-text")}),this.eventListeners.forEach(({element:e,type:t,handler:r})=>{try{e.removeEventListener(t,r)}catch(n){console.warn(`web-shield: Error removing ${t} event listener`,n)}}),this.eventListeners=[],this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null)}catch(e){console.error("web-shield: Error disabling TextShield",e)}}},u=m;var b=class{constructor(e={}){this.eventListeners=[];this.watermarkElements=[];this.mutationObserver=null;this.options=l({preventRightClick:!0,preventDrag:!0,addWatermark:!1,targetSelector:"img",observeDynamicContent:!0,convertToCanvas:!1},e),this.initialize()}initialize(){try{if(typeof document=="undefined")return;let e=this.options.targetSelector||"img";this.protectImageElements(e),this.options.observeDynamicContent&&this.setupMutationObserver()}catch(e){console.error("web-shield: Error initializing ImageShield",e)}}protectImageElements(e){try{s(e).forEach(t=>{if(t instanceof HTMLImageElement){if(this.options.preventRightClick){let r=n=>(n.preventDefault(),!1);a(t,"contextmenu",r),this.eventListeners.push({element:t,type:"contextmenu",handler:r})}if(this.options.preventDrag){t.setAttribute("draggable","false");let r=n=>(n.preventDefault(),!1);a(t,"dragstart",r),this.eventListeners.push({element:t,type:"dragstart",handler:r})}this.options.addWatermark&&this.applyWatermark(t),this.options.convertToCanvas&&this.convertImageToCanvas(t)}})}catch(t){console.error("web-shield: Error protecting image elements",t)}}applyWatermark(e){try{let t=document.createElement("div");t.style.position="relative",t.style.display="inline-block";let r=e.parentNode;if(r){r.insertBefore(t,e),t.appendChild(e);let n=document.createElement("div");n.style.position="absolute",n.style.top="0",n.style.left="0",n.style.width="100%",n.style.height="100%",n.style.display="flex",n.style.alignItems="center",n.style.justifyContent="center",n.style.pointerEvents="none",n.style.color="rgba(255,255,255,0.5)",n.style.fontSize="24px",n.style.fontWeight="bold",n.style.textShadow="1px 1px 2px rgba(0,0,0,0.7)",n.style.transform="rotate(-45deg)";let i=typeof this.options.addWatermark=="string"?this.options.addWatermark:"Protected";n.textContent=i,t.appendChild(n),this.watermarkElements.push(n)}}catch(t){console.error("web-shield: Error applying watermark",t)}}convertImageToCanvas(e){try{e.complete?this.replaceWithCanvas(e):e.addEventListener("load",()=>this.replaceWithCanvas(e))}catch(t){console.error("web-shield: Error converting image to canvas",t)}}replaceWithCanvas(e){try{let t=document.createElement("canvas"),r=t.getContext("2d");if(!r)return;if(t.width=e.naturalWidth,t.height=e.naturalHeight,t.style.width=e.clientWidth+"px",t.style.height=e.clientHeight+"px",t.className=e.className,t.id=e.id,r.drawImage(e,0,0),this.options.addWatermark){let i=typeof this.options.addWatermark=="string"?this.options.addWatermark:"Protected";r.save(),r.globalAlpha=.5,r.font="bold 24px sans-serif",r.fillStyle="white",r.textAlign="center",r.textBaseline="middle",r.translate(t.width/2,t.height/2),r.rotate(-Math.PI/4),r.fillText(i,0,0),r.restore()}e.parentNode&&e.parentNode.replaceChild(t,e),t.addEventListener("contextmenu",i=>i.preventDefault());let n=t.toDataURL;if(r){let i=r.getImageData;t.toDataURL=function(){return console.error("web-shield: Direct image export prevented"),""},r.getImageData=function(){return console.error("web-shield: Direct pixel access prevented"),new ImageData(1,1)}}}catch(t){console.error("web-shield: Error replacing image with canvas",t)}}setupMutationObserver(){try{if(!window.MutationObserver)return;let e=this.options.targetSelector||"img";this.mutationObserver=new MutationObserver(t=>{t.forEach(r=>{r.type==="childList"&&r.addedNodes.length>0&&r.addedNodes.forEach(n=>{n.nodeType===Node.ELEMENT_NODE&&(n.matches&&n.matches(e)&&this.protectImageElements(e),n.hasChildNodes()&&this.protectImageElements(e))})})}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}catch(e){console.error("web-shield: Error setting up mutation observer for images",e)}}disable(){try{this.eventListeners.forEach(({element:e,type:t,handler:r})=>{try{e.removeEventListener(t,r)}catch(n){console.warn(`web-shield: Error removing ${t} event listener`,n)}}),this.eventListeners=[],this.watermarkElements.forEach(e=>{try{e.remove()}catch(t){console.warn("web-shield: Error removing watermark",t)}}),this.watermarkElements=[],s("img").forEach(e=>{e instanceof HTMLImageElement&&e.removeAttribute("draggable")}),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null)}catch(e){console.error("web-shield: Error disabling ImageShield",e)}}},y=b;var h=class h{constructor(e={}){this.videoShield=null;this.textShield=null;this.imageShield=null;this.options=e,this.initialize()}initialize(){try{if(this.options.video){let e=typeof this.options.video=="boolean"?{}:this.options.video;this.options.observeDynamicContent!==void 0&&e.observeDynamicContent===void 0&&(e.observeDynamicContent=this.options.observeDynamicContent),this.videoShield=new v(e)}if(this.options.text){let e=typeof this.options.text=="boolean"?{}:this.options.text;this.options.observeDynamicContent!==void 0&&e.observeDynamicContent===void 0&&(e.observeDynamicContent=this.options.observeDynamicContent),this.textShield=new u(e)}if(this.options.image){let e=typeof this.options.image=="boolean"?{}:this.options.image;this.options.observeDynamicContent!==void 0&&e.observeDynamicContent===void 0&&(e.observeDynamicContent=this.options.observeDynamicContent),this.imageShield=new y(e)}}catch(e){console.error("web-shield: Error initializing WebShield",e)}}verifyIntegrity(){try{h.VERSION!=="0.1.1"&&console.warn("web-shield: Library integrity may be compromised")}catch(e){}}disable(){var e,t,r;try{(e=this.videoShield)==null||e.disable(),(t=this.textShield)==null||t.disable(),(r=this.imageShield)==null||r.disable()}catch(n){console.error("web-shield: Error disabling WebShield",n)}}};h.VERSION="0.1.1";var f=h,M=f;0&&(module.exports={ImageShield,TextShield,VideoShield});
//# sourceMappingURL=index.cjs.js.map