Created
May 24, 2020 11:29
-
-
Save jjrv/258f781646a48f56044ef15fe766a478 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Widget } from '@phosphor/widgets'; | |
import { ElementExt } from '@phosphor/domutils'; | |
export class IframePanel extends Widget { | |
constructor(iframe?: HTMLIFrameElement | null) { | |
super({ node: IframePanel.createNode() }); | |
if(!iframe) iframe = document.createElement('iframe'); | |
this.iframe = iframe; | |
this.addClass('phosphor-iframe'); | |
this.addClass('charto-panel'); | |
this.updateTitle(); | |
this.node.addEventListener('mouseover', this); | |
this.node.addEventListener('mouseout', this); | |
this.node.addEventListener('mouseup', this); | |
iframe.addEventListener('mouseover', this); | |
iframe.addEventListener('mouseout', this); | |
iframe.addEventListener('mouseup', this); | |
iframe.addEventListener('load', this); | |
iframe.classList.add('charto-content'); | |
if(iframe.contentWindow) this.handleEvent(new Event('load')); | |
} | |
static createNode(): HTMLElement { | |
const node = document.createElement('div'); | |
return(node); | |
} | |
handleEvent(event: Event) { | |
switch(event.type) { | |
case 'load': | |
this.iframe.contentWindow!.addEventListener('beforeunload', this); | |
break; | |
case 'beforeunload': | |
const uri = this.iframe.contentWindow!.location.href; | |
const interval = window.setInterval(() => { | |
if(this.iframe.contentWindow && this.iframe.contentWindow.location.href != uri) { | |
this.updateTitle(); | |
// iframe.contentWindow.location.href = 'nonexistent.html'; | |
// this.iframe.contentWindow.location.href = uri; | |
window.clearInterval(interval); | |
} | |
}, 1); | |
break; | |
case 'mouseover': | |
if(event.target == this.iframe) this.overFlags |= 1; | |
if(event.target == this.node) this.overFlags |= 2; | |
// Fallthru | |
case 'mouseup': | |
// Allow iframe to capture events if mouse enters | |
// without primary button pressed. | |
if(!((event as MouseEvent).buttons & 1)) { | |
if(this.overFlags) this.iframe.style.pointerEvents = 'auto'; | |
} | |
break; | |
case 'mouseout': | |
if(event.target == this.iframe) this.overFlags &= ~1; | |
if(event.target == this.node) this.overFlags &= ~2; | |
if(!this.overFlags) this.iframe.style.pointerEvents = 'none'; | |
break; | |
} | |
} | |
updateTitle(uri = '') { | |
if(!uri && this.iframe.contentWindow) uri = this.iframe.contentWindow.location.href; | |
const uriParts = uri.split('/'); | |
this.title.label = uriParts[uriParts.length - 1]; | |
this.title.caption = uri; | |
} | |
onAfterHide() { | |
// Using "display: none" could cause code misbehaviour inside iframe | |
// due to skipped rendering-related computation. | |
this.iframe.style.visibility = 'hidden'; | |
} | |
onAfterShow() { | |
this.iframe.style.visibility = 'visible'; | |
} | |
onResize(msg: Widget.ResizeMessage) { | |
// Move iframe over the content div. Unfortunately reparenting | |
// the iframe would cause it to reload. | |
const rect = this.node.getBoundingClientRect(); | |
const box = ElementExt.boxSizing(this.node); | |
const ibox = ElementExt.boxSizing(this.iframe); | |
this.iframe.style.top = (rect.top + box.borderTop + box.paddingTop) + 'px'; | |
this.iframe.style.left = (rect.left + box.borderLeft + box.paddingLeft) + 'px'; | |
this.iframe.style.width = (rect.right - rect.left - box.horizontalSum - ibox.borderLeft - ibox.borderRight) + 'px'; | |
this.iframe.style.height = (rect.bottom - rect.top - box.verticalSum - ibox.borderTop - ibox.borderBottom) + 'px'; | |
} | |
iframe: HTMLIFrameElement; | |
overFlags = 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as monaco from 'monaco-editor'; | |
import { Widget } from '@phosphor/widgets'; | |
export class MonacoEditor extends Widget { | |
constructor(options?: monaco.editor.IEditorConstructionOptions, override?: monaco.editor.IEditorOverrideServices) { | |
super({ node: MonacoEditor.createNode() }); | |
this.addClass('phosphor-monaco'); | |
this.addClass('charto-panel'); | |
this.editorDiv = document.createElement('div'); | |
this.editorDiv.className = 'charto-content'; | |
this.node.appendChild(this.editorDiv); | |
this.editor = monaco.editor.create(this.editorDiv, options, override); | |
this.editor.onDidChangeModel((event) => this.updateTitle(event.newModelUrl)); | |
this.updateTitle(); | |
} | |
static createNode(): HTMLElement { | |
const node = document.createElement('div'); | |
return(node); | |
} | |
updateTitle(uri = this.editor.getModel().uri) { | |
const fullPath = uri.path; | |
const pathParts = fullPath.split('/'); | |
this.title.label = pathParts[pathParts.length - 1]; | |
this.title.caption = fullPath; | |
} | |
onResize(msg: Widget.ResizeMessage) { | |
this.editor.layout(); | |
} | |
static api = monaco; | |
editorDiv: HTMLDivElement; | |
editor: monaco.editor.IStandaloneCodeEditor; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment