Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure non-exported requirejs modules do not error #2808

Merged
merged 7 commits into from
Oct 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions panel/_templates/autoload_panel_js.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,10 @@ calls it with the rendered model.
if (window.requirejs) {
window.requirejs.config({{ config|conffilter }});
{% for r in requirements %}
require(["{{ r }}"], function({{ exports[loop.index0] }}) {
window.{{ exports[loop.index0] }} = {{ exports[loop.index0] }}
require(["{{ r }}"], function({{ exports[r] }}) {
{% if r in exports %}
window.{{ exports[r] }} = {{ exports[r] }}
{% endif %}
})
{% endfor %}
}
Expand Down
24 changes: 8 additions & 16 deletions panel/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def require_components():
from .config import config
from .reactive import ReactiveHTML

configs, requirements, exports = [], [], []
configs, requirements, exports = [], [], {}
js_requires = []

from bokeh.model import Model
Expand Down Expand Up @@ -63,24 +63,16 @@ def require_components():

for req in list(model_require.get('paths', [])):
if isinstance(req, tuple):
model_require['paths'] = dict(model_require['paths'])
model_require['paths'][req[0]] = model_require['paths'].pop(req)

export = req[0] if isinstance(req, tuple) else req
if export not in model_exports:
continue
reqs = req[1] if isinstance(req, tuple) else (req,)
for r in reqs:
if r not in requirements:
requirements.append(r)
if r in model_exports:
exports[r] = model_exports[r]

if isinstance(req, tuple):
for r in req[1]:
if r not in requirements:
requirements.append(r)
req = req[0]
elif req not in requirements:
requirements.append(req)

export = model_exports[req]
for e in (export if isinstance(export, list) else [export]):
if export not in exports and export is not None:
exports.append(export)
return configs, requirements, exports, skip_import

def write_bundled_files(name, files, bundle_dir, explicit_dir=None, ext=None):
Expand Down
4 changes: 2 additions & 2 deletions panel/models/ace.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def __js_skip__(cls):

__js_require__ = {
'paths': {
('ace', ('ace/ace', 'ace/ext-language_tools')): '//cdnjs.cloudflare.com/ajax/libs/ace/1.4.7'},
'exports': {'ace': 'ace'},
('ace', ('ace/ace', 'ace/ext-language_tools', 'ace/ext-modelist')): '//cdnjs.cloudflare.com/ajax/libs/ace/1.4.7'},
'exports': {'ace/ace': 'ace'},
'shim': {
'ace/ext-language_tools': { 'deps': ["ace/ace"] },
'ace/ext-modelist': { 'deps': ["ace/ace"] }
Expand Down
2 changes: 1 addition & 1 deletion panel/models/perspective.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Perspective(HTMLBox):
"perspective-viewer-d3fc": "https://unpkg.com/@finos/perspective-viewer-d3fc@0.5.2/dist/umd/perspective-viewer-d3fc",
},
"exports": {
"perspective": "Perspective",
"perspective": "perspective",
"perspective-viewer": "PerspectiveViewer",
"perspective-viewer-datagrid": "PerspectiveViewerDatagrid",
"perspective-viewer-hypergrid": "PerspectiveViewerHypergrid",
Expand Down
9 changes: 7 additions & 2 deletions panel/models/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ def __js_skip__(cls):
]),
'exports': {
"xtermjs": "xtermjs",
"xtermjsweblinks": "WebLinksAddon"
"xtermjsweblinks": "WebLinksAddon",
},
'shim': {'xtermjsweblinks': {'exports': 'WebLinksAddon', 'deps': ['xtermjs']}}
'shim': {
'xtermjsweblinks': {
'exports': 'WebLinksAddon',
'deps': ['xtermjs']
}
}
}
4 changes: 1 addition & 3 deletions panel/models/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ export class TerminalView extends PanelHTMLBoxView {
this.term.open(this.container)

this.term.onRender(() => {
if (!this._rendered) {
if (!this._rendered)
this.fit()
}
})

this.write()
Expand Down Expand Up @@ -77,7 +76,6 @@ export class TerminalView extends PanelHTMLBoxView {
}

clear(): void {
// https://stackoverflow.com/questions/65367607/how-to-handle-new-line-in-xterm-js-while-writing-data-into-the-terminal
this.term.clear()
}

Expand Down
1 change: 0 additions & 1 deletion panel/models/vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ def __js_skip__(cls):

__js_require__ = {
"paths": {"vtk": vtk_cdn[:-3]},
"exports": {"vtk": 'vtk'},
"shim": {
"vtk": {"exports": "vtk"},
}
Expand Down
229 changes: 115 additions & 114 deletions panel/models/vtk/panel_fullscreen_renwin_sync.ts
Original file line number Diff line number Diff line change
@@ -1,149 +1,150 @@
import {vtk, vtkns, applyStyle, CSSProperties} from "./util"
import {vtkns, applyStyle, CSSProperties} from "./util"

//------------------------//
//Custom Extended Classes
//------------------------//
export let FullScreenRenderWindowSynchronized: any

if (vtk) {
const DEFAULT_VALUES = {
containerStyle: null,
controlPanelStyle: null,
listenWindowResize: true,
resizeCallback: null,
controllerVisibility: true,
synchronizerContextName: "default",
}

const STYLE_CONTROL_PANEL: CSSProperties = {
position: "absolute",
left: "25px",
top: "25px",
backgroundColor: "white",
borderRadius: "5px",
listStyle: "none",
padding: "5px 10px",
margin: "0",
display: "block",
border: "solid 1px black",
maxWidth: "calc(100vw - 70px)",
maxHeight: "calc(100vh - 60px)",
overflow: "auto",
}

function panelFullScreenRenderWindowSynchronized(publicAPI: any, model: any) {
// Panel (modification) synchronizable renderWindow
model.renderWindow = vtkns.SynchronizableRenderWindow.newInstance({
synchronizerContext: model.synchronizerContext,
})

// OpenGlRenderWindow
model.openGLRenderWindow = vtkns.OpenGLRenderWindow.newInstance()
model.openGLRenderWindow.setContainer(model.container)
model.renderWindow.addView(model.openGLRenderWindow)

// Interactor
model.interactor = vtkns.RenderWindowInteractor.newInstance()
model.interactor.setInteractorStyle(
vtkns.InteractorStyleTrackballCamera.newInstance()
)
model.interactor.setView(model.openGLRenderWindow)
model.interactor.initialize()
model.interactor.bindEvents(model.container)
const DEFAULT_VALUES = {
containerStyle: null,
controlPanelStyle: null,
listenWindowResize: true,
resizeCallback: null,
controllerVisibility: true,
synchronizerContextName: "default",
}

publicAPI.getRenderer = () => model.renderWindow.getRenderers()[0]
const STYLE_CONTROL_PANEL: CSSProperties = {
position: "absolute",
left: "25px",
top: "25px",
backgroundColor: "white",
borderRadius: "5px",
listStyle: "none",
padding: "5px 10px",
margin: "0",
display: "block",
border: "solid 1px black",
maxWidth: "calc(100vw - 70px)",
maxHeight: "calc(100vh - 60px)",
overflow: "auto",
}

publicAPI.removeController = () => {
const el = model.controlContainer
if (el) {
el.parentNode.removeChild(el)
}
function panelFullScreenRenderWindowSynchronized(publicAPI: any, model: any) {
// Panel (modification) synchronizable renderWindow
model.renderWindow = vtkns.SynchronizableRenderWindow.newInstance({
synchronizerContext: model.synchronizerContext,
})

// OpenGlRenderWindow
model.openGLRenderWindow = vtkns.OpenGLRenderWindow.newInstance()
model.openGLRenderWindow.setContainer(model.container)
model.renderWindow.addView(model.openGLRenderWindow)

// Interactor
model.interactor = vtkns.RenderWindowInteractor.newInstance()
model.interactor.setInteractorStyle(
vtkns.InteractorStyleTrackballCamera.newInstance()
)
model.interactor.setView(model.openGLRenderWindow)
model.interactor.initialize()
model.interactor.bindEvents(model.container)

publicAPI.getRenderer = () => model.renderWindow.getRenderers()[0]

publicAPI.removeController = () => {
const el = model.controlContainer
if (el) {
el.parentNode.removeChild(el)
}
}

publicAPI.setControllerVisibility = (visible: boolean) => {
model.controllerVisibility = visible
if (model.controlContainer) {
if (visible) {
model.controlContainer.style.display = "block"
} else {
model.controlContainer.style.display = "none"
}
publicAPI.setControllerVisibility = (visible: boolean) => {
model.controllerVisibility = visible
if (model.controlContainer) {
if (visible) {
model.controlContainer.style.display = "block"
} else {
model.controlContainer.style.display = "none"
}
}
}

publicAPI.toggleControllerVisibility = () => {
publicAPI.setControllerVisibility(!model.controllerVisibility)
}

publicAPI.addController = (html: string) => {
model.controlContainer = document.createElement("div")
applyStyle(
model.controlContainer,
model.controlPanelStyle || STYLE_CONTROL_PANEL
)
model.rootContainer.appendChild(model.controlContainer)
model.controlContainer.innerHTML = html

publicAPI.setControllerVisibility(model.controllerVisibility)

model.rootContainer.addEventListener("keypress", (e: KeyboardEvent) => {
if (String.fromCharCode(e.charCode) === "c") {
publicAPI.toggleControllerVisibility()
}
})
}
publicAPI.toggleControllerVisibility = () => {
publicAPI.setControllerVisibility(!model.controllerVisibility)
}

// Properly release GL context
publicAPI.delete = vtk.macro.chain(
publicAPI.setContainer,
model.openGLRenderWindow.delete,
publicAPI.delete
publicAPI.addController = (html: string) => {
model.controlContainer = document.createElement("div")
applyStyle(
model.controlContainer,
model.controlPanelStyle || STYLE_CONTROL_PANEL
)
model.rootContainer.appendChild(model.controlContainer)
model.controlContainer.innerHTML = html

publicAPI.setControllerVisibility(model.controllerVisibility)

// Handle window resize
publicAPI.resize = () => {
const dims = model.container.getBoundingClientRect()
const devicePixelRatio = window.devicePixelRatio || 1
model.openGLRenderWindow.setSize(
Math.floor(dims.width * devicePixelRatio),
Math.floor(dims.height * devicePixelRatio)
)
if (model.resizeCallback) {
model.resizeCallback(dims)
model.rootContainer.addEventListener("keypress", (e: KeyboardEvent) => {
if (String.fromCharCode(e.charCode) === "c") {
publicAPI.toggleControllerVisibility()
}
model.renderWindow.render()
}
})
}

publicAPI.setResizeCallback = (cb: CallableFunction) => {
model.resizeCallback = cb
publicAPI.resize()
// Properly release GL context
publicAPI.delete = (window as any).vtk.macro.chain(
publicAPI.setContainer,
model.openGLRenderWindow.delete,
publicAPI.delete
)

// Handle window resize
publicAPI.resize = () => {
const dims = model.container.getBoundingClientRect()
const devicePixelRatio = window.devicePixelRatio || 1
model.openGLRenderWindow.setSize(
Math.floor(dims.width * devicePixelRatio),
Math.floor(dims.height * devicePixelRatio)
)
if (model.resizeCallback) {
model.resizeCallback(dims)
}
model.renderWindow.render()
}

if (model.listenWindowResize) {
window.addEventListener("resize", publicAPI.resize)
}
publicAPI.setResizeCallback = (cb: CallableFunction) => {
model.resizeCallback = cb
publicAPI.resize()
}

FullScreenRenderWindowSynchronized = {
newInstance: vtk.macro.newInstance(
if (model.listenWindowResize) {
window.addEventListener("resize", publicAPI.resize)
}
publicAPI.resize()
}

export function initialize_fullscreen_render(): void {
let FullScreenRenderWindowSynchronized: any = {
newInstance: (window as any).vtk.macro.newInstance(
(publicAPI: any, model: any, initialValues: any = {}) => {
Object.assign(model, DEFAULT_VALUES, initialValues)
Object.assign(model, DEFAULT_VALUES, initialValues);

// Object methods
vtk.macro.obj(publicAPI, model)
vtk.macro.get(publicAPI, model, [
// Object methods
(window as any).vtk.macro.obj(publicAPI, model);
(window as any).vtk.macro.get(publicAPI, model, [
"renderWindow",
"openGLRenderWindow",
"interactor",
"rootContainer",
"container",
"controlContainer",
"synchronizerContext",
])
]);

// Object specific methods
panelFullScreenRenderWindowSynchronized(publicAPI, model)
// Object specific methods
panelFullScreenRenderWindowSynchronized(publicAPI, model);
}
),
}
vtkns.FullScreenRenderWindowSynchronized = FullScreenRenderWindowSynchronized
}
Loading