const {fileURL} = require('./utils.js') const path = require('path') /* A specialization that ignores webview events and thus allows * webviews to get touch, mouse and wheel events. */ class minimalDOMPadContainer extends DOMScatterContainer { capture(event) { if (event.target.tagName === 'WEBVIEW' || event.target.classList.contains('interactiveElement')) return false return super.capture(event) } } /* A wrapper for a webview that behaves like a virtual tablet browser. * Uses a DOMScatter to zoom and rotate the virtual browser window. * The position of buttons and the border size remain constant. */ class minimalPad { constructor(scatterContainer, { startScale=1.0, minScale=0.25, maxScale=10.5, autoBringToFront=true, type = 'minimal', title="", tabbedView = true, hasTtitleBar = false, // urlList=["https://www.iwm-tuebingen.de/www/index.html"], padMapKey="key", url="https://www.iwm-tuebingen.de/www/index.html", hideOnStart=false, translatable=true, scalable=true, rotatable=true, movableX=true, movableY=true, rotationDegrees=null, rotation=null, onTransform=null, transformOrigin = 'center center', // extras which are in part needed x=0, y=0, width=null, height=null, resizable=false, } ={}) { this.x = x this.y = y this.type = type this.url = url // this.urlList = urlList this.padMapKey = padMapKey, this.title = title, this.hasTtitleBar = hasTtitleBar this.tabbedView = tabbedView this.hideOnStart = hideOnStart this.width = width this.height = height this.minScale = minScale this.maxScale = maxScale this.scatterContainer = scatterContainer this.startScale = startScale this.scale = startScale this.scalable = scalable this.rotatable = rotatable this.rotationDegrees = this.startRotationDegrees this.transformOrigin = transformOrigin this.web = null this.WebviewCounter = 0 this.id=0 this.pointerCounter = 0 this.webviewMap = new Map() this.overlayMap = new Map() this.tabMap = new Map() this.listMap = new Map() this.frame = document.createElement('div') this.frame.classList.add("pad") this.border = 50 / startScale Elements.setStyle(this.frame, { backgroundColor: "#333", position: "absolute", display: 'flex', width: this.width+"px", height: this.height+"px", visibility: "visible", top: 0, left: 0, // boxShadow: `10px 10px 10px rgba(0, 0, 0, 0.5)`, // borderRadius: '10px', overflow: "visible"}) document.body.appendChild( this.frame) this.tabs=document.createElement("div") this.webBackground=document.createElement("div") this.webviewList=document.createElement("div") this.titlebar = document.createElement("div") this.webViewSnapshot=document.createElement("img") this.tabs.classList.add("interactiveElement") this.tabs.classList.add("tabs") // this.tabs.style.display="flex" // this.tabs.style.flexFlow="row nowrap" Elements.setStyle(this.tabs, { position: "absolute", background: "white", overflowX: "auto", overflowY: "hidden", display: "flex", flexFlow:"row nowrap", // justifyContent: "flex-end", alignItems: "flex-end" // overflow: "auto", }) this.titlebar.innerHTML = "" Elements.setStyle(this.titlebar, { color: "#fff", position: "absolute", overflowX: "hidden" }) Elements.setStyle(this.webBackground, { position: "absolute", overflow: "hidden", background: "white" }) this.webviewList.classList.add("interactiveElement") Elements.setStyle(this.webviewList, { position: "absolute", visibility: "hidden", overflow: "auto", background: "white", boxShadow: "5px 5px 10px #bbb" }) /*Elements.setStyle(this.overlay, { position: "absolute", overflow: "auto", background: "white", opacity: "0.8" })*/ Elements.setStyle(this.webViewSnapshot, { position: "absolute", overflow: "auto" }) if(this.hasTtitleBar)this.frame.appendChild(this.titlebar) this.frame.appendChild(this.webBackground) // this.frame.appendChild(this.webViewSnapshot) this.frame.appendChild(this.tabs) this.frame.appendChild(this.webviewList) this.webViewSnapshot.style.visibility="hidden" this.closeButton = this.addButton("../assets/icons/svg/cross.svg", "close") this.backButton = this.addButton("../assets/icons/svg/left.svg", "go back") this.forwardButton = this.addButton("../assets/icons/svg/right.svg", "go forward") this.showWebviewListButton = this.addButton("../assets/icons/svg/flat/ic_list_48px.svg", "show list") this.addNewWebview(this.url) this.backButton.style.opacity = 0.5 this.forwardButton.style.opacity = 0.5 /*for (let callback of window.padLoadedHandler) { callback(this, url) }*/ // this.pseudoFrame = document.createElement('div') this.pseudoFrameTop = document.createElement('div') this.pseudoFrameLeft = document.createElement('div') this.pseudoFrameRight = document.createElement('div') /*Elements.setStyle(this.pseudoFrame, { position: "absolute", top: "0px", left: "0px", width: "100%", height: "100%", pointerEvents: "none" })*/ Elements.setStyle(this.pseudoFrameTop, { position: "absolute", // background: "pink", top: "0px", left: "0px", width: "100%" // height: "50px" }) Elements.setStyle(this.pseudoFrameLeft, { position: "absolute", // background: "pink", top: "0px", left: "0px", // width: "5px", height: "100%" }) Elements.setStyle(this.pseudoFrameRight, { position: "absolute", // background: "pink", top: "0px", right: "0px", // width: "5px", height: "100%" }) this.frame.appendChild(this.pseudoFrameTop) this.frame.appendChild(this.pseudoFrameLeft) this.frame.appendChild(this.pseudoFrameRight) // this.frame.appendChild(this.pseudoFrame) this.pseudoFrameTop.addEventListener('pointerenter',(e)=>{ this.scatter.scalable=false this.web.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameTop.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) this.pseudoFrameLeft.addEventListener('pointerenter',(e)=>{ // e.target.setPointerCapture(e.pointerId) this.scatter.scalable=false this.web.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameLeft.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) this.pseudoFrameRight.addEventListener('pointerenter',(e)=>{ this.scatter.scalable=false this.web.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameRight.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) /*this.web.addEventListener('new-window', (e) => { if(e.url.indexOf("youtube")>-1)return if (urlPadMap.has(e.url)) { let childPad = urlPadMap.get(e.url) childPad.scatter.moveTo(x, y) return childPad } let childPad = new minimalPad(this.scatterContainer, { x: this.scatter.position.x+100, y: this.scatter.position.y+100, url: e.url, width: this.scatter.width, height: this.scatter.height, scalable: true, rotatable: true}) urlPadMap.set(e.url, childPad) for(let callback of window.padLoadedHandler) { callback(childPad, url) } })*/ /*this.backButton.addEventListener('click', (e)=>{ if(this.web.canGoBack()){ TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.web.goBack() } }) this.forwardButton.addEventListener('click', (e)=>{ if(this.web.canGoForward()){ TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.web.goForward() } }) this.closeButton.addEventListener('click', (e)=>{ TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.close() })*/ InteractionMapper.on('tap',this.backButton, e => { if(this.web.canGoBack()){ TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.web.goBack() } }) InteractionMapper.on('tap',this.forwardButton, e => { if(this.web.canGoForward()){ TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.web.goForward() } }) InteractionMapper.on('tap',this.closeButton, e => { TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }}) this.close() }) this.showWebviewListButton.addEventListener('click', (e)=>{ /*TweenMax.to(e.target, 0.1, {scale:"1.1", onComplete: ()=>{ TweenMax.to(e.target, 0.1, {scale:"1.0"}) }})*/ this.webviewList.style.visibility=="visible" ? this.webviewList.style.visibility="hidden" : this.webviewList.style.visibility="visible" }) this.scatter = new DOMScatter(this.frame, scatterContainer, { x: this.x, y: this.y, startScale: this.startScale, width: this.width, height: this.height, minScale: this.minScale, maxScale: this.maxScale, scalable: this.scalable, resizable: true, rotatable: this.rotatable}) let img=document.createElement("img") img.style.width = "70%" img.style.position = "absolute" img.style.bottom = "20%" img.style.right = "20%" img.style.pointerEvents="none" img.src = "../../assets/icons/png/flat/resize.png" this.scatter.resizeButton.appendChild(img) this.scatter.moveTo({x, y}) this.scatter.bringToFront() this.scatter.addTransformEventCallback((e) => { let newBorder = 50 / e.scale if (newBorder !== this.border) { this.border = newBorder this.layout() } }) /*this.test = document.createElement('div') Elements.setStyle(this.test, { position: "absolute", width: "400px", height: "400px", overflow: "auto", background: "pink" }) this.frame.appendChild(this.test) this.test.addEventListener('click',()=>{ // this.frame.style.visibility="hidden" console.log($( this.webBackground ).children()) $( this.webBackground ).children().css( "visibility", "hidden" ) $( this.frame ).children().css( "visibility", "hidden" ) })*/ this.heinz = document.createElement('div') Elements.setStyle(this.heinz, { position: "absolute", background: "pink", top: "0px", left: "0px", width: "100%", opacity: "0.5", display: "inline", height: "100%" }) this.heinz.addEventListener('pointerdown',(e)=>{ console.log('pointer down on Heinz') e.target.style.display="none" }) this.layout() // this.webBackground.appendChild(this.heinz) // this.heinz.classList.add("interactiveElement") } addNewWebview(src){ /* if(this.web!=null){ this.web.style.visibility="hidden" this.web.setAttribute('selected','0') }*/ let timeTouchStart = 0 let webview=document.createElement("webview") this.web=webview // webview.style.pointerEvents="none" webview.setAttribute('loaded','0') this.webBackground.appendChild(webview) this.webviewMap.set(src+this.padMapKey, webview) // console.log("number of webviews",this.webviewMap.size) // $("webview").each(function(i, obj) { // obj.setAttribute('selected','0') // }) Elements.setStyle(webview, { position: "absolute", overflow: "hidden", width: "100%", height: "100%", // border: "1px solid #fff" }) webview.src=src webview.preload= path.join(__dirname, './preloadPad.js') let listItem=document.createElement('div') listItem.className="interactiveElement" listItem.classList.add("webviewListItem") listItem.setAttribute('id',src+this.padMapKey) // listItem.style.height = "5%" // // listItem.style.width = "80%" // listItem.style.marginLeft="10%" // listItem.style.marginTop="5%" listItem.style.padding = "10px" // listItem.style.paddingBottom = "10px" this.webviewList.appendChild(listItem) this.listMap.set(src+this.padMapKey,listItem) webview.setAttribute('id',src+this.padMapKey) this.setSelectedWebview(src+this.padMapKey) this.addNewTab(webview,src) listItem.addEventListener('click',(e)=>{ console.log(e.target.getAttribute('id')) this.setSelectedWebview(e.target.getAttribute('id')) this.webviewList.style.visibility = "hidden" $(this.tabs).animate({scrollLeft: $(".tab[id='"+e.target.getAttribute('id')+"']").prop('offsetLeft') - 10}, "slow") this.enableButtons() }) listItem.addEventListener('pointerenter',(e)=>{ e.target.style.background = "#ddd" let webview=null this.webviewMap.forEach(function (item, key, mapObj) { item.style.visibility="hidden" if(item.getAttribute('id')==e.target.getAttribute("id")){ item.style.visibility="visible" if(item.getAttribute('selected')=='0')item.style.opacity="0.5" webview=item // obj.style.width="50%" // obj.style.height="50%" } }) this.overlayMap.forEach(function (item, key, mapObj) { item.style.visibility="hidden" if(item.getAttribute('id')==e.target.getAttribute("id")){ item.style.visibility="visible" } }) // webview.getAttribute('loaded')=='0' ? this.overlay.style.visibility='visible' : this.overlay.style.visibility='hidden' }) listItem.addEventListener('pointerleave',(e)=>{ e.target.style.background = "#fff" if(e.target.getAttribute('selected')=='1') e.target.style.background = "#999" this.webviewMap.forEach(function (item, key, mapObj) { if(item.getAttribute('selected')=='0'){ item.style.visibility="hidden" } if(item.getAttribute('selected')=='1'){ item.style.visibility="visible" item.style.opacity="1" } // obj.style.width="100%" // obj.style.height="100%" }) }) let overlay = document.createElement('div') overlay.style.position="absolute" overlay.style.width="100%" overlay.style.height="100%" overlay.style.top="0px" overlay.style.left="0px" overlay.style.background="white" overlay.style.opacity="0.6" this.overlayMap.set(src,overlay) let overlayCaptureEvents = document.createElement('div') overlayCaptureEvents.style.position="absolute" overlayCaptureEvents.style.background="lime" overlayCaptureEvents.style.opacity="0.01" overlayCaptureEvents.style.width="100%" overlayCaptureEvents.style.height="100%" overlayCaptureEvents.style.top="0px" overlayCaptureEvents.style.left="0px" // overlay.style.background="white" overlayCaptureEvents.classList.add("interactiveElement") overlayCaptureEvents.addEventListener('touchmove',(e)=>{ e.preventDefault() e.stopPropagation() }) overlayCaptureEvents.addEventListener('pointerup',(e)=>{ e.preventDefault() e.stopPropagation() let p = {x:e.clientX, y:e.clientY} let webviewPosition = Points.fromPageToNode(webview,p) // oldX = 0 // oldY = 0 let d = new Date() console.log("delta Time",d.getTime()-timeTouchStart) // if(d.getTime()-timeTouchStart<150)webview.sendInputEvent({type:'mouseUp', x: (e.clientX-webview.getBoundingClientRect().left)/this.scatter.scale, y: (e.clientY-webview.getBoundingClientRect().top)/this.scatter.scale, button:'left', clickCount: 1}) if(d.getTime()-timeTouchStart<150)webview.sendInputEvent({type:'mouseUp', x: webviewPosition.x, y: webviewPosition.y, button:'left', clickCount: 1}) }) overlayCaptureEvents.addEventListener('pointerdown',(e)=>{ e.preventDefault() e.stopPropagation() this.scatter.bringToFront() let p = {x:e.clientX, y:e.clientY} let webviewPosition = Points.fromPageToNode(webview,p) let d = new Date() timeTouchStart = d.getTime() // webview.sendInputEvent({type:'mouseDown', x: (e.clientX-webview.getBoundingClientRect().left)/this.scatter.scale, y: (e.clientY-webview.getBoundingClientRect().top)/this.scatter.scale, button:'left', clickCount: 1}) webview.sendInputEvent({type:'mouseDown', x: webviewPosition.x, y: webviewPosition.y, button:'left', clickCount: 1}) }) overlayCaptureEvents.addEventListener('pointermove',(e)=>{ if(e.pointerType!='mouse'){ let rotation = Angle.radian2degree(this.scatter.rotation); rotation = (rotation + 360) % 360; let r = Math.sqrt(Math.pow(e.movementX, 2) + Math.pow(e.movementY, 2)); let phi = Angle.radian2degree(Math.atan2(e.movementX, e.movementY)); phi = ((phi) + 630) % 360; let rot = ((rotation + 90) + 630) % 360; let diffAngle = ((0 + rot) + 360) % 360; let phiCorrected = (phi + diffAngle + 360) % 360; let deltaX = r * Math.cos(Angle.degree2radian(phiCorrected)); let deltaY = -r * Math.sin(Angle.degree2radian(phiCorrected)); // if(oldX!=0)deltaX = (e.clientX-oldX) // if(oldY!=0)deltaY = (e.clientY-oldY) // console.log("e.movementY",e.movementY) // webview.sendInputEvent({type:'mouseWheel', x: 0, y: 0, deltaX: e.movementX, deltaY: e.movementY, canScroll: true }) webview.executeJavaScript("window.scrollTo(scrollX+"+(-1*deltaX)+", scrollY+"+ (-1*deltaY)+")") // oldX = e.clientX // oldY = e.clientY } }) overlayCaptureEvents.addEventListener('mousewheel',(e)=>{ console.log("mousewheel",e.deltaY) // webview.sendInputEvent({type:'mouseWheel', x: 0, y: 0, deltaX: e.deltaX, deltaY: -e.deltaY, canScroll: true }) webview.executeJavaScript("window.scrollTo(scrollX+"+e.deltaX+", scrollY+"+ e.deltaY+")") }) let loadAnim = document.createElement("div") loadAnim.style.webkitAnimation= "spin 2s linear infinite" loadAnim.style.animation= "spin 2s linear infinite" loadAnim.style.position = "absolute" document.styleSheets[0].insertRule("div.tabs::-webkit-scrollbar {display: none;}"); document.styleSheets[0].insertRule('\ @keyframes spin {\ from { transform: rotateZ(0deg); }\ to { transform: rotateZ(360deg); }\ }' ) overlay.appendChild(loadAnim) this.webBackground.appendChild(overlay) if(remote.getGlobal('multiUserMode'))this.webBackground.appendChild(overlayCaptureEvents) webview.addEventListener('did-navigate', (e) => { this.enableButtons() //this.backButton.style.opacity = (webview.canGoBack()) ? 1 : 0.5 //this.forwardButton.style.opacity = (webview.canGoForward()) ? 1 : 0.5 }) webview.addEventListener('dom-ready',()=>{ // console.log("DOM READY TABBED WEBVIEW!!!!!!!!!!") listItem.innerHTML=webview.getTitle()+" "+src $(".tab[id='"+src+this.padMapKey+"']").children()[0].innerHTML=webview.getTitle() // $(".tab[id='"+src+"']").children()[0].innerHTML="READY LOADED" $(this.tabs).animate({scrollLeft: $(".tab[id='"+src+"']").prop('offsetLeft') - 10}, "slow") this.titlebar.innerHTML=this.web.getTitle() // this.web.openDevTools() // webview.style.overflow= "auto" // webview.style.overflowY= "hidden" }) webview.addEventListener('ipc-message', (e) => { if(e.channel=='touchStart'){ // console.log("pointer down on webview",e.srcElement) if(e.srcElement.src==webview.src)this.pointerCounter++ this.scatter.bringToFront() } if(e.channel=='touchEnd'){ // console.log("pointer up on webview") if(e.srcElement.src==webview.src)this.pointerCounter-- } if(e.channel=='webviewPointerCancel'){ this.heinz.style.display="inline" } // console.log("pointerCounter",this.pointerCounter) }) /* let {ipcRenderer} = require('electron') ipcRenderer.on('touchStartWebview' ,function(event){ console.log(event) })*/ webview.addEventListener('did-start-loading', ()=>{ webview.setAttribute('loaded','0') overlay.style.visibility="visible" let w = overlay.offsetWidth let h = overlay.offsetHeight let animationSize = w{ // }) webview.addEventListener('did-stop-loading', ()=>{ webview.setAttribute('loaded','1') this.layout() overlay.style.visibility="hidden" }) webview.addEventListener('new-window', (e) => { if (!this.webviewMap.has(e.url+this.padMapKey)){ if(this.tabbedView)this.addNewWebview(e.url) if(!this.tabbedView){ if (urlPadMap.has(e.url)) { let childPad = urlPadMap.get(e.url) childPad.scatter.moveTo(x, y) return childPad } let childPad = new minimalPad(this.scatterContainer, { x: this.scatter.position.x+100, y: this.scatter.position.y+100, url: e.url, tabbedView: false, hasTtitleBar: this.hasTtitleBar, width: this.scatter.width, height: this.scatter.height, scalable: true, rotatable: true}) urlPadMap.set(e.url, childPad) for(let callback of window.padLoadedHandler) { callback(childPad, url) } } } }) this.id++ } setSelectedWebview(id){ let webview=null this.webviewMap.forEach(function (item, key, mapObj) { item.setAttribute('selected','0') item.style.opacity = "0" item.style.visibility = "hidden" if(key==id){ webview=item item.setAttribute('selected','1') item.style.opacity = "1" item.style.visibility = "visible" } }) this.tabMap.forEach(function (tab, key, mapObj) { tab.style.border="none" if(key==id){ tab.style.borderLeft="1px solid black" tab.style.borderTop="1px solid black" tab.style.borderRight="1px solid black" } }) this.listMap.forEach(function (entry, key, mapObj) { entry.style.background = "white" entry.setAttribute('selected','0') if(key==id){ entry.style.background = "#999" entry.setAttribute('selected','1') } }) this.web = webview if(webview.getAttribute('loaded')=='1') this.titlebar.innerHTML=this.web.getTitle() // webview.getAttribute('loaded')=='0' ? this.overlay.style.visibility='visible' : this.overlay.style.visibility='hidden' } addNewTab(webview,src){ this.tabMap.forEach(function (tab, key, mapObj) { tab.style.border="none" }) let tab=document.createElement('div') tab.className="tab" tab.classList.add("interactiveElement") tab.style.display="flex" tab.style.flexFlow="row nowrap" tab.style.textOverflow="ellipsis" tab.setAttribute('id',src+this.padMapKey) // tab.innerHTML=" " tab.style.color="black" tab.style.background="white" tab.style.borderLeft="1px solid black" tab.style.borderTop="1px solid black" tab.style.borderRight="1px solid black" tab.style.position="relative" tab.style.borderRadius="5px 5px 0 0" tab.style.maxWidth="25%" tab.style.height="80%" tab.style.alignItems= "center" // tab.style.display="inline" // tab.style.marginLeft="10px" tab.style.paddingLeft="10px" this.tabs.appendChild(tab) this.tabMap.set(src+this.padMapKey,tab) let newSelectedWebview=null let title = document.createElement('div') title.classList.add('tabTitle') // title.style.display="flex" // title.style.flexFlow="row nowrap" title.style.overflow="hidden" title.style.whiteSpace="nowrap" title.style.textOverflow="ellipsis" title.style.pointerEvents="none" title.innerHTML="New Tab" tab.appendChild(title) let close = document.createElement('img') close.setAttribute('id',src+this.padMapKey) close.classList.add('tabCloseButton') close.style.background="#666" close.style.height="50%" close.style.marginLeft="10px" close.style.marginRight="10px" close.style.borderRadius="100%" close.style.visibility="hidden" close.src = "../../assets/icons/svg/cross.svg" tab.appendChild(close) close.addEventListener('click',(e)=>{ e.stopPropagation() e.preventDefault() let newSelectedItem = false if(this.webviewMap.size>1){ let next=this.getNextTab(e.target.getAttribute("id")) let previous=this.getPreviousTab(e.target.getAttribute("id")) this.webviewMap.forEach(function (item, key, mapObj) { if(item.getAttribute('id')==e.target.getAttribute("id")){ if(item.getAttribute('selected')=='1'){ newSelectedItem=true } mapObj.delete(key) $(item).remove() } }) this.tabMap.forEach(function (tab, key, mapObj) { if(tab.getAttribute('id')==e.target.getAttribute("id")){ mapObj.delete(key) $(tab).remove() } }) this.listMap.forEach(function (entry, key, mapObj) { if(entry.getAttribute('id')==e.target.getAttribute("id")){ mapObj.delete(key) } }) $(".webviewListItem[id='"+e.target.getAttribute("id")+"']").remove() $(e.target).remove() if(newSelectedItem){ next!=null ? this.setSelectedWebview(next.getAttribute('id')) : this.setSelectedWebview(previous.getAttribute('id')) } } this.layout() }) tab.addEventListener('pointerenter',(e)=>{ if(this.webviewMap.size>1)e.target.childNodes[1].style.visibility="visible" let z=this.frame.style.zIndex let webview=null e.target.style.background="#ddd" this.webviewMap.forEach(function (item, key, mapObj) { item.style.visibility="hidden" if(item.getAttribute('id')==e.target.getAttribute("id")){ item.style.visibility="visible" if(item.getAttribute('selected')=='0')item.style.opacity="0.5" webview=item // obj.style.width="50%" // obj.style.height="50%" } }) this.overlayMap.forEach(function (item, key, mapObj) { item.style.visibility="hidden" if(item.getAttribute('id')==e.target.getAttribute("id")){ item.style.visibility="visible" } }) // webview.getAttribute('loaded')=='0' ? this.overlay.style.visibility='visible' : this.overlay.style.visibility='hidden' /*Popup.open({"text":webview.getTitle()}, {x: e.clientX, y: e.clientY}, { fontSize: "2vh", maxWidth: width*0.2, spacing: '10px', notchPosition: 'topLeft', zIndex: z+100})*/ }) tab.addEventListener('pointerleave',(e)=>{ e.target.childNodes[1].style.visibility="hidden" e.target.style.background="#fff" this.webviewMap.forEach(function (item, key, mapObj) { if(item.getAttribute('selected')=='0'){ item.style.visibility="hidden" } if(item.getAttribute('selected')=='1'){ item.style.visibility="visible" item.style.opacity="1" } // obj.style.width="100%" // obj.style.height="100%" }) //this.web.style.visibility="visible" //this.web.style.opacity="1" }) tab.addEventListener('click',(e)=>{ this.tabMap.forEach(function (item, key, mapObj) { item.style.border="none" }) e.target.style.borderLeft="1px solid black" e.target.style.borderTop="1px solid black" e.target.style.borderRight="1px solid black" this.setSelectedWebview(e.target.getAttribute('id')) if(e.target.offsetLeft+e.target.offsetWidth>this.tabs.offsetWidth+this.tabs.scrollLeft){ $(this.tabs).animate({scrollLeft: e.target.offsetLeft-this.tabs.offsetWidth+e.target.offsetWidth}, "slow") } if(e.target.offsetLeft 1){ this.tabs.style.display = "flex" this.showWebviewListButton.style.display = "inline" if(this.hasTtitleBar){ Elements.setStyle(this.webBackground, { top: b+"px", width: w, height: size-b, margin: "1px"}) Elements.setStyle(this.titlebar, { display: "inline"}) } if(!this.hasTtitleBar){ Elements.setStyle(this.webBackground, { width: w, height: size, margin: "1px"}) } } if(this.tabMap.size <= 1){ this.tabs.style.display = "none" this.showWebviewListButton.style.display = "none" if(this.hasTtitleBar){ Elements.setStyle(this.webBackground, { top: b+"px", width: w, height: size, margin: "1px"}) Elements.setStyle(this.titlebar, { display: "inline"}) } if(!this.hasTtitleBar){ Elements.setStyle(this.webBackground, { width: w, height: h, margin: "1px"}) } } if(!this.tabbedView){ this.tabs.style.display = "none" this.showWebviewListButton.style.display = "none" Elements.setStyle(this.webBackground, { width: w, height: h, margin: "1px"}) } } } class minimalPadFromElement { constructor(element, scatterContainer, { startScale=1.0, minScale=0.1, maxScale=1.0, autoBringToFront=true, translatable=true, scalable=true, rotatable=true, movableX=true, movableY=true, rotationDegrees=null, rotation=null, onTransform=null, transformOrigin = 'center center', // extras which are in part needed x=0, y=0, width=null, height=null, resizable=false, } ={}) { this.element = element this.x = x this.y = y this.width = width this.height = height this.minScale = minScale this.maxScale = maxScale this.scatterContainer = scatterContainer this.scale = startScale this.scalable = scalable this.rotatable = rotatable this.rotationDegrees = this.startRotationDegrees this.transformOrigin = transformOrigin this.frame = document.createElement('div') Elements.setStyle(this.frame, { width: this.width+"px", height: this.height+"px", backgroundColor: "#333", position: "fixed", top: 0, left: 0, overflow: "auto"}) this.closeButton = this.addButton("../assets/icons/svg/cross.svg", "close") document.body.appendChild( this.frame) this.border = 50 this.frame.appendChild(this.element) this.title = document.createElement("div") this.title.innerHTML = "" this.title.style.color = "white" // this.frame.appendChild(this.title) Elements.setStyle(this.title, { position: "absolute" }) // this.pseudoFrame = document.createElement('div') this.pseudoFrameTop = document.createElement('div') this.pseudoFrameLeft = document.createElement('div') this.pseudoFrameRight = document.createElement('div') /*Elements.setStyle(this.pseudoFrame, { position: "absolute", top: "0px", left: "0px", width: "100%", height: "100%", pointerEvents: "none" })*/ Elements.setStyle(this.pseudoFrameTop, { position: "absolute", // background: "pink", top: "0px", left: "0px", width: "100%" // height: "50px" }) Elements.setStyle(this.pseudoFrameLeft, { position: "absolute", // background: "pink", top: "0px", left: "0px", // width: "5px", height: "100%" }) Elements.setStyle(this.pseudoFrameRight, { position: "absolute", // background: "pink", top: "0px", right: "0px", // width: "5px", height: "100%" }) this.frame.appendChild(this.pseudoFrameTop) this.frame.appendChild(this.pseudoFrameLeft) this.frame.appendChild(this.pseudoFrameRight) // this.frame.appendChild(this.pseudoFrame) this.pseudoFrameTop.addEventListener('pointerenter',(e)=>{ this.scatter.scalable=false this.element.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameTop.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) this.pseudoFrameLeft.addEventListener('pointerenter',(e)=>{ // e.target.setPointerCapture(e.pointerId) this.scatter.scalable=false this.element.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameLeft.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) this.pseudoFrameRight.addEventListener('pointerenter',(e)=>{ this.scatter.scalable=false this.element.pointerEvents = "none" e.target.style.cursor = "move" }) this.pseudoFrameRight.addEventListener('pointerleave',(e)=>{ this.scatter.scalable=true // this.frame.style.cursor = "initial" }) // this.element.style.overflow = "auto" // this.element.style.position = "absolute" this.layout() this.closeButton.addEventListener('click', ()=>{ this.frame.style.display="none" }) this.scatter = new DOMScatter(this.frame, scatterContainer, { x: this.x, y: this.y, startScale: this.startScale, width: this.width, height: this.height, minScale: this.minScale, maxScale: this.maxScale, scalable: this.scalable, resizable: true, rotatable: this.rotatable}) let img=document.createElement("img") img.style.width = "70%" img.style.position = "absolute" img.style.bottom = "20%" img.style.right = "20%" img.style.pointerEvents="none" img.src = "../../assets/icons/png/flat/resize.png" this.scatter.resizeButton.appendChild(img) this.scatter.bringToFront() this.scatter.addTransformEventCallback((e) => { let newBorder = 50 / e.scale if (newBorder !== this.border) { this.border = newBorder this.layout() } }) this.element.addEventListener('pointerdown', (e) => { this.scatter.bringToFront() }) } close() { // this.frame.style.display="none" this.frame.parentNode.removeChild(this.frame) urlPadMap.delete(this.url) } addButton(src, value) { let button = document.createElement("img") button.type = "image" button.className = "frameButton" button.style.position = "absolute" button.src = fileURL(src) button.value="close" button.draggable = false this.frame.appendChild(button) return button } layout() { let b = this.border let b2 = b * 2 let b8 = b / 8 let b25 = b / 25 let b15 = b / 15 let size = "calc(100% - " + (2*b) +"px)" let h = "calc(100% - " + (b) +"px)" let w = "calc(100% - "+2 +"px)" let w2 = "calc(100% - " + (b+2) +"px)" this.scatter.resizeButton.style.width=b+"px" this.scatter.resizeButton.style.height=b+"px" Elements.setStyle(this.frame, { // borderRadius: b8 + "px", // boxShadow: `${b25}px ${b15}px ${b8}px rgba(0, 0, 0, 0.5)` }) Elements.setStyle(this.element, { width: w, height: h, top: 0+"px", left: 0+"px"}) Elements.setStyle(this.title, { left: (b * 1.5) + "px", fontSize: (b * 0.8) + "px", top: (0.1)+"0px"}) Elements.setStyle(this.pseudoFrameTop, { width: w, height: 0.1*b+"px", margin: "0px"}) Elements.setStyle(this.pseudoFrameLeft, { width: 0.1*b+"px", height: h, margin: "0px"}) Elements.setStyle(this.pseudoFrameRight, { width: 0.1*b+"px", height: h, margin: "0px"}) Elements.setStyle(this.closeButton, { right: (b * 0.75) + "px", bottom: "0px", width: b+"px", height: b+"px"}) } } module.exports = { minimalPad, minimalDOMPadContainer, minimalPadFromElement}